diff options
author | Jesse Barnes <jesse.barnes@intel.com> | 2007-10-30 12:52:46 -0700 |
---|---|---|
committer | Jesse Barnes <jesse.barnes@intel.com> | 2007-10-30 12:52:46 -0700 |
commit | 91aae7e683786a48547872b0a5fa92b2232e02c0 (patch) | |
tree | a30c8022886d61add4a4c2e073fa07f29d7745a7 /shared-core | |
parent | 7e9ea55a2f052cc939ba9bbf9edac39798344b7a (diff) | |
parent | 79744d730c90019edd367eee4a8ec1fa22d53402 (diff) |
Merge branch 'master' into vblank-rework, fixup remaining drivers
Conflicts:
linux-core/drmP.h
linux-core/drm_drv.c
linux-core/drm_irq.c
shared-core/i915_drv.h
shared-core/i915_irq.c
shared-core/mga_drv.h
shared-core/mga_irq.c
shared-core/radeon_drv.h
shared-core/radeon_irq.c
Merge in the latest master bits and update the remaining drivers (except
mach64 which math_b is working on). Also remove the 9xx hack from the i915
driver; it seems to be correct.
Diffstat (limited to 'shared-core')
82 files changed, 11933 insertions, 6005 deletions
diff --git a/shared-core/Makefile.am b/shared-core/Makefile.am index f0ebf2a3..7193e527 100644 --- a/shared-core/Makefile.am +++ b/shared-core/Makefile.am @@ -36,4 +36,5 @@ klibdrminclude_HEADERS = \ sis_drm.h \ via_drm.h \ r300_reg.h \ - via_3d_reg.h + via_3d_reg.h \ + xgi_drm.h diff --git a/shared-core/drm.h b/shared-core/drm.h index eae25c64..3092e536 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -89,24 +89,6 @@ #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) #endif -#define XFREE86_VERSION(major,minor,patch,snap) \ - ((major << 16) | (minor << 8) | patch) - -#ifndef CONFIG_XFREE86_VERSION -#define CONFIG_XFREE86_VERSION XFREE86_VERSION(4,1,0,0) -#endif - -#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0) -#define DRM_PROC_DEVICES "/proc/devices" -#define DRM_PROC_MISC "/proc/misc" -#define DRM_PROC_DRM "/proc/drm" -#define DRM_DEV_DRM "/dev/drm" -#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) -#define DRM_DEV_UID 0 -#define DRM_DEV_GID 0 -#endif - -#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0) #ifdef __OpenBSD__ #define DRM_MAJOR 81 #endif @@ -114,7 +96,7 @@ #define DRM_MAJOR 226 #endif #define DRM_MAX_MINOR 15 -#endif + #define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */ #define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */ #define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */ @@ -127,16 +109,9 @@ #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) #if defined(__linux__) -#if defined(__KERNEL__) -typedef __u64 drm_u64_t; -#else -typedef unsigned long long drm_u64_t; -#endif - typedef unsigned int drm_handle_t; #else #include <sys/types.h> -typedef u_int64_t drm_u64_t; typedef unsigned long drm_handle_t; /**< To mapped regions */ #endif typedef unsigned int drm_context_t; /**< GLXContext handle */ @@ -152,31 +127,23 @@ typedef unsigned int drm_magic_t; /**< Magic for authentication */ * \note KW: Actually it's illegal to change either for * backwards-compatibility reasons. */ -typedef struct drm_clip_rect { +struct drm_clip_rect { unsigned short x1; unsigned short y1; unsigned short x2; unsigned short y2; -} drm_clip_rect_t; - -/** - * Drawable information. - */ -typedef struct drm_drawable_info { - unsigned int num_rects; - drm_clip_rect_t *rects; -} drm_drawable_info_t; +}; /** * Texture region, */ -typedef struct drm_tex_region { +struct drm_tex_region { unsigned char next; unsigned char prev; unsigned char in_use; unsigned char padding; unsigned int age; -} drm_tex_region_t; +}; /** * Hardware lock. @@ -185,10 +152,10 @@ typedef struct drm_tex_region { * processor bus contention on a multiprocessor system, there should not be any * other data stored in the same cache line. */ -typedef struct drm_hw_lock { +struct drm_hw_lock { __volatile__ unsigned int lock; /**< lock variable */ char padding[60]; /**< Pad to cache line */ -} drm_hw_lock_t; +}; /* This is beyond ugly, and only works on GCC. However, it allows me to use * drm.h in places (i.e., in the X-server) where I can't use size_t. The real @@ -211,7 +178,7 @@ typedef struct drm_hw_lock { * * \sa drmGetVersion(). */ -typedef struct drm_version { +struct drm_version { int version_major; /**< Major version */ int version_minor; /**< Minor version */ int version_patchlevel; /**< Patch level */ @@ -221,35 +188,35 @@ typedef struct drm_version { char __user *date; /**< User-space buffer to hold date */ DRM_SIZE_T desc_len; /**< Length of desc buffer */ char __user *desc; /**< User-space buffer to hold desc */ -} drm_version_t; +}; /** * DRM_IOCTL_GET_UNIQUE ioctl argument type. * * \sa drmGetBusid() and drmSetBusId(). */ -typedef struct drm_unique { +struct drm_unique { DRM_SIZE_T unique_len; /**< Length of unique */ char __user *unique; /**< Unique name for driver instantiation */ -} drm_unique_t; +}; #undef DRM_SIZE_T -typedef struct drm_list { +struct drm_list { int count; /**< Length of user-space structures */ - drm_version_t __user *version; -} drm_list_t; + struct drm_version __user *version; +}; -typedef struct drm_block { +struct drm_block { int unused; -} drm_block_t; +}; /** * DRM_IOCTL_CONTROL ioctl argument type. * * \sa drmCtlInstHandler() and drmCtlUninstHandler(). */ -typedef struct drm_control { +struct drm_control { enum { DRM_ADD_COMMAND, DRM_RM_COMMAND, @@ -257,12 +224,12 @@ typedef struct drm_control { DRM_UNINST_HANDLER } func; int irq; -} drm_control_t; +}; /** * Type of memory to map. */ -typedef enum drm_map_type { +enum drm_map_type { _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */ _DRM_REGISTERS = 1, /**< no caching, no core dump */ _DRM_SHM = 2, /**< shared, cached */ @@ -270,12 +237,12 @@ typedef enum drm_map_type { _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ _DRM_TTM = 6 -} drm_map_type_t; +}; /** * Memory mapping flags. */ -typedef enum drm_map_flags { +enum drm_map_flags { _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */ _DRM_READ_ONLY = 0x02, _DRM_LOCKED = 0x04, /**< shared, cached, locked */ @@ -283,12 +250,12 @@ typedef enum drm_map_flags { _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ _DRM_REMOVABLE = 0x40 /**< Removable mapping */ -} drm_map_flags_t; +}; -typedef struct drm_ctx_priv_map { +struct drm_ctx_priv_map { unsigned int ctx_id; /**< Context requesting private mapping */ void *handle; /**< Handle of map */ -} drm_ctx_priv_map_t; +}; /** * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls @@ -296,30 +263,30 @@ typedef struct drm_ctx_priv_map { * * \sa drmAddMap(). */ -typedef struct drm_map { +struct drm_map { unsigned long offset; /**< Requested physical address (0 for SAREA)*/ unsigned long size; /**< Requested physical size (bytes) */ - drm_map_type_t type; /**< Type of memory to map */ - drm_map_flags_t flags; /**< Flags */ + enum drm_map_type type; /**< Type of memory to map */ + enum drm_map_flags flags; /**< Flags */ void *handle; /**< User-space: "Handle" to pass to mmap() */ /**< Kernel-space: kernel-virtual address */ int mtrr; /**< MTRR slot used */ /* Private data */ -} drm_map_t; +}; /** * DRM_IOCTL_GET_CLIENT ioctl argument type. */ -typedef struct drm_client { +struct drm_client { int idx; /**< Which client desired? */ int auth; /**< Is client authenticated? */ unsigned long pid; /**< Process ID */ unsigned long uid; /**< User ID */ unsigned long magic; /**< Magic */ unsigned long iocs; /**< Ioctl count */ -} drm_client_t; +}; -typedef enum { +enum drm_stat_type { _DRM_STAT_LOCK, _DRM_STAT_OPENS, _DRM_STAT_CLOSES, @@ -337,23 +304,23 @@ typedef enum { _DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */ _DRM_STAT_MISSED /**< Missed DMA opportunity */ /* Add to the *END* of the list */ -} drm_stat_type_t; +}; /** * DRM_IOCTL_GET_STATS ioctl argument type. */ -typedef struct drm_stats { +struct drm_stats { unsigned long count; struct { unsigned long value; - drm_stat_type_t type; + enum drm_stat_type type; } data[15]; -} drm_stats_t; +}; /** * Hardware locking flags. */ -typedef enum drm_lock_flags { +enum drm_lock_flags { _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */ _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */ _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */ @@ -363,17 +330,17 @@ typedef enum drm_lock_flags { full-screen DGA-like mode. */ _DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */ _DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */ -} drm_lock_flags_t; +}; /** * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type. * * \sa drmGetLock() and drmUnlock(). */ -typedef struct drm_lock { +struct drm_lock { int context; - drm_lock_flags_t flags; -} drm_lock_t; + enum drm_lock_flags flags; +}; /** * DMA flags @@ -383,7 +350,7 @@ typedef struct drm_lock { * * \sa drm_dma. */ -typedef enum drm_dma_flags { +enum drm_dma_flags { /* Flags for DMA buffer dispatch */ _DRM_DMA_BLOCK = 0x01, /**< * Block until buffer dispatched. @@ -402,14 +369,14 @@ typedef enum drm_dma_flags { _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */ _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */ _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */ -} drm_dma_flags_t; +}; /** * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type. * * \sa drmAddBufs(). */ -typedef struct drm_buf_desc { +struct drm_buf_desc { int count; /**< Number of buffers of this size */ int size; /**< Size in bytes */ int low_mark; /**< Low water mark */ @@ -425,48 +392,48 @@ typedef struct drm_buf_desc { * Start address of where the AGP buffers are * in the AGP aperture */ -} drm_buf_desc_t; +}; /** * DRM_IOCTL_INFO_BUFS ioctl argument type. */ -typedef struct drm_buf_info { +struct drm_buf_info { int count; /**< Number of buffers described in list */ - drm_buf_desc_t __user *list; /**< List of buffer descriptions */ -} drm_buf_info_t; + struct drm_buf_desc __user *list; /**< List of buffer descriptions */ +}; /** * DRM_IOCTL_FREE_BUFS ioctl argument type. */ -typedef struct drm_buf_free { +struct drm_buf_free { int count; int __user *list; -} drm_buf_free_t; +}; /** * Buffer information * * \sa drm_buf_map. */ -typedef struct drm_buf_pub { +struct drm_buf_pub { int idx; /**< Index into the master buffer list */ int total; /**< Buffer size */ int used; /**< Amount of buffer in use (for DMA) */ void __user *address; /**< Address of buffer */ -} drm_buf_pub_t; +}; /** * DRM_IOCTL_MAP_BUFS ioctl argument type. */ -typedef struct drm_buf_map { +struct drm_buf_map { int count; /**< Length of the buffer list */ #if defined(__cplusplus) void __user *c_virtual; #else void __user *virtual; /**< Mmap'd area in user-virtual */ #endif - drm_buf_pub_t __user *list; /**< Buffer information */ -} drm_buf_map_t; + struct drm_buf_pub __user *list; /**< Buffer information */ +}; /** * DRM_IOCTL_DMA ioctl argument type. @@ -475,48 +442,48 @@ typedef struct drm_buf_map { * * \sa drmDMA(). */ -typedef struct drm_dma { +struct drm_dma { int context; /**< Context handle */ int send_count; /**< Number of buffers to send */ int __user *send_indices; /**< List of handles to buffers */ int __user *send_sizes; /**< Lengths of data to send */ - drm_dma_flags_t flags; /**< Flags */ + enum drm_dma_flags flags; /**< Flags */ int request_count; /**< Number of buffers requested */ int request_size; /**< Desired size for buffers */ int __user *request_indices; /**< Buffer information */ int __user *request_sizes; int granted_count; /**< Number of buffers granted */ -} drm_dma_t; +}; -typedef enum { +enum drm_ctx_flags { _DRM_CONTEXT_PRESERVED = 0x01, _DRM_CONTEXT_2DONLY = 0x02 -} drm_ctx_flags_t; +}; /** * DRM_IOCTL_ADD_CTX ioctl argument type. * * \sa drmCreateContext() and drmDestroyContext(). */ -typedef struct drm_ctx { +struct drm_ctx { drm_context_t handle; - drm_ctx_flags_t flags; -} drm_ctx_t; + enum drm_ctx_flags flags; +}; /** * DRM_IOCTL_RES_CTX ioctl argument type. */ -typedef struct drm_ctx_res { +struct drm_ctx_res { int count; - drm_ctx_t __user *contexts; -} drm_ctx_res_t; + struct drm_ctx __user *contexts; +}; /** * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type. */ -typedef struct drm_draw { +struct drm_draw { drm_drawable_t handle; -} drm_draw_t; +}; /** * DRM_IOCTL_UPDATE_DRAW ioctl argument type. @@ -525,53 +492,53 @@ typedef enum { DRM_DRAWABLE_CLIPRECTS, } drm_drawable_info_type_t; -typedef struct drm_update_draw { +struct drm_update_draw { drm_drawable_t handle; unsigned int type; unsigned int num; unsigned long long data; -} drm_update_draw_t; +}; /** * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type. */ -typedef struct drm_auth { +struct drm_auth { drm_magic_t magic; -} drm_auth_t; +}; /** * DRM_IOCTL_IRQ_BUSID ioctl argument type. * * \sa drmGetInterruptFromBusID(). */ -typedef struct drm_irq_busid { +struct drm_irq_busid { int irq; /**< IRQ number */ int busnum; /**< bus number */ int devnum; /**< device number */ int funcnum; /**< function number */ -} drm_irq_busid_t; +}; -typedef enum { +enum drm_vblank_seq_type { _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */ -} drm_vblank_seq_type_t; +}; #define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) #define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \ _DRM_VBLANK_NEXTONMISS) struct drm_wait_vblank_request { - drm_vblank_seq_type_t type; + enum drm_vblank_seq_type type; unsigned int sequence; unsigned long signal; }; struct drm_wait_vblank_reply { - drm_vblank_seq_type_t type; + enum drm_vblank_seq_type type; unsigned int sequence; long tval_sec; long tval_usec; @@ -582,10 +549,10 @@ struct drm_wait_vblank_reply { * * \sa drmWaitVBlank(). */ -typedef union drm_wait_vblank { +union drm_wait_vblank { struct drm_wait_vblank_request request; struct drm_wait_vblank_reply reply; -} drm_wait_vblank_t; +}; typedef enum { _DRM_PRE_MODESET = 1, @@ -598,7 +565,7 @@ typedef enum { * \sa drmModesetCtl(). */ typedef struct drm_modeset_ctl { - drm_u64_t arg; + u64 arg; drm_modeset_ctl_cmd_t cmd; } drm_modeset_ctl_t; @@ -607,31 +574,31 @@ typedef struct drm_modeset_ctl { * * \sa drmAgpEnable(). */ -typedef struct drm_agp_mode { +struct drm_agp_mode { unsigned long mode; /**< AGP mode */ -} drm_agp_mode_t; +}; /** * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type. * * \sa drmAgpAlloc() and drmAgpFree(). */ -typedef struct drm_agp_buffer { +struct drm_agp_buffer { unsigned long size; /**< In bytes -- will round to page boundary */ unsigned long handle; /**< Used for binding / unbinding */ unsigned long type; /**< Type of memory to allocate */ unsigned long physical; /**< Physical used by i810 */ -} drm_agp_buffer_t; +}; /** * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type. * * \sa drmAgpBind() and drmAgpUnbind(). */ -typedef struct drm_agp_binding { +struct drm_agp_binding { unsigned long handle; /**< From drm_agp_buffer */ unsigned long offset; /**< In bytes -- will round to page boundary */ -} drm_agp_binding_t; +}; /** * DRM_IOCTL_AGP_INFO ioctl argument type. @@ -640,7 +607,7 @@ typedef struct drm_agp_binding { * drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(), * drmAgpVendorId() and drmAgpDeviceId(). */ -typedef struct drm_agp_info { +struct drm_agp_info { int agp_version_major; int agp_version_minor; unsigned long mode; @@ -654,56 +621,49 @@ typedef struct drm_agp_info { unsigned short id_vendor; unsigned short id_device; /*@} */ -} drm_agp_info_t; +}; /** * DRM_IOCTL_SG_ALLOC ioctl argument type. */ -typedef struct drm_scatter_gather { +struct drm_scatter_gather { unsigned long size; /**< In bytes -- will round to page boundary */ unsigned long handle; /**< Used for mapping / unmapping */ -} drm_scatter_gather_t; +}; /** * DRM_IOCTL_SET_VERSION ioctl argument type. */ -typedef struct drm_set_version { +struct drm_set_version { int drm_di_major; int drm_di_minor; int drm_dd_major; int drm_dd_minor; -} drm_set_version_t; +}; #define DRM_FENCE_FLAG_EMIT 0x00000001 #define DRM_FENCE_FLAG_SHAREABLE 0x00000002 #define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004 #define DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS 0x00000008 +#define DRM_FENCE_FLAG_NO_USER 0x00000010 /* Reserved for driver use */ #define DRM_FENCE_MASK_DRIVER 0xFF000000 #define DRM_FENCE_TYPE_EXE 0x00000001 -typedef struct drm_fence_arg { - unsigned handle; - int class; - unsigned type; - unsigned flags; - unsigned signaled; - unsigned expand_pad[4]; /*Future expansion */ - enum { - drm_fence_create, - drm_fence_destroy, - drm_fence_reference, - drm_fence_unreference, - drm_fence_signaled, - drm_fence_flush, - drm_fence_wait, - drm_fence_emit, - drm_fence_buffers - } op; -} drm_fence_arg_t; +struct drm_fence_arg { + unsigned int handle; + unsigned int fence_class; + unsigned int type; + unsigned int flags; + unsigned int signaled; + unsigned int error; + unsigned int sequence; + unsigned int pad64; + uint64_t expand_pad[2]; /*Future expansion */ +}; /* Buffer permissions, referring to how the GPU uses the buffers. * these translate to fence types used for the buffers. @@ -711,9 +671,9 @@ typedef struct drm_fence_arg { * a command (batch-) buffer is exe. Can be or-ed together. */ -#define DRM_BO_FLAG_READ 0x00000001 -#define DRM_BO_FLAG_WRITE 0x00000002 -#define DRM_BO_FLAG_EXE 0x00000004 +#define DRM_BO_FLAG_READ (1ULL << 0) +#define DRM_BO_FLAG_WRITE (1ULL << 1) +#define DRM_BO_FLAG_EXE (1ULL << 2) /* * Status flags. Can be read to determine the actual state of a buffer. @@ -726,25 +686,25 @@ typedef struct drm_fence_arg { * or lock. * Flags: Acknowledge */ -#define DRM_BO_FLAG_NO_EVICT 0x00000010 +#define DRM_BO_FLAG_NO_EVICT (1ULL << 4) /* * Mask: Require that the buffer is placed in mappable memory when validated. * If not set the buffer may or may not be in mappable memory when validated. * Flags: If set, the buffer is in mappable memory. */ -#define DRM_BO_FLAG_MAPPABLE 0x00000020 +#define DRM_BO_FLAG_MAPPABLE (1ULL << 5) /* Mask: The buffer should be shareable with other processes. * Flags: The buffer is shareable with other processes. */ -#define DRM_BO_FLAG_SHAREABLE 0x00000040 +#define DRM_BO_FLAG_SHAREABLE (1ULL << 6) /* Mask: If set, place the buffer in cache-coherent memory if available. * If clear, never place the buffer in cache coherent memory if validated. * Flags: The buffer is currently in cache-coherent memory. */ -#define DRM_BO_FLAG_CACHED 0x00000080 +#define DRM_BO_FLAG_CACHED (1ULL << 7) /* Mask: Make sure that every time this buffer is validated, * it ends up on the same location provided that the memory mask is the same. @@ -753,23 +713,24 @@ typedef struct drm_fence_arg { * part of buffer manager shutdown or locking. * Flags: Acknowledge. */ -#define DRM_BO_FLAG_NO_MOVE 0x00000100 +#define DRM_BO_FLAG_NO_MOVE (1ULL << 8) /* Mask: Make sure the buffer is in cached memory when mapped for reading. * Flags: Acknowledge. */ -#define DRM_BO_FLAG_READ_CACHED 0x00080000 +#define DRM_BO_FLAG_READ_CACHED (1ULL << 19) /* Mask: Force DRM_BO_FLAG_CACHED flag strictly also if it is set. * Flags: Acknowledge. */ -#define DRM_BO_FLAG_FORCE_CACHING 0x00002000 +#define DRM_BO_FLAG_FORCE_CACHING (1ULL << 13) /* * Mask: Force DRM_BO_FLAG_MAPPABLE flag strictly also if it is clear. * Flags: Acknowledge. */ -#define DRM_BO_FLAG_FORCE_MAPPABLE 0x00004000 +#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14) +#define DRM_BO_FLAG_TILE (1ULL << 15) /* * Memory type flags that can be or'ed together in the mask, but only @@ -777,62 +738,56 @@ typedef struct drm_fence_arg { */ /* System memory */ -#define DRM_BO_FLAG_MEM_LOCAL 0x01000000 +#define DRM_BO_FLAG_MEM_LOCAL (1ULL << 24) /* Translation table memory */ -#define DRM_BO_FLAG_MEM_TT 0x02000000 +#define DRM_BO_FLAG_MEM_TT (1ULL << 25) /* Vram memory */ -#define DRM_BO_FLAG_MEM_VRAM 0x04000000 +#define DRM_BO_FLAG_MEM_VRAM (1ULL << 26) /* Up to the driver to define. */ -#define DRM_BO_FLAG_MEM_PRIV0 0x08000000 -#define DRM_BO_FLAG_MEM_PRIV1 0x10000000 -#define DRM_BO_FLAG_MEM_PRIV2 0x20000000 -#define DRM_BO_FLAG_MEM_PRIV3 0x40000000 -#define DRM_BO_FLAG_MEM_PRIV4 0x80000000 +#define DRM_BO_FLAG_MEM_PRIV0 (1ULL << 27) +#define DRM_BO_FLAG_MEM_PRIV1 (1ULL << 28) +#define DRM_BO_FLAG_MEM_PRIV2 (1ULL << 29) +#define DRM_BO_FLAG_MEM_PRIV3 (1ULL << 30) +#define DRM_BO_FLAG_MEM_PRIV4 (1ULL << 31) +/* We can add more of these now with a 64-bit flag type */ /* Memory flag mask */ -#define DRM_BO_MASK_MEM 0xFF000000 -#define DRM_BO_MASK_MEMTYPE 0xFF0000A0 +#define DRM_BO_MASK_MEM 0x00000000FF000000ULL +#define DRM_BO_MASK_MEMTYPE 0x00000000FF0000A0ULL + +/* Driver-private flags */ +#define DRM_BO_MASK_DRIVER 0xFFFF000000000000ULL /* Don't block on validate and map */ #define DRM_BO_HINT_DONT_BLOCK 0x00000002 /* Don't place this buffer on the unfenced list.*/ #define DRM_BO_HINT_DONT_FENCE 0x00000004 #define DRM_BO_HINT_WAIT_LAZY 0x00000008 -#define DRM_BO_HINT_ALLOW_UNFENCED_MAP 0x00000010 +#define DRM_BO_INIT_MAGIC 0xfe769812 +#define DRM_BO_INIT_MAJOR 1 +#define DRM_BO_INIT_MINOR 0 +#define DRM_BO_INIT_PATCH 0 + + +struct drm_bo_info_req { + uint64_t mask; + uint64_t flags; + unsigned int handle; + unsigned int hint; + unsigned int fence_class; + unsigned int desired_tile_stride; + unsigned int tile_info; + unsigned int pad64; +}; -typedef enum { - drm_bo_type_dc, - drm_bo_type_user, - drm_bo_type_fake, - drm_bo_type_kernel, /* for initial kernel allocations */ -}drm_bo_type_t; - - -typedef struct drm_bo_arg_request { - unsigned handle; /* User space handle */ - unsigned mask; - unsigned hint; - drm_u64_t size; - drm_bo_type_t type; - unsigned arg_handle; - drm_u64_t buffer_start; - unsigned page_alignment; - unsigned expand_pad[4]; /*Future expansion */ - enum { - drm_bo_create, - drm_bo_validate, - drm_bo_map, - drm_bo_unmap, - drm_bo_fence, - drm_bo_destroy, - drm_bo_reference, - drm_bo_unreference, - drm_bo_info, - drm_bo_wait_idle, - drm_bo_ref_fence - } op; -} drm_bo_arg_request_t; +struct drm_bo_create_req { + uint64_t mask; + uint64_t size; + uint64_t buffer_start; + unsigned int hint; + unsigned int page_alignment; +}; /* @@ -841,30 +796,76 @@ typedef struct drm_bo_arg_request { #define DRM_BO_REP_BUSY 0x00000001 -typedef struct drm_bo_arg_reply { +struct drm_bo_info_rep { + uint64_t flags; + uint64_t mask; + uint64_t size; + uint64_t offset; + uint64_t arg_handle; + uint64_t buffer_start; + unsigned int handle; + unsigned int fence_flags; + unsigned int rep_flags; + unsigned int page_alignment; + unsigned int desired_tile_stride; + unsigned int hw_tile_stride; + unsigned int tile_info; + unsigned int pad64; + uint64_t expand_pad[4]; /*Future expansion */ +}; + +struct drm_bo_arg_rep { + struct drm_bo_info_rep bo_info; int ret; - unsigned handle; - unsigned flags; - drm_u64_t size; - drm_u64_t offset; - drm_u64_t arg_handle; - unsigned mask; - drm_u64_t buffer_start; - unsigned fence_flags; - unsigned rep_flags; - unsigned page_alignment; - unsigned expand_pad[4]; /*Future expansion */ -}drm_bo_arg_reply_t; - - -typedef struct drm_bo_arg{ - int handled; - drm_u64_t next; + unsigned int pad64; +}; + +struct drm_bo_create_arg { + union { + struct drm_bo_create_req req; + struct drm_bo_info_rep rep; + } d; +}; + +struct drm_bo_handle_arg { + unsigned int handle; +}; + +struct drm_bo_reference_info_arg { union { - drm_bo_arg_request_t req; - drm_bo_arg_reply_t rep; + struct drm_bo_handle_arg req; + struct drm_bo_info_rep rep; } d; -} drm_bo_arg_t; +}; + +struct drm_bo_map_wait_idle_arg { + union { + struct drm_bo_info_req req; + struct drm_bo_info_rep rep; + } d; +}; + +struct drm_bo_op_req { + enum { + drm_bo_validate, + drm_bo_fence, + drm_bo_ref_fence, + } op; + unsigned int arg_handle; + struct drm_bo_info_req bo_req; +}; + + +struct drm_bo_op_arg { + uint64_t next; + union { + struct drm_bo_op_req req; + struct drm_bo_arg_rep rep; + } d; + int handled; + unsigned int pad64; +}; + #define DRM_BO_MEM_LOCAL 0 #define DRM_BO_MEM_TT 1 @@ -877,25 +878,28 @@ typedef struct drm_bo_arg{ #define DRM_BO_MEM_TYPES 8 /* For now. */ -typedef union drm_mm_init_arg{ - struct { - enum { - mm_init, - mm_takedown, - mm_query, - mm_lock, - mm_unlock - } op; - drm_u64_t p_offset; - drm_u64_t p_size; - unsigned mem_type; - unsigned expand_pad[8]; /*Future expansion */ - } req; - struct { - drm_handle_t mm_sarea; - unsigned expand_pad[8]; /*Future expansion */ - } rep; -} drm_mm_init_arg_t; +#define DRM_BO_LOCK_UNLOCK_BM (1 << 0) +#define DRM_BO_LOCK_IGNORE_NO_EVICT (1 << 1) + +struct drm_bo_version_arg { + uint32_t major; + uint32_t minor; + uint32_t patchlevel; +}; + +struct drm_mm_type_arg { + unsigned int mem_type; + unsigned int lock_flags; +}; + +struct drm_mm_init_arg { + unsigned int magic; + unsigned int major; + unsigned int minor; + unsigned int mem_type; + uint64_t p_offset; + uint64_t p_size; +}; /** * \name Ioctls Definitions @@ -908,65 +912,86 @@ typedef union drm_mm_init_arg{ #define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) #define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) -#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) -#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) -#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t) -#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t) -#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, drm_map_t) -#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, drm_client_t) -#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, drm_stats_t) -#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, drm_set_version_t) - -#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t) -#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t) -#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t) -#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t) -#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t) -#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t) -#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t) -#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t) -#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t) -#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t) -#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t) - -#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, drm_map_t) - -#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, drm_ctx_priv_map_t) -#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, drm_ctx_priv_map_t) - -#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t) -#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t) -#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t) -#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t) -#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t) -#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t) -#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t) -#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t) -#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t) -#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t) -#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t) -#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t) -#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t) +#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version) +#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique) +#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, struct drm_auth) +#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid) +#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map) +#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) +#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) +#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) + +#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) +#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) +#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block) +#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, struct drm_block) +#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, struct drm_control) +#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, struct drm_map) +#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc) +#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, struct drm_buf_desc) +#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, struct drm_buf_info) +#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, struct drm_buf_map) +#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, struct drm_buf_free) + +#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, struct drm_map) + +#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) +#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) + +#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) +#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) +#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) +#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, struct drm_ctx) +#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, struct drm_ctx) +#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, struct drm_ctx) +#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, struct drm_ctx_res) +#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, struct drm_draw) +#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, struct drm_draw) +#define DRM_IOCTL_DMA DRM_IOWR(0x29, struct drm_dma) +#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, struct drm_lock) +#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) +#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) #define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) #define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) -#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t) -#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t) -#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t) -#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t) -#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t) -#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) - -#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t) -#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t) - -#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t) +#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode) +#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, struct drm_agp_info) +#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer) +#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, struct drm_agp_buffer) +#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding) +#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding) + +#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, struct drm_scatter_gather) +#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather) + +#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank) + +#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) + +#define DRM_IOCTL_MM_INIT DRM_IOWR(0xc0, struct drm_mm_init_arg) +#define DRM_IOCTL_MM_TAKEDOWN DRM_IOWR(0xc1, struct drm_mm_type_arg) +#define DRM_IOCTL_MM_LOCK DRM_IOWR(0xc2, struct drm_mm_type_arg) +#define DRM_IOCTL_MM_UNLOCK DRM_IOWR(0xc3, struct drm_mm_type_arg) + +#define DRM_IOCTL_FENCE_CREATE DRM_IOWR(0xc4, struct drm_fence_arg) +#define DRM_IOCTL_FENCE_REFERENCE DRM_IOWR(0xc6, struct drm_fence_arg) +#define DRM_IOCTL_FENCE_UNREFERENCE DRM_IOWR(0xc7, struct drm_fence_arg) +#define DRM_IOCTL_FENCE_SIGNALED DRM_IOWR(0xc8, struct drm_fence_arg) +#define DRM_IOCTL_FENCE_FLUSH DRM_IOWR(0xc9, struct drm_fence_arg) +#define DRM_IOCTL_FENCE_WAIT DRM_IOWR(0xca, struct drm_fence_arg) +#define DRM_IOCTL_FENCE_EMIT DRM_IOWR(0xcb, struct drm_fence_arg) +#define DRM_IOCTL_FENCE_BUFFERS DRM_IOWR(0xcc, struct drm_fence_arg) + +#define DRM_IOCTL_BO_CREATE DRM_IOWR(0xcd, struct drm_bo_create_arg) +#define DRM_IOCTL_BO_MAP DRM_IOWR(0xcf, struct drm_bo_map_wait_idle_arg) +#define DRM_IOCTL_BO_UNMAP DRM_IOWR(0xd0, struct drm_bo_handle_arg) +#define DRM_IOCTL_BO_REFERENCE DRM_IOWR(0xd1, struct drm_bo_reference_info_arg) +#define DRM_IOCTL_BO_UNREFERENCE DRM_IOWR(0xd2, struct drm_bo_handle_arg) +#define DRM_IOCTL_BO_SETSTATUS DRM_IOWR(0xd3, struct drm_bo_map_wait_idle_arg) +#define DRM_IOCTL_BO_INFO DRM_IOWR(0xd4, struct drm_bo_reference_info_arg) +#define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg) +#define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg) -#define DRM_IOCTL_FENCE DRM_IOWR(0x3b, drm_fence_arg_t) -#define DRM_IOCTL_BUFOBJ DRM_IOWR(0x3d, drm_bo_arg_t) -#define DRM_IOCTL_MM_INIT DRM_IOWR(0x3e, drm_mm_init_arg_t) - -#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, drm_update_draw_t) #define DRM_IOCTL_MODESET_CTL DRM_IOW(0xa0, drm_modeset_ctl_t) @@ -983,4 +1008,52 @@ typedef union drm_mm_init_arg{ #define DRM_COMMAND_BASE 0x40 #define DRM_COMMAND_END 0xA0 +/* typedef area */ +#if !defined(__KERNEL__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +typedef struct drm_clip_rect drm_clip_rect_t; +typedef struct drm_tex_region drm_tex_region_t; +typedef struct drm_hw_lock drm_hw_lock_t; +typedef struct drm_version drm_version_t; +typedef struct drm_unique drm_unique_t; +typedef struct drm_list drm_list_t; +typedef struct drm_block drm_block_t; +typedef struct drm_control drm_control_t; +typedef enum drm_map_type drm_map_type_t; +typedef enum drm_map_flags drm_map_flags_t; +typedef struct drm_ctx_priv_map drm_ctx_priv_map_t; +typedef struct drm_map drm_map_t; +typedef struct drm_client drm_client_t; +typedef enum drm_stat_type drm_stat_type_t; +typedef struct drm_stats drm_stats_t; +typedef enum drm_lock_flags drm_lock_flags_t; +typedef struct drm_lock drm_lock_t; +typedef enum drm_dma_flags drm_dma_flags_t; +typedef struct drm_buf_desc drm_buf_desc_t; +typedef struct drm_buf_info drm_buf_info_t; +typedef struct drm_buf_free drm_buf_free_t; +typedef struct drm_buf_pub drm_buf_pub_t; +typedef struct drm_buf_map drm_buf_map_t; +typedef struct drm_dma drm_dma_t; +typedef union drm_wait_vblank drm_wait_vblank_t; +typedef struct drm_agp_mode drm_agp_mode_t; +typedef enum drm_ctx_flags drm_ctx_flags_t; +typedef struct drm_ctx drm_ctx_t; +typedef struct drm_ctx_res drm_ctx_res_t; +typedef struct drm_draw drm_draw_t; +typedef struct drm_update_draw drm_update_draw_t; +typedef struct drm_auth drm_auth_t; +typedef struct drm_irq_busid drm_irq_busid_t; +typedef enum drm_vblank_seq_type drm_vblank_seq_type_t; +typedef struct drm_agp_buffer drm_agp_buffer_t; +typedef struct drm_agp_binding drm_agp_binding_t; +typedef struct drm_agp_info drm_agp_info_t; +typedef struct drm_scatter_gather drm_scatter_gather_t; +typedef struct drm_set_version drm_set_version_t; + +typedef struct drm_fence_arg drm_fence_arg_t; +typedef struct drm_mm_type_arg drm_mm_type_arg_t; +typedef struct drm_mm_init_arg drm_mm_init_arg_t; +typedef enum drm_bo_type drm_bo_type_t; +#endif + #endif diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt index ba02aa89..05d32f2e 100644 --- a/shared-core/drm_pciids.txt +++ b/shared-core/drm_pciids.txt @@ -211,6 +211,8 @@ 0x1039 0x6300 0 "SiS 630" 0x1039 0x6330 SIS_CHIP_315 "SiS 661" 0x1039 0x7300 0 "SiS 730" +0x18CA 0x0040 SIS_CHIP_315 "Volari V3XT/V5/V8" +0x18CA 0x0042 SIS_CHIP_315 "Volari Unknown" [tdfx] 0x121a 0x0003 0 "3dfx Voodoo Banshee" @@ -479,234 +481,6 @@ 0x10DE 0x009D NV40 "NVidia Quadro FX 4500" 0x10DE 0x009E NV40 "NVidia 0x009E" -[nouveau] -0x10de 0x0008 NV_03 "EDGE 3D" -0x10de 0x0009 NV_03 "EDGE 3D" -0x10de 0x0010 NV_03 "Mutara V08" -0x10de 0x0020 NV_04 "RIVA TNT" -0x10de 0x0028 NV_04 "RIVA TNT2/TNT2 Pro" -0x10de 0x0029 NV_04 "RIVA TNT2 Ultra" -0x10de 0x002a NV_04 "Riva TnT2" -0x10de 0x002b NV_04 "Riva TnT2" -0x10de 0x002c NV_04 "Vanta/Vanta LT" -0x10de 0x002d NV_04 "RIVA TNT2 Model 64/Model 64 Pro" -0x10de 0x002e NV_04 "Vanta" -0x10de 0x002f NV_04 "Vanta" -0x10de 0x0040 NV_40 "GeForce 6800 Ultra" -0x10de 0x0041 NV_40 "GeForce 6800" -0x10de 0x0042 NV_40 "GeForce 6800 LE" -0x10de 0x0043 NV_40 "NV40.3" -0x10de 0x0044 NV_40 "GeForce 6800 XT" -0x10de 0x0045 NV_40 "GeForce 6800 GT" -0x10de 0x0046 NV_40 "GeForce 6800 GT" -0x10de 0x0047 NV_40 "GeForce 6800 GS" -0x10de 0x0048 NV_40 "GeForce 6800 XT" -0x10de 0x0049 NV_40 "NV40GL" -0x10de 0x004d NV_40 "Quadro FX 4000" -0x10de 0x004e NV_40 "Quadro FX 4000" -0x10de 0x0090 NV_40 "GeForce 7800 GTX" -0x10de 0x0091 NV_40 "GeForce 7800 GTX" -0x10de 0x0092 NV_40 "GeForce 7800 GT" -0x10de 0x0093 NV_40 "GeForce 7800 GS" -0x10de 0x0098 NV_40 "GeForce Go 7800" -0x10de 0x0099 NV_40 "GE Force Go 7800 GTX" -0x10de 0x009d NV_40 "Quadro FX4500" -0x10de 0x00a0 NV_04 "Aladdin TNT2" -0x10de 0x00c0 NV_40 "GeForce 6800 GS" -0x10de 0x00c1 NV_40 "GeForce 6800" -0x10de 0x00c2 NV_40 "GeForce 6800 LE" -0x10de 0x00c3 NV_40 "Geforce 6800 XT" -0x10de 0x00c8 NV_40 "GeForce Go 6800" -0x10de 0x00c9 NV_40 "GeForce Go 6800 Ultra" -0x10de 0x00cc NV_40 "Quadro FX Go1400" -0x10de 0x00cd NV_40 "Quadro FX 3450/4000 SDI" -0x10de 0x00ce NV_40 "Quadro FX 1400" -0x10de 0x00f0 NV_40 "GeForce 6800/GeForce 6800 Ultra" -0x10de 0x00f1 NV_40 "GeForce 6600/GeForce 6600 GT" -0x10de 0x00f2 NV_40 "GeForce 6600/GeForce 6600 GT" -0x10de 0x00f3 NV_40 "GeForce 6200" -0x10de 0x00f4 NV_40 "GeForce 6600 LE" -0x10de 0x00f5 NV_40 "GeForce 7800 GS" -0x10de 0x00f6 NV_40 "GeForce 6600 GS" -0x10de 0x00f8 NV_40 "Quadro FX 3400/4400" -0x10de 0x00f9 NV_40 "GeForce 6800 Ultra/GeForce 6800 GT" -0x10de 0x00fa NV_30 "GeForce PCX 5750" -0x10de 0x00fb NV_30 "GeForce PCX 5900" -0x10de 0x00fc NV_30 "Quadro FX 330/GeForce PCX 5300" -0x10de 0x00fd NV_30 "Quadro FX 330/Quadro NVS280" -0x10de 0x00fe NV_30 "Quadro FX 1300" -0x10de 0x00ff NV_17 "GeForce PCX 4300" -0x10de 0x0100 NV_10 "GeForce 256 SDR" -0x10de 0x0101 NV_10 "GeForce 256 DDR" -0x10de 0x0103 NV_10 "Quadro" -0x10de 0x0110 NV_11 "GeForce2 MX/MX 400" -0x10de 0x0111 NV_11 "GeForce2 MX 100 DDR/200 DDR" -0x10de 0x0112 NV_11 "GeForce2 Go" -0x10de 0x0113 NV_11 "Quadro2 MXR/EX/Go" -0x10de 0x0140 NV_40 "GeForce 6600 GT" -0x10de 0x0141 NV_40 "GeForce 6600" -0x10de 0x0142 NV_40 "GeForce 6600 PCIe" -0x10de 0x0144 NV_40 "GeForce Go 6600" -0x10de 0x0145 NV_40 "GeForce 6610 XL" -0x10de 0x0146 NV_40 "Geforce Go 6600TE/6200TE" -0x10de 0x0148 NV_40 "GeForce Go 6600" -0x10de 0x0149 NV_40 "GeForce Go 6600 GT" -0x10de 0x014a NV_40 "Quadro NVS 440" -0x10de 0x014d NV_17 "Quadro FX 550" -0x10de 0x014e NV_40 "Quadro FX 540" -0x10de 0x014f NV_40 "GeForce 6200" -0x10de 0x0150 NV_15 "GeForce2 GTS/Pro" -0x10de 0x0151 NV_15 "GeForce2 Ti" -0x10de 0x0152 NV_15 "GeForce2 Ultra, Bladerunner" -0x10de 0x0153 NV_15 "Quadro2 Pro" -0x10de 0x0161 NV_44 "GeForce 6200 TurboCache(TM)" -0x10de 0x0162 NV_44 "GeForce 6200 SE TurboCache (TM)" -0x10de 0x0163 NV_44 "GeForce 6200 LE" -0x10de 0x0164 NV_44 "GeForce Go 6200" -0x10de 0x0165 NV_44 "Quadro NVS 285" -0x10de 0x0166 NV_44 "GeForce Go 6400" -0x10de 0x0167 NV_44 "GeForce Go 6200 TurboCache" -0x10de 0x0168 NV_44 "GeForce Go 6200 TurboCache" -0x10de 0x0170 NV_17 "GeForce4 MX 460" -0x10de 0x0171 NV_17 "GeForce4 MX 440" -0x10de 0x0172 NV_17 "GeForce4 MX 420" -0x10de 0x0173 NV_17 "GeForce4 MX 440-SE" -0x10de 0x0174 NV_17 "GeForce4 440 Go" -0x10de 0x0175 NV_17 "GeForce4 420 Go" -0x10de 0x0176 NV_17 "GeForce4 420 Go 32M" -0x10de 0x0177 NV_17 "GeForce4 460 Go" -0x10de 0x0178 NV_17 "Quadro4 550 XGL" -0x10de 0x0179 NV_17 "GeForce4 420 Go 32M" -0x10de 0x017a NV_17 "Quadro4 200/400 NVS" -0x10de 0x017b NV_17 "Quadro4 550 XGL" -0x10de 0x017c NV_17 "Quadro4 500 GoGL" -0x10de 0x017d NV_17 "GeForce4 410 Go 16M" -0x10de 0x0181 NV_17 "GeForce4 MX 440 AGP 8x" -0x10de 0x0182 NV_17 "GeForce4 MX 440SE AGP 8x" -0x10de 0x0183 NV_17 "GeForce4 MX 420 AGP 8x" -0x10de 0x0185 NV_17 "GeForce4 MX 4000 AGP 8x" -0x10de 0x0186 NV_17 "GeForce4 448 Go" -0x10de 0x0187 NV_17 "GeForce4 488 Go" -0x10de 0x0188 NV_17 "Quadro4 580 XGL" -0x10de 0x018a NV_17 "Quadro4 NVS AGP 8x" -0x10de 0x018b NV_17 "Quadro4 380 XGL" -0x10de 0x018c NV_17 "Quadro NVS 50 PCI" -0x10de 0x018d NV_17 "GeForce4 448 Go" -0x10de 0x0191 NV_50 "GeForce 8800 GTX" -0x10de 0x0193 NV_50 "GeForce 8800 GTS" -0x10de 0x01a0 NV_11|NV_NFORCE "GeForce2 MX Integrated Graphics" -0x10de 0x01d1 NV_44 "GeForce 7300 LE" -0x10de 0x01d6 NV_44 "GeForce Go 7200" -0x10de 0x01d7 NV_44 "Quadro NVS 110M / GeForce Go 7300" -0x10de 0x01d8 NV_44 "GeForce Go 7400" -0x10de 0x01da NV_44 "Quadro NVS 110M" -0x10de 0x01dc NV_44 "Quadro FX 350M" -0x10de 0x01df NV_44 "GeForce 7300 GS" -0x10de 0x01f0 NV_17|NV_NFORCE2 "GeForce4 MX - nForce GPU" -0x10de 0x0200 NV_20 "GeForce3" -0x10de 0x0201 NV_20 "GeForce3 Ti 200" -0x10de 0x0202 NV_20 "GeForce3 Ti 500" -0x10de 0x0203 NV_20 "Quadro DCC" -0x10de 0x0211 NV_40 "GeForce 6800" -0x10de 0x0212 NV_40 "GeForce 6800 LE" -0x10de 0x0215 NV_40 "GeForce 6800 GT" -0x10de 0x0218 NV_40 "GeForce 6800 XT" -0x10de 0x0221 NV_44 "GeForce 6200" -0x10de 0x0240 NV_44 "GeForce 6150" -0x10de 0x0242 NV_44 "GeForce 6100" -0x10de 0x0244 NV_44 "GeForce 6150 Go" -0x10de 0x0250 NV_25 "GeForce4 Ti 4600" -0x10de 0x0251 NV_25 "GeForce4 Ti 4400" -0x10de 0x0252 NV_25 "GeForce4 Ti" -0x10de 0x0253 NV_25 "GeForce4 Ti 4200" -0x10de 0x0258 NV_25 "Quadro4 900 XGL" -0x10de 0x0259 NV_25 "Quadro4 750 XGL" -0x10de 0x025b NV_25 "Quadro4 700 XGL" -0x10de 0x0280 NV_25 "GeForce4 Ti 4800" -0x10de 0x0281 NV_25 "GeForce4 Ti 4200 AGP 8x" -0x10de 0x0282 NV_25 "GeForce4 Ti 4800 SE" -0x10de 0x0286 NV_25 "GeForce4 Ti 4200 Go AGP 8x" -0x10de 0x0288 NV_25 "Quadro4 980 XGL" -0x10de 0x0289 NV_25 "Quadro4 780 XGL" -0x10de 0x028c NV_25 "Quadro4 700 GoGL" -0x10de 0x0290 NV_40 "GeForce 7900 GTX" -0x10de 0x0291 NV_40 "GeForce 7900 GT" -0x10de 0x0292 NV_40 "GeForce 7900 GS" -0x10de 0x0298 NV_40 "GeForce Go 7900 GS" -0x10de 0x0299 NV_40 "GeForce Go 7900 GTX" -0x10de 0x029a NV_40 "Quadro FX 2500M" -0x10de 0x029b NV_40 "Quadro FX 1500M" -0x10de 0x029c NV_40 "Quadro FX 5500" -0x10de 0x029d NV_40 "Quadro FX 3500" -0x10de 0x029e NV_40 "Quadro FX 1500" -0x10de 0x029f NV_40 "Quadro FX 4500 X2" -0x10de 0x02a0 NV_20 "XGPU" -0x10de 0x02e1 NV_40 "GeForce 7600 GS" -0x10de 0x0300 NV_30 "GeForce FX" -0x10de 0x0301 NV_30 "GeForce FX 5800 Ultra" -0x10de 0x0302 NV_30 "GeForce FX 5800" -0x10de 0x0308 NV_30 "Quadro FX 2000" -0x10de 0x0309 NV_30 "Quadro FX 1000" -0x10de 0x0311 NV_30 "GeForce FX 5600 Ultra" -0x10de 0x0312 NV_30 "GeForce FX 5600" -0x10de 0x0313 NV_30 "NV31" -0x10de 0x0314 NV_30 "GeForce FX 5600XT" -0x10de 0x0316 NV_30 "NV31M" -0x10de 0x0317 NV_30 "NV31M Pro" -0x10de 0x031a NV_30 "GeForce FX Go5600" -0x10de 0x031b NV_30 "GeForce FX Go5650" -0x10de 0x031d NV_30 "NV31GLM" -0x10de 0x031e NV_30 "NV31GLM Pro" -0x10de 0x031f NV_30 "NV31GLM Pro" -0x10de 0x0320 NV_34 "GeForce FX 5200" -0x10de 0x0321 NV_34 "GeForce FX 5200 Ultra" -0x10de 0x0322 NV_34 "GeForce FX 5200" -0x10de 0x0323 NV_34 "GeForce FX 5200LE" -0x10de 0x0324 NV_34 "GeForce FX Go5200" -0x10de 0x0325 NV_34 "GeForce FX Go5250" -0x10de 0x0326 NV_34 "GeForce FX 5500" -0x10de 0x0327 NV_34 "GeForce FX 5100" -0x10de 0x0328 NV_34 "GeForce FX Go5200 32M/64M" -0x10de 0x0329 NV_34 "GeForce FX Go5200" -0x10de 0x032a NV_34 "Quadro NVS 280 PCI" -0x10de 0x032b NV_34 "Quadro FX 500/600 PCI" -0x10de 0x032c NV_34 "GeForce FX Go 5300" -0x10de 0x032d NV_34 "GeForce FX Go5100" -0x10de 0x032f NV_34 "NV34GL" -0x10de 0x0330 NV_30 "GeForce FX 5900 Ultra" -0x10de 0x0331 NV_30 "GeForce FX 5900" -0x10de 0x0332 NV_30 "GeForce FX 5900XT" -0x10de 0x0333 NV_30 "GeForce FX 5950 Ultra" -0x10de 0x0334 NV_30 "GeForce FX 5900ZT" -0x10de 0x0338 NV_30 "Quadro FX 3000" -0x10de 0x033f NV_30 "Quadro FX 700" -0x10de 0x0341 NV_30 "GeForce FX 5700 Ultra" -0x10de 0x0342 NV_30 "GeForce FX 5700" -0x10de 0x0343 NV_30 "GeForce FX 5700LE" -0x10de 0x0344 NV_30 "GeForce FX 5700VE" -0x10de 0x0345 NV_30 "NV36.5" -0x10de 0x0347 NV_30 "GeForce FX Go5700" -0x10de 0x0348 NV_30 "GeForce FX Go5700" -0x10de 0x0349 NV_30 "NV36M Pro" -0x10de 0x034b NV_30 "NV36MAP" -0x10de 0x034c NV_30 "Quadro FX Go1000" -0x10de 0x034e NV_30 "Quadro FX 1100" -0x10de 0x034f NV_30 "NV36GL" -0x10de 0x0391 NV_40 "GeForce 7600 GT" -0x10de 0x0392 NV_40 "GeForce 7600 GS" -0x10de 0x0393 NV_40 "GeForce 7300 GT" -0x10de 0x0398 NV_40 "GeForce Go 7600" -0x10de 0x03d0 NV_44 "GeForce 6100 nForce 430" -0x10de 0x03d1 NV_44 "GeForce 6100 nForce 405" -0x10de 0x03d2 NV_44 "GeForce 6100 nForce 400" -0x10de 0x03d5 NV_44 "GeForce 6100 nForce 420" -0x12d2 0x0008 NV_03 "NV1" -0x12d2 0x0009 NV_03 "DAC64" -0x12d2 0x0018 NV_03 "Riva128" -0x12d2 0x0019 NV_03 "Riva128ZX" -0x12d2 0x0020 NV_04 "TNT" -0x12d2 0x0028 NV_04 "TNT2" -0x12d2 0x0029 NV_04 "UTNT2" -0x12d2 0x002c NV_04 "VTNT2" -0x12d2 0x00a0 NV_04 "ITNT2" - +[xgi] +0x18ca 0x2200 0 "XP5" +0x18ca 0x0047 0 "XP10 / XG47" diff --git a/shared-core/drm_sarea.h b/shared-core/drm_sarea.h index 43d1114f..34050a6d 100644 --- a/shared-core/drm_sarea.h +++ b/shared-core/drm_sarea.h @@ -50,29 +50,35 @@ #define SAREA_DRAWABLE_CLAIMED_ENTRY 0x80000000 /** SAREA drawable */ -typedef struct drm_sarea_drawable { +struct drm_sarea_drawable { unsigned int stamp; unsigned int flags; -} drm_sarea_drawable_t; +}; /** SAREA frame */ -typedef struct drm_sarea_frame { +struct drm_sarea_frame { unsigned int x; unsigned int y; unsigned int width; unsigned int height; unsigned int fullscreen; -} drm_sarea_frame_t; +}; /** SAREA */ -typedef struct drm_sarea { +struct drm_sarea { /** first thing is always the DRM locking structure */ - drm_hw_lock_t lock; + struct drm_hw_lock lock; /** \todo Use readers/writer lock for drm_sarea::drawable_lock */ - drm_hw_lock_t drawable_lock; - drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */ - drm_sarea_frame_t frame; /**< frame */ + struct drm_hw_lock drawable_lock; + struct drm_sarea_drawable drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */ + struct drm_sarea_frame frame; /**< frame */ drm_context_t dummy_context; -} drm_sarea_t; +}; + +#ifndef __KERNEL__ +typedef struct drm_sarea_drawable drm_sarea_drawable_t; +typedef struct drm_sarea_frame drm_sarea_frame_t; +typedef struct drm_sarea drm_sarea_t; +#endif #endif /* _DRM_SAREA_H_ */ diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index b2398896..24a4ec4a 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -36,7 +36,7 @@ * the head pointer changes, so that EBUSY only happens if the ring * actually stalls for (eg) 3 seconds. */ -int i915_wait_ring(drm_device_t * dev, int n, const char *caller) +int i915_wait_ring(struct drm_device * dev, int n, const char *caller) { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_ring_buffer_t *ring = &(dev_priv->ring); @@ -60,10 +60,10 @@ int i915_wait_ring(drm_device_t * dev, int n, const char *caller) DRM_UDELAY(1); } - return DRM_ERR(EBUSY); + return -EBUSY; } -void i915_kernel_lost_context(drm_device_t * dev) +void i915_kernel_lost_context(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_ring_buffer_t *ring = &(dev_priv->ring); @@ -78,8 +78,9 @@ void i915_kernel_lost_context(drm_device_t * dev) dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; } -static int i915_dma_cleanup(drm_device_t * dev) +static int i915_dma_cleanup(struct drm_device * dev) { + drm_i915_private_t *dev_priv = dev->dev_private; /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. @@ -87,55 +88,51 @@ static int i915_dma_cleanup(drm_device_t * dev) if (dev->irq) drm_irq_uninstall(dev); - if (dev->dev_private) { - drm_i915_private_t *dev_priv = - (drm_i915_private_t *) dev->dev_private; - - if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->ring.map, dev); - } + if (dev_priv->ring.virtual_start) { + drm_core_ioremapfree(&dev_priv->ring.map, dev); + dev_priv->ring.virtual_start = 0; + dev_priv->ring.map.handle = 0; + dev_priv->ring.map.size = 0; + } - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - /* Need to rewrite hardware status page */ - I915_WRITE(0x02080, 0x1ffff000); - } - if (dev_priv->status_gfx_addr) { - dev_priv->status_gfx_addr = 0; - drm_core_ioremapfree(&dev_priv->hws_map, dev); - I915_WRITE(0x02080, 0x1ffff000); - } - drm_free(dev->dev_private, sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); + if (dev_priv->status_page_dmah) { + drm_pci_free(dev, dev_priv->status_page_dmah); + dev_priv->status_page_dmah = NULL; + /* Need to rewrite hardware status page */ + I915_WRITE(0x02080, 0x1ffff000); + } - dev->dev_private = NULL; + if (dev_priv->status_gfx_addr) { + dev_priv->status_gfx_addr = 0; + drm_core_ioremapfree(&dev_priv->hws_map, dev); + I915_WRITE(0x02080, 0x1ffff000); } return 0; } -static int i915_initialize(drm_device_t * dev, - drm_i915_private_t * dev_priv, - drm_i915_init_t * init) +static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) { - memset(dev_priv, 0, sizeof(drm_i915_private_t)); + drm_i915_private_t *dev_priv = dev->dev_private; dev_priv->sarea = drm_getsarea(dev); if (!dev_priv->sarea) { DRM_ERROR("can not find sarea!\n"); - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); if (!dev_priv->mmio_map) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("can not find mmio map!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } +#ifdef I915_HAVE_BUFFER + dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; +#endif + dev_priv->sarea_priv = (drm_i915_sarea_t *) ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); @@ -153,11 +150,10 @@ static int i915_initialize(drm_device_t * dev, drm_core_ioremap(&dev_priv->ring.map, dev); if (dev_priv->ring.map.handle == NULL) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } dev_priv->ring.virtual_start = dev_priv->ring.map.handle; @@ -184,10 +180,9 @@ static int i915_initialize(drm_device_t * dev, drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); if (!dev_priv->status_page_dmah) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); DRM_ERROR("Can not allocate hardware status page\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; @@ -197,11 +192,11 @@ static int i915_initialize(drm_device_t * dev, I915_WRITE(0x02080, dev_priv->dma_status_page); } DRM_DEBUG("Enabled hardware status page\n"); - dev->dev_private = (void *)dev_priv; + mutex_init(&dev_priv->cmdbuf_mutex); return 0; } -static int i915_dma_resume(drm_device_t * dev) +static int i915_dma_resume(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -209,24 +204,24 @@ static int i915_dma_resume(drm_device_t * dev) if (!dev_priv->sarea) { DRM_ERROR("can not find sarea!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (!dev_priv->mmio_map) { DRM_ERROR("can not find mmio map!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (dev_priv->ring.map.handle == NULL) { DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } /* Program Hardware Status Page */ if (!dev_priv->hw_status_page) { DRM_ERROR("Can not find hardware status page\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); @@ -239,23 +234,15 @@ static int i915_dma_resume(drm_device_t * dev) return 0; } -static int i915_dma_init(DRM_IOCTL_ARGS) +static int i915_dma_init(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; - drm_i915_private_t *dev_priv; - drm_i915_init_t init; + drm_i915_init_t *init = data; int retcode = 0; - DRM_COPY_FROM_USER_IOCTL(init, (drm_i915_init_t __user *) data, - sizeof(init)); - - switch (init.func) { + switch (init->func) { case I915_INIT_DMA: - dev_priv = drm_alloc(sizeof(drm_i915_private_t), - DRM_MEM_DRIVER); - if (dev_priv == NULL) - return DRM_ERR(ENOMEM); - retcode = i915_initialize(dev, dev_priv, &init); + retcode = i915_initialize(dev, init); break; case I915_CLEANUP_DMA: retcode = i915_dma_cleanup(dev); @@ -264,7 +251,7 @@ static int i915_dma_init(DRM_IOCTL_ARGS) retcode = i915_dma_resume(dev); break; default: - retcode = DRM_ERR(EINVAL); + retcode = -EINVAL; break; } @@ -347,14 +334,15 @@ static int validate_cmd(int cmd) return ret; } -static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) +static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, + int dwords) { drm_i915_private_t *dev_priv = dev->dev_private; int i; RING_LOCALS; if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) - return DRM_ERR(EINVAL); + return -EINVAL; BEGIN_LP_RING((dwords+1)&~1); @@ -362,17 +350,17 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) int cmd, sz; if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) - return DRM_ERR(EINVAL); + return -EINVAL; if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) - return DRM_ERR(EINVAL); + return -EINVAL; OUT_RING(cmd); while (++i, --sz) { if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) { - return DRM_ERR(EINVAL); + return -EINVAL; } OUT_RING(cmd); } @@ -386,22 +374,22 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) return 0; } -static int i915_emit_box(drm_device_t * dev, - drm_clip_rect_t __user * boxes, +static int i915_emit_box(struct drm_device * dev, + struct drm_clip_rect __user * boxes, int i, int DR1, int DR4) { drm_i915_private_t *dev_priv = dev->dev_private; - drm_clip_rect_t box; + struct drm_clip_rect box; RING_LOCALS; if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { - return DRM_ERR(EFAULT); + return -EFAULT; } if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { DRM_ERROR("Bad box %d,%d..%d,%d\n", box.x1, box.y1, box.x2, box.y2); - return DRM_ERR(EINVAL); + return -EINVAL; } if (IS_I965G(dev)) { @@ -429,15 +417,17 @@ static int i915_emit_box(drm_device_t * dev, * emit. For now, do it in both places: */ -void i915_emit_breadcrumb(drm_device_t *dev) +void i915_emit_breadcrumb(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; RING_LOCALS; - dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; + if (++dev_priv->counter > BREADCRUMB_MASK) { + dev_priv->counter = 1; + DRM_DEBUG("Breadcrumb counter wrapped around\n"); + } - if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; + dev_priv->sarea_priv->last_enqueue = dev_priv->counter; BEGIN_LP_RING(4); OUT_RING(CMD_STORE_DWORD_IDX); @@ -448,7 +438,7 @@ void i915_emit_breadcrumb(drm_device_t *dev) } -int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush) +int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush) { drm_i915_private_t *dev_priv = dev->dev_private; uint32_t flush_cmd = CMD_MI_FLUSH; @@ -469,7 +459,7 @@ int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush) } -static int i915_dispatch_cmdbuffer(drm_device_t * dev, +static int i915_dispatch_cmdbuffer(struct drm_device * dev, drm_i915_cmdbuffer_t * cmd) { #ifdef I915_HAVE_FENCE @@ -479,8 +469,8 @@ static int i915_dispatch_cmdbuffer(drm_device_t * dev, int i = 0, count, ret; if (cmd->sz & 0x3) { - DRM_ERROR("alignment"); - return DRM_ERR(EINVAL); + DRM_ERROR("alignment\n"); + return -EINVAL; } i915_kernel_lost_context(dev); @@ -507,18 +497,18 @@ static int i915_dispatch_cmdbuffer(drm_device_t * dev, return 0; } -static int i915_dispatch_batchbuffer(drm_device_t * dev, +static int i915_dispatch_batchbuffer(struct drm_device * dev, drm_i915_batchbuffer_t * batch) { drm_i915_private_t *dev_priv = dev->dev_private; - drm_clip_rect_t __user *boxes = batch->cliprects; + struct drm_clip_rect __user *boxes = batch->cliprects; int nbox = batch->num_cliprects; int i = 0, count; RING_LOCALS; if ((batch->start | batch->used) & 0x7) { - DRM_ERROR("alignment"); - return DRM_ERR(EINVAL); + DRM_ERROR("alignment\n"); + return -EINVAL; } i915_kernel_lost_context(dev); @@ -535,9 +525,15 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev, if (dev_priv->use_mi_batchbuffer_start) { BEGIN_LP_RING(2); - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); - OUT_RING(batch->start | MI_BATCH_NON_SECURE); + if (IS_I965G(dev)) { + OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); + OUT_RING(batch->start); + } else { + OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); + OUT_RING(batch->start | MI_BATCH_NON_SECURE); + } ADVANCE_LP_RING(); + } else { BEGIN_LP_RING(4); OUT_RING(MI_BATCH_BUFFER); @@ -555,11 +551,11 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev, return 0; } -static void i915_do_dispatch_flip(drm_device_t * dev, int pipe, int sync) +static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync) { drm_i915_private_t *dev_priv = dev->dev_private; u32 num_pages, current_page, next_page, dspbase; - int shift = 2 * pipe, x, y; + int shift = 2 * plane, x, y; RING_LOCALS; /* Calculate display base offset */ @@ -580,25 +576,25 @@ static void i915_do_dispatch_flip(drm_device_t * dev, int pipe, int sync) break; } - if (pipe == 0) { - x = dev_priv->sarea_priv->pipeA_x; - y = dev_priv->sarea_priv->pipeA_y; + if (plane == 0) { + x = dev_priv->sarea_priv->planeA_x; + y = dev_priv->sarea_priv->planeA_y; } else { - x = dev_priv->sarea_priv->pipeB_x; - y = dev_priv->sarea_priv->pipeB_y; + x = dev_priv->sarea_priv->planeB_x; + y = dev_priv->sarea_priv->planeB_y; } dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp; - DRM_DEBUG("pipe=%d current_page=%d dspbase=0x%x\n", pipe, current_page, + DRM_DEBUG("plane=%d current_page=%d dspbase=0x%x\n", plane, current_page, dspbase); BEGIN_LP_RING(4); OUT_RING(sync ? 0 : - (MI_WAIT_FOR_EVENT | (pipe ? MI_WAIT_FOR_PLANE_B_FLIP : + (MI_WAIT_FOR_EVENT | (plane ? MI_WAIT_FOR_PLANE_B_FLIP : MI_WAIT_FOR_PLANE_A_FLIP))); OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) | - (pipe ? DISPLAY_PLANE_B : DISPLAY_PLANE_A)); + (plane ? DISPLAY_PLANE_B : DISPLAY_PLANE_A)); OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp); OUT_RING(dspbase); ADVANCE_LP_RING(); @@ -607,19 +603,19 @@ static void i915_do_dispatch_flip(drm_device_t * dev, int pipe, int sync) dev_priv->sarea_priv->pf_current_page |= next_page << shift; } -void i915_dispatch_flip(drm_device_t * dev, int pipes, int sync) +void i915_dispatch_flip(struct drm_device * dev, int planes, int sync) { drm_i915_private_t *dev_priv = dev->dev_private; int i; - DRM_DEBUG("%s: pipes=0x%x pfCurrentPage=%d\n", + DRM_DEBUG("%s: planes=0x%x pfCurrentPage=%d\n", __FUNCTION__, - pipes, dev_priv->sarea_priv->pf_current_page); + planes, dev_priv->sarea_priv->pf_current_page); i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH); for (i = 0; i < 2; i++) - if (pipes & (1 << i)) + if (planes & (1 << i)) i915_do_dispatch_flip(dev, i, sync); i915_emit_breadcrumb(dev); @@ -629,7 +625,7 @@ void i915_dispatch_flip(drm_device_t * dev, int pipes, int sync) #endif } -static int i915_quiescent(drm_device_t * dev) +static int i915_quiescent(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -637,74 +633,68 @@ static int i915_quiescent(drm_device_t * dev) return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__); } -static int i915_flush_ioctl(DRM_IOCTL_ARGS) +static int i915_flush_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); return i915_quiescent(dev); } -static int i915_batchbuffer(DRM_IOCTL_ARGS) +static int i915_batchbuffer(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) dev_priv->sarea_priv; - drm_i915_batchbuffer_t batch; + drm_i915_batchbuffer_t *batch = data; int ret; if (!dev_priv->allow_batchbuffer) { DRM_ERROR("Batchbuffer ioctl disabled\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(batch, (drm_i915_batchbuffer_t __user *) data, - sizeof(batch)); - DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n", - batch.start, batch.used, batch.num_cliprects); + batch->start, batch->used, batch->num_cliprects); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); - if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects, - batch.num_cliprects * - sizeof(drm_clip_rect_t))) - return DRM_ERR(EFAULT); + if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, + batch->num_cliprects * + sizeof(struct drm_clip_rect))) + return -EFAULT; - ret = i915_dispatch_batchbuffer(dev, &batch); + ret = i915_dispatch_batchbuffer(dev, batch); sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); return ret; } -static int i915_cmdbuffer(DRM_IOCTL_ARGS) +static int i915_cmdbuffer(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) dev_priv->sarea_priv; - drm_i915_cmdbuffer_t cmdbuf; + drm_i915_cmdbuffer_t *cmdbuf = data; int ret; - DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_i915_cmdbuffer_t __user *) data, - sizeof(cmdbuf)); - DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", - cmdbuf.buf, cmdbuf.sz, cmdbuf.num_cliprects); + cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); - if (cmdbuf.num_cliprects && - DRM_VERIFYAREA_READ(cmdbuf.cliprects, - cmdbuf.num_cliprects * - sizeof(drm_clip_rect_t))) { + if (cmdbuf->num_cliprects && + DRM_VERIFYAREA_READ(cmdbuf->cliprects, + cmdbuf->num_cliprects * + sizeof(struct drm_clip_rect))) { DRM_ERROR("Fault accessing cliprects\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } - ret = i915_dispatch_cmdbuffer(dev, &cmdbuf); + ret = i915_dispatch_cmdbuffer(dev, cmdbuf); if (ret) { DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); return ret; @@ -714,68 +704,445 @@ static int i915_cmdbuffer(DRM_IOCTL_ARGS) return 0; } -static int i915_do_cleanup_pageflip(drm_device_t * dev) +#ifdef I915_HAVE_BUFFER +struct i915_relocatee_info { + struct drm_buffer_object *buf; + unsigned long offset; + u32 *data_page; + unsigned page_offset; + struct drm_bo_kmap_obj kmap; + int is_iomem; +}; + +static void i915_dereference_buffers_locked(struct drm_buffer_object **buffers, + unsigned num_buffers) +{ + while (num_buffers--) + drm_bo_usage_deref_locked(&buffers[num_buffers]); +} + +int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, + struct drm_buffer_object **buffers, + struct i915_relocatee_info *relocatee, + uint32_t *reloc) +{ + unsigned index; + unsigned long new_cmd_offset; + u32 val; + int ret; + + if (reloc[2] >= num_buffers) { + DRM_ERROR("Illegal relocation buffer %08X\n", reloc[2]); + return -EINVAL; + } + + new_cmd_offset = reloc[0]; + if (!relocatee->data_page || + !drm_bo_same_page(relocatee->offset, new_cmd_offset)) { + drm_bo_kunmap(&relocatee->kmap); + relocatee->offset = new_cmd_offset; + ret = drm_bo_kmap(relocatee->buf, new_cmd_offset >> PAGE_SHIFT, + 1, &relocatee->kmap); + if (ret) { + DRM_ERROR("Could not map command buffer to apply relocs\n %08lx", new_cmd_offset); + return ret; + } + + relocatee->data_page = drm_bmo_virtual(&relocatee->kmap, + &relocatee->is_iomem); + relocatee->page_offset = (relocatee->offset & PAGE_MASK); + } + + val = buffers[reloc[2]]->offset; + index = (reloc[0] - relocatee->page_offset) >> 2; + + /* add in validate */ + val = val + reloc[1]; + + relocatee->data_page[index] = val; + return 0; +} + +int i915_process_relocs(struct drm_file *file_priv, + uint32_t buf_handle, + uint32_t *reloc_buf_handle, + struct i915_relocatee_info *relocatee, + struct drm_buffer_object **buffers, + uint32_t num_buffers) +{ + struct drm_device *dev = file_priv->head->dev; + struct drm_buffer_object *reloc_list_object; + uint32_t cur_handle = *reloc_buf_handle; + uint32_t *reloc_page; + int ret, reloc_is_iomem, reloc_stride; + uint32_t num_relocs, reloc_offset, reloc_end, reloc_page_offset, next_offset, cur_offset; + struct drm_bo_kmap_obj reloc_kmap; + + memset(&reloc_kmap, 0, sizeof(reloc_kmap)); + + mutex_lock(&dev->struct_mutex); + reloc_list_object = drm_lookup_buffer_object(file_priv, cur_handle, 1); + mutex_unlock(&dev->struct_mutex); + if (!reloc_list_object) + return -EINVAL; + + ret = drm_bo_kmap(reloc_list_object, 0, 1, &reloc_kmap); + if (ret) { + DRM_ERROR("Could not map relocation buffer.\n"); + goto out; + } + + reloc_page = drm_bmo_virtual(&reloc_kmap, &reloc_is_iomem); + num_relocs = reloc_page[0] & 0xffff; + + if ((reloc_page[0] >> 16) & 0xffff) { + DRM_ERROR("Unsupported relocation type requested\n"); + goto out; + } + + /* get next relocate buffer handle */ + *reloc_buf_handle = reloc_page[1]; + reloc_stride = I915_RELOC0_STRIDE * sizeof(uint32_t); /* may be different for other types of relocs */ + + DRM_DEBUG("num relocs is %d, next is %08X\n", num_relocs, reloc_page[1]); + + reloc_page_offset = 0; + reloc_offset = I915_RELOC_HEADER * sizeof(uint32_t); + reloc_end = reloc_offset + (num_relocs * reloc_stride); + + do { + next_offset = drm_bo_offset_end(reloc_offset, reloc_end); + + do { + cur_offset = ((reloc_offset + reloc_page_offset) & ~PAGE_MASK) / sizeof(uint32_t); + ret = i915_apply_reloc(file_priv, num_buffers, + buffers, relocatee, &reloc_page[cur_offset]); + if (ret) + goto out; + + reloc_offset += reloc_stride; + } while (reloc_offset < next_offset); + + drm_bo_kunmap(&reloc_kmap); + + reloc_offset = next_offset; + if (reloc_offset != reloc_end) { + ret = drm_bo_kmap(reloc_list_object, reloc_offset >> PAGE_SHIFT, 1, &reloc_kmap); + if (ret) { + DRM_ERROR("Could not map relocation buffer.\n"); + goto out; + } + + reloc_page = drm_bmo_virtual(&reloc_kmap, &reloc_is_iomem); + reloc_page_offset = reloc_offset & ~PAGE_MASK; + } + + } while (reloc_offset != reloc_end); +out: + drm_bo_kunmap(&relocatee->kmap); + relocatee->data_page = NULL; + + drm_bo_kunmap(&reloc_kmap); + + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(&reloc_list_object); + mutex_unlock(&dev->struct_mutex); + + return ret; +} + +static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, + drm_handle_t buf_reloc_handle, + struct drm_buffer_object **buffers, + uint32_t buf_count) +{ + struct drm_device *dev = file_priv->head->dev; + struct i915_relocatee_info relocatee; + int ret = 0; + + memset(&relocatee, 0, sizeof(relocatee)); + + mutex_lock(&dev->struct_mutex); + relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1); + mutex_unlock(&dev->struct_mutex); + if (!relocatee.buf) { + DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle); + ret = -EINVAL; + goto out_err; + } + + while (buf_reloc_handle) { + ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count); + if (ret) { + DRM_ERROR("process relocs failed\n"); + break; + } + } + + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(&relocatee.buf); + mutex_unlock(&dev->struct_mutex); + +out_err: + return ret; +} + +/* + * Validate, add fence and relocate a block of bos from a userspace list + */ +int i915_validate_buffer_list(struct drm_file *file_priv, + unsigned int fence_class, uint64_t data, + struct drm_buffer_object **buffers, + uint32_t *num_buffers) +{ + struct drm_i915_op_arg arg; + struct drm_bo_op_req *req = &arg.d.req; + struct drm_bo_arg_rep rep; + unsigned long next = 0; + int ret = 0; + unsigned buf_count = 0; + struct drm_device *dev = file_priv->head->dev; + uint32_t buf_reloc_handle, buf_handle; + + + do { + if (buf_count >= *num_buffers) { + DRM_ERROR("Buffer count exceeded %d\n.", *num_buffers); + ret = -EINVAL; + goto out_err; + } + + buffers[buf_count] = NULL; + + if (copy_from_user(&arg, (void __user *)(unsigned)data, sizeof(arg))) { + ret = -EFAULT; + goto out_err; + } + + if (arg.handled) { + data = arg.next; + mutex_lock(&dev->struct_mutex); + buffers[buf_count] = drm_lookup_buffer_object(file_priv, req->arg_handle, 1); + mutex_unlock(&dev->struct_mutex); + buf_count++; + continue; + } + + rep.ret = 0; + if (req->op != drm_bo_validate) { + DRM_ERROR + ("Buffer object operation wasn't \"validate\".\n"); + rep.ret = -EINVAL; + goto out_err; + } + + buf_handle = req->bo_req.handle; + buf_reloc_handle = arg.reloc_handle; + + if (buf_reloc_handle) { + ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count); + if (ret) + goto out_err; + DRM_MEMORYBARRIER(); + } + + rep.ret = drm_bo_handle_validate(file_priv, req->bo_req.handle, + req->bo_req.fence_class, + req->bo_req.flags, + req->bo_req.mask, + req->bo_req.hint, + 0, + &rep.bo_info, + &buffers[buf_count]); + + if (rep.ret) { + DRM_ERROR("error on handle validate %d\n", rep.ret); + goto out_err; + } + + + next = arg.next; + arg.handled = 1; + arg.d.rep = rep; + + if (copy_to_user((void __user *)(unsigned)data, &arg, sizeof(arg))) + return -EFAULT; + + data = next; + buf_count++; + + } while (next != 0); + *num_buffers = buf_count; + return 0; +out_err: + mutex_lock(&dev->struct_mutex); + i915_dereference_buffers_locked(buffers, buf_count); + mutex_unlock(&dev->struct_mutex); + *num_buffers = 0; + return (ret) ? ret : rep.ret; +} + +static int i915_execbuffer(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) + dev_priv->sarea_priv; + struct drm_i915_execbuffer *exec_buf = data; + struct _drm_i915_batchbuffer *batch = &exec_buf->batch; + struct drm_fence_arg *fence_arg = &exec_buf->fence_arg; + int num_buffers; + int ret; + struct drm_buffer_object **buffers; + struct drm_fence_object *fence; + + if (!dev_priv->allow_batchbuffer) { + DRM_ERROR("Batchbuffer ioctl disabled\n"); + return -EINVAL; + } + + + if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, + batch->num_cliprects * + sizeof(struct drm_clip_rect))) + return -EFAULT; + + if (exec_buf->num_buffers > dev_priv->max_validate_buffers) + return -EINVAL; + + + ret = drm_bo_read_lock(&dev->bm.bm_lock); + if (ret) + return ret; + + /* + * The cmdbuf_mutex makes sure the validate-submit-fence + * operation is atomic. + */ + + ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex); + if (ret) { + drm_bo_read_unlock(&dev->bm.bm_lock); + return -EAGAIN; + } + + num_buffers = exec_buf->num_buffers; + + buffers = drm_calloc(num_buffers, sizeof(struct drm_buffer_object *), DRM_MEM_DRIVER); + if (!buffers) { + drm_bo_read_unlock(&dev->bm.bm_lock); + mutex_unlock(&dev_priv->cmdbuf_mutex); + return -ENOMEM; + } + + /* validate buffer list + fixup relocations */ + ret = i915_validate_buffer_list(file_priv, 0, exec_buf->ops_list, + buffers, &num_buffers); + if (ret) + goto out_free; + + /* make sure all previous memory operations have passed */ + DRM_MEMORYBARRIER(); + + /* submit buffer */ + batch->start = buffers[num_buffers-1]->offset; + + DRM_DEBUG("i915 exec batchbuffer, start %x used %d cliprects %d\n", + batch->start, batch->used, batch->num_cliprects); + + ret = i915_dispatch_batchbuffer(dev, batch); + if (ret) + goto out_err0; + + sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); + + /* fence */ + ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence); + if (ret) + goto out_err0; + + if (!(fence_arg->flags & DRM_FENCE_FLAG_NO_USER)) { + ret = drm_fence_add_user_object(file_priv, fence, fence_arg->flags & DRM_FENCE_FLAG_SHAREABLE); + if (!ret) { + fence_arg->handle = fence->base.hash.key; + fence_arg->fence_class = fence->fence_class; + fence_arg->type = fence->type; + fence_arg->signaled = fence->signaled; + } + } + drm_fence_usage_deref_unlocked(&fence); +out_err0: + + /* handle errors */ + mutex_lock(&dev->struct_mutex); + i915_dereference_buffers_locked(buffers, num_buffers); + mutex_unlock(&dev->struct_mutex); + +out_free: + drm_free(buffers, (exec_buf->num_buffers * sizeof(struct drm_buffer_object *)), DRM_MEM_DRIVER); + + mutex_unlock(&dev_priv->cmdbuf_mutex); + drm_bo_read_unlock(&dev->bm.bm_lock); + return ret; +} +#endif + +static int i915_do_cleanup_pageflip(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; - int i, pipes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; + int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; DRM_DEBUG("%s\n", __FUNCTION__); - for (i = 0, pipes = 0; i < 2; i++) + for (i = 0, planes = 0; i < 2; i++) if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) { dev_priv->sarea_priv->pf_current_page = (dev_priv->sarea_priv->pf_current_page & ~(0x3 << (2 * i))) | (num_pages - 1) << (2 * i); - pipes |= 1 << i; + planes |= 1 << i; } - if (pipes) - i915_dispatch_flip(dev, pipes, 0); + if (planes) + i915_dispatch_flip(dev, planes, 0); return 0; } -static int i915_flip_bufs(DRM_IOCTL_ARGS) +static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_i915_flip_t param; + drm_i915_flip_t *param = data; DRM_DEBUG("%s\n", __FUNCTION__); - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_flip_t __user *) data, - sizeof(param)); + LOCK_TEST_WITH_RETURN(dev, file_priv); - if (param.pipes & ~0x3) { - DRM_ERROR("Invalid pipes 0x%x, only <= 0x3 is valid\n", - param.pipes); - return DRM_ERR(EINVAL); + /* This is really planes */ + if (param->pipes & ~0x3) { + DRM_ERROR("Invalid planes 0x%x, only <= 0x3 is valid\n", + param->pipes); + return -EINVAL; } - i915_dispatch_flip(dev, param.pipes, 0); + i915_dispatch_flip(dev, param->pipes, 0); return 0; } -static int i915_getparam(DRM_IOCTL_ARGS) +static int i915_getparam(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_getparam_t param; + drm_i915_getparam_t *param = data; int value; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_getparam_t __user *) data, - sizeof(param)); - - switch (param.param) { + switch (param->param) { case I915_PARAM_IRQ_ACTIVE: value = dev->irq ? 1 : 0; break; @@ -786,45 +1153,42 @@ static int i915_getparam(DRM_IOCTL_ARGS) value = READ_BREADCRUMB(dev_priv); break; default: - DRM_ERROR("Unknown parameter %d\n", param.param); - return DRM_ERR(EINVAL); + DRM_ERROR("Unknown parameter %d\n", param->param); + return -EINVAL; } - if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { + if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { DRM_ERROR("DRM_COPY_TO_USER failed\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } return 0; } -static int i915_setparam(DRM_IOCTL_ARGS) +static int i915_setparam(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_setparam_t param; + drm_i915_setparam_t *param = data; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_setparam_t __user *) data, - sizeof(param)); - - switch (param.param) { + switch (param->param) { case I915_SETPARAM_USE_MI_BATCHBUFFER_START: - dev_priv->use_mi_batchbuffer_start = param.value; + dev_priv->use_mi_batchbuffer_start = param->value; break; case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: - dev_priv->tex_lru_log_granularity = param.value; + dev_priv->tex_lru_log_granularity = param->value; break; case I915_SETPARAM_ALLOW_BATCHBUFFER: - dev_priv->allow_batchbuffer = param.value; + dev_priv->allow_batchbuffer = param->value; break; default: - DRM_ERROR("unknown parameter %d\n", param.param); - return DRM_ERR(EINVAL); + DRM_ERROR("unknown parameter %d\n", param->param); + return -EINVAL; } return 0; @@ -840,68 +1204,68 @@ drm_i915_mmio_entry_t mmio_table[] = { static int mmio_table_size = sizeof(mmio_table)/sizeof(drm_i915_mmio_entry_t); -static int i915_mmio(DRM_IOCTL_ARGS) +static int i915_mmio(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - char buf[32]; - DRM_DEVICE; + uint32_t buf[8]; drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_mmio_entry_t *e; - drm_i915_mmio_t mmio; + drm_i915_mmio_t *mmio = data; void __iomem *base; + int i; + if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(mmio, (drm_i915_mmio_t __user *) data, - sizeof(mmio)); - if (mmio.reg >= mmio_table_size) - return DRM_ERR(EINVAL); + if (mmio->reg >= mmio_table_size) + return -EINVAL; - e = &mmio_table[mmio.reg]; + e = &mmio_table[mmio->reg]; base = (u8 *) dev_priv->mmio_map->handle + e->offset; - switch (mmio.read_write) { + switch (mmio->read_write) { case I915_MMIO_READ: if (!(e->flag & I915_MMIO_MAY_READ)) - return DRM_ERR(EINVAL); - memcpy_fromio(buf, base, e->size); - if (DRM_COPY_TO_USER(mmio.data, buf, e->size)) { + return -EINVAL; + for (i = 0; i < e->size / 4; i++) + buf[i] = I915_READ(e->offset + i * 4); + if (DRM_COPY_TO_USER(mmio->data, buf, e->size)) { DRM_ERROR("DRM_COPY_TO_USER failed\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } break; case I915_MMIO_WRITE: if (!(e->flag & I915_MMIO_MAY_WRITE)) - return DRM_ERR(EINVAL); - if(DRM_COPY_FROM_USER(buf, mmio.data, e->size)) { + return -EINVAL; + if(DRM_COPY_FROM_USER(buf, mmio->data, e->size)) { DRM_ERROR("DRM_COPY_TO_USER failed\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } - memcpy_toio(base, buf, e->size); + for (i = 0; i < e->size / 4; i++) + I915_WRITE(e->offset + i * 4, buf[i]); break; } return 0; } -static int i915_set_status_page(DRM_IOCTL_ARGS) +static int i915_set_status_page(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_hws_addr_t hws; + drm_i915_hws_addr_t *hws = data; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(hws, (drm_i915_hws_addr_t __user *) data, - sizeof(hws)); - printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws.addr); + DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); - dev_priv->status_gfx_addr = hws.addr & (0x1ffff<<12); + dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); - dev_priv->hws_map.offset = dev->agp->agp_info.aper_base + hws.addr; + dev_priv->hws_map.offset = dev->agp->base + hws->addr; dev_priv->hws_map.size = 4*1024; dev_priv->hws_map.type = 0; dev_priv->hws_map.flags = 0; @@ -909,12 +1273,11 @@ static int i915_set_status_page(DRM_IOCTL_ARGS) drm_core_ioremap(&dev_priv->hws_map, dev); if (dev_priv->hws_map.handle == NULL) { - dev->dev_private = (void *)dev_priv; i915_dma_cleanup(dev); dev_priv->status_gfx_addr = 0; DRM_ERROR("can not ioremap virtual address for" " G33 hw status page\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } dev_priv->hw_status_page = dev_priv->hws_map.handle; @@ -926,8 +1289,12 @@ static int i915_set_status_page(DRM_IOCTL_ARGS) return 0; } -int i915_driver_load(drm_device_t *dev, unsigned long flags) +int i915_driver_load(struct drm_device *dev, unsigned long flags) { + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long base, size; + int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; + /* i915 has 4 more counters */ dev->counters += 4; dev->types[6] = _DRM_STAT_IRQ; @@ -935,46 +1302,76 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) dev->types[8] = _DRM_STAT_SECONDARY; dev->types[9] = _DRM_STAT_DMA; + dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); + if (dev_priv == NULL) + return -ENOMEM; + + memset(dev_priv, 0, sizeof(drm_i915_private_t)); + + dev->dev_private = (void *)dev_priv; + + /* Add register map (needed for suspend/resume) */ + base = drm_get_resource_start(dev, mmio_bar); + size = drm_get_resource_len(dev, mmio_bar); + + ret = drm_addmap(dev, base, size, _DRM_REGISTERS, _DRM_KERNEL, + &dev_priv->mmio_map); + + return ret; +} + +int i915_driver_unload(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->mmio_map) + drm_rmmap(dev, dev_priv->mmio_map); + + drm_free(dev->dev_private, sizeof(drm_i915_private_t), + DRM_MEM_DRIVER); return 0; } -void i915_driver_lastclose(drm_device_t * dev) +void i915_driver_lastclose(struct drm_device * dev) { - if (dev->dev_private) { - drm_i915_private_t *dev_priv = dev->dev_private; + drm_i915_private_t *dev_priv = dev->dev_private; + + if (drm_getsarea(dev) && dev_priv->sarea_priv) i915_do_cleanup_pageflip(dev); + if (dev_priv->agp_heap) i915_mem_takedown(&(dev_priv->agp_heap)); - } + i915_dma_cleanup(dev); } -void i915_driver_preclose(drm_device_t * dev, DRMFILE filp) -{ - if (dev->dev_private) { - drm_i915_private_t *dev_priv = dev->dev_private; - i915_mem_release(dev, filp, dev_priv->agp_heap); - } -} - -drm_ioctl_desc_t i915_ioctls[] = { - [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, - [DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY }, - [DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH }, - [DRM_IOCTL_NR(DRM_I915_VBLANK_SWAP)] = {i915_vblank_swap, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_MMIO)] = {i915_mmio, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_I915_HWS_ADDR)] = {i915_set_status_page, DRM_AUTH}, +void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + i915_mem_release(dev, file_priv, dev_priv->agp_heap); +} + +struct drm_ioctl_desc i915_ioctls[] = { + DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), + DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), + DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), + DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_MMIO, i915_mmio, DRM_AUTH), + DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH), +#ifdef I915_HAVE_BUFFER + DRM_IOCTL_DEF(DRM_I915_EXECBUFFER, i915_execbuffer, DRM_AUTH), +#endif }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); @@ -990,7 +1387,7 @@ int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); * \returns * A value of 1 is always retured to indictate every i9x5 is AGP. */ -int i915_driver_device_is_agp(drm_device_t * dev) +int i915_driver_device_is_agp(struct drm_device * dev) { return 1; } diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index 1c6ff4d3..a6c3cf30 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -64,7 +64,7 @@ typedef struct _drm_i915_init { } drm_i915_init_t; typedef struct _drm_i915_sarea { - drm_tex_region_t texList[I915_NR_TEX_REGIONS + 1]; + struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1]; int last_upload; /* last time texture was uploaded */ int last_enqueue; /* last time a buffer was enqueued */ int last_dispatch; /* age of the most recently dispatched buffer */ @@ -105,14 +105,14 @@ typedef struct _drm_i915_sarea { unsigned int rotated_tiled; unsigned int rotated2_tiled; - int pipeA_x; - int pipeA_y; - int pipeA_w; - int pipeA_h; - int pipeB_x; - int pipeB_y; - int pipeB_w; - int pipeB_h; + int planeA_x; + int planeA_y; + int planeA_w; + int planeA_h; + int planeB_x; + int planeB_y; + int planeB_w; + int planeB_h; /* Triple buffering */ drm_handle_t third_handle; @@ -160,6 +160,7 @@ typedef struct _drm_i915_sarea { #define DRM_I915_VBLANK_SWAP 0x0f #define DRM_I915_MMIO 0x10 #define DRM_I915_HWS_ADDR 0x11 +#define DRM_I915_EXECBUFFER 0x12 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -177,11 +178,17 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) - +#define DRM_IOCTL_I915_EXECBUFFER DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_EXECBUFFER, struct drm_i915_execbuffer) /* Asynchronous page flipping: */ typedef struct drm_i915_flip { + /* + * This is really talking about planes, and we could rename it + * except for the fact that some of the duplicated i915_drm.h files + * out there check for HAVE_I915_FLIP and so might pick up this + * version. + */ int pipes; } drm_i915_flip_t; @@ -194,7 +201,7 @@ typedef struct _drm_i915_batchbuffer { int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t __user *cliprects; /* pointer to userspace cliprects */ + struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */ } drm_i915_batchbuffer_t; /* As above, but pass a pointer to userspace buffer which can be @@ -206,7 +213,7 @@ typedef struct _drm_i915_cmdbuffer { int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t __user *cliprects; /* pointer to userspace cliprects */ + struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */ } drm_i915_cmdbuffer_t; /* Userspace can request & wait on irq's: @@ -283,7 +290,7 @@ typedef struct drm_i915_vblank_pipe { */ typedef struct drm_i915_vblank_swap { drm_drawable_t drawable; - drm_vblank_seq_type_t seqtype; + enum drm_vblank_seq_type seqtype; unsigned int sequence; } drm_i915_vblank_swap_t; @@ -319,4 +326,40 @@ typedef struct drm_i915_hws_addr { uint64_t addr; } drm_i915_hws_addr_t; +/* + * Relocation header is 4 uint32_ts + * 0 - (16-bit relocation type << 16)| 16 bit reloc count + * 1 - buffer handle for another list of relocs + * 2-3 - spare. + */ +#define I915_RELOC_HEADER 4 + +/* + * type 0 relocation has 4-uint32_t stride + * 0 - offset into buffer + * 1 - delta to add in + * 2 - index into buffer list + * 3 - reserved (for optimisations later). + */ +#define I915_RELOC_TYPE_0 0 +#define I915_RELOC0_STRIDE 4 + +struct drm_i915_op_arg { + uint64_t next; + uint32_t reloc_handle; + int handled; + union { + struct drm_bo_op_req req; + struct drm_bo_arg_rep rep; + } d; + +}; + +struct drm_i915_execbuffer { + uint64_t ops_list; + uint32_t num_buffers; + struct _drm_i915_batchbuffer batch; + struct drm_fence_arg fence_arg; +}; + #endif /* _I915_DRM_H_ */ diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index c8961c08..d34621e5 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -39,6 +39,11 @@ #define DRIVER_DESC "Intel Graphics" #define DRIVER_DATE "20070209" +#if defined(__linux__) +#define I915_HAVE_FENCE +#define I915_HAVE_BUFFER +#endif + /* Interface history: * * 1.1: Original. @@ -50,14 +55,19 @@ * - Support vertical blank on secondary display pipe * 1.8: New ioctl for ARB_Occlusion_Query * 1.9: Usable page flipping and triple buffering + * 1.10: Plane/pipe disentangling + * 1.11: TTM superioctl */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 9 +#if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER) +#define DRIVER_MINOR 11 +#else +#define DRIVER_MINOR 6 +#endif #define DRIVER_PATCHLEVEL 0 -#if defined(__linux__) -#define I915_HAVE_FENCE -#define I915_HAVE_BUFFER +#ifdef I915_HAVE_BUFFER +#define I915_MAX_VALIDATE_BUFFERS 4096 #endif typedef struct _drm_i915_ring_buffer { @@ -77,13 +87,13 @@ struct mem_block { struct mem_block *prev; int start; int size; - DRMFILE filp; /* 0: free, -1: heap, other: real files */ + struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ }; typedef struct _drm_i915_vbl_swap { struct list_head head; drm_drawable_t drw_id; - unsigned int pipe; + unsigned int plane; unsigned int sequence; int flip; } drm_i915_vbl_swap_t; @@ -114,7 +124,7 @@ typedef struct drm_i915_private { struct mem_block *agp_heap; unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; int vblank_pipe; - spinlock_t user_irq_lock; + DRM_SPINTYPE user_irq_lock; int user_irq_refcount; int fence_irq_on; uint32_t irq_enable_reg; @@ -128,10 +138,92 @@ typedef struct drm_i915_private { #endif #ifdef I915_HAVE_BUFFER void *agp_iomap; + unsigned int max_validate_buffers; + struct mutex cmdbuf_mutex; #endif - spinlock_t swaps_lock; + + DRM_SPINTYPE swaps_lock; drm_i915_vbl_swap_t vbl_swaps; unsigned int swaps_pending; + + /* Register state */ + u8 saveLBB; + u32 saveDSPACNTR; + u32 saveDSPBCNTR; + u32 savePIPEACONF; + u32 savePIPEBCONF; + u32 savePIPEASRC; + u32 savePIPEBSRC; + u32 saveFPA0; + u32 saveFPA1; + u32 saveDPLL_A; + u32 saveDPLL_A_MD; + u32 saveHTOTAL_A; + u32 saveHBLANK_A; + u32 saveHSYNC_A; + u32 saveVTOTAL_A; + u32 saveVBLANK_A; + u32 saveVSYNC_A; + u32 saveBCLRPAT_A; + u32 saveDSPASTRIDE; + u32 saveDSPASIZE; + u32 saveDSPAPOS; + u32 saveDSPABASE; + u32 saveDSPASURF; + u32 saveDSPATILEOFF; + u32 savePFIT_PGM_RATIOS; + u32 saveBLC_PWM_CTL; + u32 saveBLC_PWM_CTL2; + u32 saveFPB0; + u32 saveFPB1; + u32 saveDPLL_B; + u32 saveDPLL_B_MD; + u32 saveHTOTAL_B; + u32 saveHBLANK_B; + u32 saveHSYNC_B; + u32 saveVTOTAL_B; + u32 saveVBLANK_B; + u32 saveVSYNC_B; + u32 saveBCLRPAT_B; + u32 saveDSPBSTRIDE; + u32 saveDSPBSIZE; + u32 saveDSPBPOS; + u32 saveDSPBBASE; + u32 saveDSPBSURF; + u32 saveDSPBTILEOFF; + u32 saveVCLK_DIVISOR_VGA0; + u32 saveVCLK_DIVISOR_VGA1; + u32 saveVCLK_POST_DIV; + u32 saveVGACNTRL; + u32 saveADPA; + u32 saveLVDS; + u32 saveLVDSPP_ON; + u32 saveLVDSPP_OFF; + u32 saveDVOA; + u32 saveDVOB; + u32 saveDVOC; + u32 savePP_ON; + u32 savePP_OFF; + u32 savePP_CONTROL; + u32 savePP_CYCLE; + u32 savePFIT_CONTROL; + u32 save_palette_a[256]; + u32 save_palette_b[256]; + u32 saveFBC_CFB_BASE; + u32 saveFBC_LL_BASE; + u32 saveFBC_CONTROL; + u32 saveFBC_CONTROL2; + u32 saveSWF0[16]; + u32 saveSWF1[16]; + u32 saveSWF2[3]; + u8 saveMSR; + u8 saveSR[8]; + u8 saveGR[24]; + u8 saveAR_INDEX; + u8 saveAR[20]; + u8 saveDACMASK; + u8 saveDACDATA[256*3]; /* 256 3-byte colors */ + u8 saveCR[36]; } drm_i915_private_t; enum intel_chip_family { @@ -141,72 +233,85 @@ enum intel_chip_family { CHIP_I965 = 0x08, }; -extern drm_ioctl_desc_t i915_ioctls[]; +extern struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; /* i915_dma.c */ -extern void i915_kernel_lost_context(drm_device_t * dev); +extern void i915_kernel_lost_context(struct drm_device * dev); extern int i915_driver_load(struct drm_device *, unsigned long flags); -extern void i915_driver_lastclose(drm_device_t * dev); -extern void i915_driver_preclose(drm_device_t * dev, DRMFILE filp); -extern int i915_driver_device_is_agp(drm_device_t * dev); +extern int i915_driver_unload(struct drm_device *); +extern void i915_driver_lastclose(struct drm_device * dev); +extern void i915_driver_preclose(struct drm_device *dev, + struct drm_file *file_priv); +extern int i915_driver_device_is_agp(struct drm_device * dev); extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -extern void i915_emit_breadcrumb(drm_device_t *dev); -extern void i915_dispatch_flip(drm_device_t * dev, int pipes, int sync); -extern int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush); +extern void i915_emit_breadcrumb(struct drm_device *dev); +extern void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync); +extern int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush); extern int i915_driver_firstopen(struct drm_device *dev); /* i915_irq.c */ -extern int i915_irq_emit(DRM_IOCTL_ARGS); -extern int i915_irq_wait(DRM_IOCTL_ARGS); +extern int i915_irq_emit(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int i915_irq_wait(struct drm_device *dev, void *data, + struct drm_file *file_priv); extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); -extern void i915_driver_irq_preinstall(drm_device_t * dev); -extern int i915_driver_irq_postinstall(drm_device_t * dev); -extern void i915_driver_irq_uninstall(drm_device_t * dev); -extern int i915_vblank_pipe_set(DRM_IOCTL_ARGS); -extern int i915_vblank_pipe_get(DRM_IOCTL_ARGS); -extern int i915_emit_irq(drm_device_t * dev); +extern void i915_driver_irq_preinstall(struct drm_device * dev); +extern int i915_driver_irq_postinstall(struct drm_device * dev); +extern void i915_driver_irq_uninstall(struct drm_device * dev); +extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int i915_emit_irq(struct drm_device * dev); +extern int i915_enable_vblank(struct drm_device *dev, int crtc); +extern void i915_disable_vblank(struct drm_device *dev, int crtc); +extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); +extern int i915_vblank_swap(struct drm_device *dev, void *data, + struct drm_file *file_priv); extern void i915_user_irq_on(drm_i915_private_t *dev_priv); extern void i915_user_irq_off(drm_i915_private_t *dev_priv); -extern int i915_vblank_swap(DRM_IOCTL_ARGS); -extern int i915_enable_vblank(drm_device_t *dev, int crtc); -extern void i915_disable_vblank(drm_device_t *dev, int crtc); -extern u32 i915_get_vblank_counter(drm_device_t *dev, int crtc); /* i915_mem.c */ -extern int i915_mem_alloc(DRM_IOCTL_ARGS); -extern int i915_mem_free(DRM_IOCTL_ARGS); -extern int i915_mem_init_heap(DRM_IOCTL_ARGS); -extern int i915_mem_destroy_heap(DRM_IOCTL_ARGS); +extern int i915_mem_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int i915_mem_free(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int i915_mem_init_heap(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int i915_mem_destroy_heap(struct drm_device *dev, void *data, + struct drm_file *file_priv); extern void i915_mem_takedown(struct mem_block **heap); -extern void i915_mem_release(drm_device_t * dev, - DRMFILE filp, struct mem_block *heap); +extern void i915_mem_release(struct drm_device * dev, + struct drm_file *file_priv, + struct mem_block *heap); #ifdef I915_HAVE_FENCE /* i915_fence.c */ -extern void i915_fence_handler(drm_device_t *dev); -extern int i915_fence_emit_sequence(drm_device_t *dev, uint32_t class, +extern void i915_fence_handler(struct drm_device *dev); +extern int i915_fence_emit_sequence(struct drm_device *dev, uint32_t class, uint32_t flags, uint32_t *sequence, uint32_t *native_type); -extern void i915_poke_flush(drm_device_t *dev, uint32_t class); -extern int i915_fence_has_irq(drm_device_t *dev, uint32_t class, uint32_t flags); +extern void i915_poke_flush(struct drm_device *dev, uint32_t class); +extern int i915_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t flags); #endif #ifdef I915_HAVE_BUFFER /* i915_buffer.c */ -extern drm_ttm_backend_t *i915_create_ttm_backend_entry(drm_device_t *dev); -extern int i915_fence_types(drm_buffer_object_t *bo, uint32_t *class, uint32_t *type); -extern int i915_invalidate_caches(drm_device_t *dev, uint32_t buffer_flags); -extern int i915_init_mem_type(drm_device_t *dev, uint32_t type, - drm_mem_type_manager_t *man); -extern uint32_t i915_evict_mask(drm_buffer_object_t *bo); -extern int i915_move(drm_buffer_object_t *bo, int evict, - int no_wait, drm_bo_mem_reg_t *new_mem); - +extern struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device *dev); +extern int i915_fence_types(struct drm_buffer_object *bo, uint32_t *fclass, + uint32_t *type); +extern int i915_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags); +extern int i915_init_mem_type(struct drm_device *dev, uint32_t type, + struct drm_mem_type_manager *man); +extern uint32_t i915_evict_mask(struct drm_buffer_object *bo); +extern int i915_move(struct drm_buffer_object *bo, int evict, + int no_wait, struct drm_bo_mem_reg *new_mem); +void i915_flush_ttm(struct drm_ttm *ttm); #endif #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg)) @@ -246,7 +351,51 @@ extern int i915_move(drm_buffer_object_t *bo, int evict, I915_WRITE(LP_RING + RING_TAIL, outring); \ } while(0) -extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); +extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); + +/* Extended config space */ +#define LBB 0xf4 + +/* VGA stuff */ + +#define VGA_ST01_MDA 0x3ba +#define VGA_ST01_CGA 0x3da + +#define VGA_MSR_WRITE 0x3c2 +#define VGA_MSR_READ 0x3cc +#define VGA_MSR_MEM_EN (1<<1) +#define VGA_MSR_CGA_MODE (1<<0) + +#define VGA_SR_INDEX 0x3c4 +#define VGA_SR_DATA 0x3c5 + +#define VGA_AR_INDEX 0x3c0 +#define VGA_AR_VID_EN (1<<5) +#define VGA_AR_DATA_WRITE 0x3c0 +#define VGA_AR_DATA_READ 0x3c1 + +#define VGA_GR_INDEX 0x3ce +#define VGA_GR_DATA 0x3cf +/* GR05 */ +#define VGA_GR_MEM_READ_MODE_SHIFT 3 +#define VGA_GR_MEM_READ_MODE_PLANE 1 +/* GR06 */ +#define VGA_GR_MEM_MODE_MASK 0xc +#define VGA_GR_MEM_MODE_SHIFT 2 +#define VGA_GR_MEM_A0000_AFFFF 0 +#define VGA_GR_MEM_A0000_BFFFF 1 +#define VGA_GR_MEM_B0000_B7FFF 2 +#define VGA_GR_MEM_B0000_BFFFF 3 + +#define VGA_DACMASK 0x3c6 +#define VGA_DACRX 0x3c7 +#define VGA_DACWX 0x3c8 +#define VGA_DACDATA 0x3c9 + +#define VGA_CR_INDEX_MDA 0x3b4 +#define VGA_CR_DATA_MDA 0x3b5 +#define VGA_CR_INDEX_CGA 0x3d4 +#define VGA_CR_DATA_CGA 0x3d5 #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) @@ -258,12 +407,56 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define MI_NO_WRITE_FLUSH (1 << 2) #define MI_READ_FLUSH (1 << 0) #define MI_EXE_FLUSH (1 << 1) +#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ +#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ + +/* Packet to load a register value from the ring/batch command stream: + */ +#define CMD_MI_LOAD_REGISTER_IMM ((0x22 << 23)|0x1) #define BB1_START_ADDR_MASK (~0x7) #define BB1_PROTECTED (1<<0) #define BB1_UNPROTECTED (0<<0) #define BB2_END_ADDR_MASK (~0x7) +/* Framebuffer compression */ +#define FBC_CFB_BASE 0x03200 /* 4k page aligned */ +#define FBC_LL_BASE 0x03204 /* 4k page aligned */ +#define FBC_CONTROL 0x03208 +#define FBC_CTL_EN (1<<31) +#define FBC_CTL_PERIODIC (1<<30) +#define FBC_CTL_INTERVAL_SHIFT (16) +#define FBC_CTL_UNCOMPRESSIBLE (1<<14) +#define FBC_CTL_STRIDE_SHIFT (5) +#define FBC_CTL_FENCENO (1<<0) +#define FBC_COMMAND 0x0320c +#define FBC_CMD_COMPRESS (1<<0) +#define FBC_STATUS 0x03210 +#define FBC_STAT_COMPRESSING (1<<31) +#define FBC_STAT_COMPRESSED (1<<30) +#define FBC_STAT_MODIFIED (1<<29) +#define FBC_STAT_CURRENT_LINE (1<<0) +#define FBC_CONTROL2 0x03214 +#define FBC_CTL_FENCE_DBL (0<<4) +#define FBC_CTL_IDLE_IMM (0<<2) +#define FBC_CTL_IDLE_FULL (1<<2) +#define FBC_CTL_IDLE_LINE (2<<2) +#define FBC_CTL_IDLE_DEBUG (3<<2) +#define FBC_CTL_CPU_FENCE (1<<1) +#define FBC_CTL_PLANEA (0<<0) +#define FBC_CTL_PLANEB (1<<0) +#define FBC_FENCE_OFF 0x0321b + +#define FBC_LL_SIZE (1536) +#define FBC_LL_PAD (32) + +/* Interrupt bits: + */ +#define USER_INT_FLAG (1<<1) +#define VSYNC_PIPEB_FLAG (1<<5) +#define VSYNC_PIPEA_FLAG (1<<7) +#define HWB_OOM_FLAG (1<<13) /* binner out of memory */ + #define I915REG_HWSTAM 0x02098 #define I915REG_INT_IDENTITY_R 0x020a4 #define I915REG_INT_MASK_R 0x020a8 @@ -331,6 +524,10 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define NOPID 0x2094 #define LP_RING 0x2030 #define HP_RING 0x2040 +/* The binner has its own ring buffer: + */ +#define HWB_RING 0x2400 + #define RING_TAIL 0x00 #define TAIL_ADDR 0x001FFFF8 #define RING_HEAD 0x04 @@ -349,11 +546,105 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define RING_VALID 0x00000001 #define RING_INVALID 0x00000000 +/* Instruction parser error reg: + */ +#define IPEIR 0x2088 + +/* Scratch pad debug 0 reg: + */ +#define SCPD0 0x209c + +/* Error status reg: + */ +#define ESR 0x20b8 + +/* Secondary DMA fetch address debug reg: + */ +#define DMA_FADD_S 0x20d4 + +/* Cache mode 0 reg. + * - Manipulating render cache behaviour is central + * to the concept of zone rendering, tuning this reg can help avoid + * unnecessary render cache reads and even writes (for z/stencil) + * at beginning and end of scene. + * + * - To change a bit, write to this reg with a mask bit set and the + * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set. + */ +#define Cache_Mode_0 0x2120 +#define CM0_MASK_SHIFT 16 +#define CM0_IZ_OPT_DISABLE (1<<6) +#define CM0_ZR_OPT_DISABLE (1<<5) +#define CM0_DEPTH_EVICT_DISABLE (1<<4) +#define CM0_COLOR_EVICT_DISABLE (1<<3) +#define CM0_DEPTH_WRITE_DISABLE (1<<1) +#define CM0_RC_OP_FLUSH_DISABLE (1<<0) + + +/* Graphics flush control. A CPU write flushes the GWB of all writes. + * The data is discarded. + */ +#define GFX_FLSH_CNTL 0x2170 + +/* Binner control. Defines the location of the bin pointer list: + */ +#define BINCTL 0x2420 +#define BC_MASK (1 << 9) + +/* Binned scene info. + */ +#define BINSCENE 0x2428 +#define BS_OP_LOAD (1 << 8) +#define BS_MASK (1 << 22) + +/* Bin command parser debug reg: + */ +#define BCPD 0x2480 + +/* Bin memory control debug reg: + */ +#define BMCD 0x2484 + +/* Bin data cache debug reg: + */ +#define BDCD 0x2488 + +/* Binner pointer cache debug reg: + */ +#define BPCD 0x248c + +/* Binner scratch pad debug reg: + */ +#define BINSKPD 0x24f0 + +/* HWB scratch pad debug reg: + */ +#define HWBSKPD 0x24f4 + +/* Binner memory pool reg: + */ +#define BMP_BUFFER 0x2430 +#define BMP_PAGE_SIZE_4K (0 << 10) +#define BMP_BUFFER_SIZE_SHIFT 1 +#define BMP_ENABLE (1 << 0) + +/* Get/put memory from the binner memory pool: + */ +#define BMP_GET 0x2438 +#define BMP_PUT 0x2440 +#define BMP_OFFSET_SHIFT 5 + +/* 3D state packets: + */ +#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24)) + #define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) #define SC_UPDATE_SCISSOR (0x1<<1) #define SC_ENABLE_MASK (0x1<<0) #define SC_ENABLE (0x1<<0) +#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16)) + #define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) #define SCI_YMIN_MASK (0xffff<<16) #define SCI_XMIN_MASK (0xffff<<0) @@ -380,6 +671,8 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define MI_BATCH_BUFFER_END (0xA<<23) #define MI_BATCH_NON_SECURE (1) +#define MI_BATCH_NON_SECURE_I965 (1<<8) + #define MI_WAIT_FOR_EVENT ((0x3<<23)) #define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) #define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) @@ -392,21 +685,525 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define DISPLAY_PLANE_A (0<<20) #define DISPLAY_PLANE_B (1<<20) +/* Display regs */ +#define DSPACNTR 0x70180 +#define DSPBCNTR 0x71180 +#define DISPPLANE_SEL_PIPE_MASK (1<<24) + +/* Define the region of interest for the binner: + */ +#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4) + #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) +#define BREADCRUMB_BITS 31 +#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1) + #define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5]) #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) -#define IS_I965G(dev) (dev->pci_device == 0x2972 || \ - dev->pci_device == 0x2982 || \ - dev->pci_device == 0x2992 || \ - dev->pci_device == 0x29A2 || \ - dev->pci_device == 0x2A02 || \ - dev->pci_device == 0x2A12) +#define BLC_PWM_CTL 0x61254 +#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) + +#define BLC_PWM_CTL2 0x61250 +/** + * This is the most significant 15 bits of the number of backlight cycles in a + * complete cycle of the modulated backlight control. + * + * The actual value is this field multiplied by two. + */ +#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BLM_LEGACY_MODE (1 << 16) +/** + * This is the number of cycles out of the backlight modulation cycle for which + * the backlight is on. + * + * This field must be no greater than the number of cycles in the complete + * backlight modulation cycle. + */ +#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) +#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) + +#define I915_GCFGC 0xf0 +#define I915_LOW_FREQUENCY_ENABLE (1 << 7) +#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) +#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) +#define I915_DISPLAY_CLOCK_MASK (7 << 4) + +#define I855_HPLLCC 0xc0 +#define I855_CLOCK_CONTROL_MASK (3 << 0) +#define I855_CLOCK_133_200 (0 << 0) +#define I855_CLOCK_100_200 (1 << 0) +#define I855_CLOCK_100_133 (2 << 0) +#define I855_CLOCK_166_250 (3 << 0) + +/* p317, 319 + */ +#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */ +#define VCLK2_VCO_N 0x600a +#define VCLK2_VCO_DIV_SEL 0x6012 + +#define VCLK_DIVISOR_VGA0 0x6000 +#define VCLK_DIVISOR_VGA1 0x6004 +#define VCLK_POST_DIV 0x6010 +/** Selects a post divisor of 4 instead of 2. */ +# define VGA1_PD_P2_DIV_4 (1 << 15) +/** Overrides the p2 post divisor field */ +# define VGA1_PD_P1_DIV_2 (1 << 13) +# define VGA1_PD_P1_SHIFT 8 +/** P1 value is 2 greater than this field */ +# define VGA1_PD_P1_MASK (0x1f << 8) +/** Selects a post divisor of 4 instead of 2. */ +# define VGA0_PD_P2_DIV_4 (1 << 7) +/** Overrides the p2 post divisor field */ +# define VGA0_PD_P1_DIV_2 (1 << 5) +# define VGA0_PD_P1_SHIFT 0 +/** P1 value is 2 greater than this field */ +# define VGA0_PD_P1_MASK (0x1f << 0) + +/* I830 CRTC registers */ +#define HTOTAL_A 0x60000 +#define HBLANK_A 0x60004 +#define HSYNC_A 0x60008 +#define VTOTAL_A 0x6000c +#define VBLANK_A 0x60010 +#define VSYNC_A 0x60014 +#define PIPEASRC 0x6001c +#define BCLRPAT_A 0x60020 +#define VSYNCSHIFT_A 0x60028 + +#define HTOTAL_B 0x61000 +#define HBLANK_B 0x61004 +#define HSYNC_B 0x61008 +#define VTOTAL_B 0x6100c +#define VBLANK_B 0x61010 +#define VSYNC_B 0x61014 +#define PIPEBSRC 0x6101c +#define BCLRPAT_B 0x61020 +#define VSYNCSHIFT_B 0x61028 + +#define PP_STATUS 0x61200 +# define PP_ON (1 << 31) +/** + * Indicates that all dependencies of the panel are on: + * + * - PLL enabled + * - pipe enabled + * - LVDS/DVOB/DVOC on + */ +# define PP_READY (1 << 30) +# define PP_SEQUENCE_NONE (0 << 28) +# define PP_SEQUENCE_ON (1 << 28) +# define PP_SEQUENCE_OFF (2 << 28) +# define PP_SEQUENCE_MASK 0x30000000 +#define PP_CONTROL 0x61204 +# define POWER_TARGET_ON (1 << 0) + +#define LVDSPP_ON 0x61208 +#define LVDSPP_OFF 0x6120c +#define PP_CYCLE 0x61210 + +#define PFIT_CONTROL 0x61230 +# define PFIT_ENABLE (1 << 31) +# define PFIT_PIPE_MASK (3 << 29) +# define PFIT_PIPE_SHIFT 29 +# define VERT_INTERP_DISABLE (0 << 10) +# define VERT_INTERP_BILINEAR (1 << 10) +# define VERT_INTERP_MASK (3 << 10) +# define VERT_AUTO_SCALE (1 << 9) +# define HORIZ_INTERP_DISABLE (0 << 6) +# define HORIZ_INTERP_BILINEAR (1 << 6) +# define HORIZ_INTERP_MASK (3 << 6) +# define HORIZ_AUTO_SCALE (1 << 5) +# define PANEL_8TO6_DITHER_ENABLE (1 << 3) + +#define PFIT_PGM_RATIOS 0x61234 +# define PFIT_VERT_SCALE_MASK 0xfff00000 +# define PFIT_HORIZ_SCALE_MASK 0x0000fff0 + +#define PFIT_AUTO_RATIOS 0x61238 + + +#define DPLL_A 0x06014 +#define DPLL_B 0x06018 +# define DPLL_VCO_ENABLE (1 << 31) +# define DPLL_DVO_HIGH_SPEED (1 << 30) +# define DPLL_SYNCLOCK_ENABLE (1 << 29) +# define DPLL_VGA_MODE_DIS (1 << 28) +# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ +# define DPLLB_MODE_LVDS (2 << 26) /* i915 */ +# define DPLL_MODE_MASK (3 << 26) +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ +# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ +# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ +# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ +# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ +/** + * The i830 generation, in DAC/serial mode, defines p1 as two plus this + * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 +/** + * The i830 generation, in LVDS mode, defines P1 as the bit number set within + * this field (only one bit may be set). + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 +# define DPLL_FPA01_P1_POST_DIV_SHIFT 16 +# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */ +# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ +# define PLL_REF_INPUT_DREFCLK (0 << 13) +# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ +# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ +# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) +# define PLL_REF_INPUT_MASK (3 << 13) +# define PLL_LOAD_PULSE_PHASE_SHIFT 9 +/* + * Parallel to Serial Load Pulse phase selection. + * Selects the phase for the 10X DPLL clock for the PCIe + * digital display port. The range is 4 to 13; 10 or more + * is just a flip delay. The default is 6 + */ +# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) +# define DISPLAY_RATE_SELECT_FPA1 (1 << 8) + +/** + * SDVO multiplier for 945G/GM. Not used on 965. + * + * \sa DPLL_MD_UDI_MULTIPLIER_MASK + */ +# define SDVO_MULTIPLIER_MASK 0x000000ff +# define SDVO_MULTIPLIER_SHIFT_HIRES 4 +# define SDVO_MULTIPLIER_SHIFT_VGA 0 + +/** @defgroup DPLL_MD + * @{ + */ +/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */ +#define DPLL_A_MD 0x0601c +/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */ +#define DPLL_B_MD 0x06020 +/** + * UDI pixel divider, controlling how many pixels are stuffed into a packet. + * + * Value is pixels minus 1. Must be set to 1 pixel for SDVO. + */ +# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 +# define DPLL_MD_UDI_DIVIDER_SHIFT 24 +/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ +# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 +# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 +/** + * SDVO/UDI pixel multiplier. + * + * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus + * clock rate is 10 times the DPLL clock. At low resolution/refresh rate + * modes, the bus rate would be below the limits, so SDVO allows for stuffing + * dummy bytes in the datastream at an increased clock rate, with both sides of + * the link knowing how many bytes are fill. + * + * So, for a mode with a dotclock of 65Mhz, we would want to double the clock + * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be + * set to 130Mhz, and the SDVO multiplier set to 2x in this register and + * through an SDVO command. + * + * This register field has values of multiplication factor minus 1, with + * a maximum multiplier of 5 for SDVO. + */ +# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 +# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 +/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. + * This best be set to the default value (3) or the CRT won't work. No, + * I don't entirely understand what this does... + */ +# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f +# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 +/** @} */ + +#define DPLL_TEST 0x606c +# define DPLLB_TEST_SDVO_DIV_1 (0 << 22) +# define DPLLB_TEST_SDVO_DIV_2 (1 << 22) +# define DPLLB_TEST_SDVO_DIV_4 (2 << 22) +# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) +# define DPLLB_TEST_N_BYPASS (1 << 19) +# define DPLLB_TEST_M_BYPASS (1 << 18) +# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) +# define DPLLA_TEST_N_BYPASS (1 << 3) +# define DPLLA_TEST_M_BYPASS (1 << 2) +# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) + +#define ADPA 0x61100 +#define ADPA_DAC_ENABLE (1<<31) +#define ADPA_DAC_DISABLE 0 +#define ADPA_PIPE_SELECT_MASK (1<<30) +#define ADPA_PIPE_A_SELECT 0 +#define ADPA_PIPE_B_SELECT (1<<30) +#define ADPA_USE_VGA_HVPOLARITY (1<<15) +#define ADPA_SETS_HVPOLARITY 0 +#define ADPA_VSYNC_CNTL_DISABLE (1<<11) +#define ADPA_VSYNC_CNTL_ENABLE 0 +#define ADPA_HSYNC_CNTL_DISABLE (1<<10) +#define ADPA_HSYNC_CNTL_ENABLE 0 +#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) +#define ADPA_VSYNC_ACTIVE_LOW 0 +#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) +#define ADPA_HSYNC_ACTIVE_LOW 0 + +#define FPA0 0x06040 +#define FPA1 0x06044 +#define FPB0 0x06048 +#define FPB1 0x0604c +# define FP_N_DIV_MASK 0x003f0000 +# define FP_N_DIV_SHIFT 16 +# define FP_M1_DIV_MASK 0x00003f00 +# define FP_M1_DIV_SHIFT 8 +# define FP_M2_DIV_MASK 0x0000003f +# define FP_M2_DIV_SHIFT 0 + + +#define PORT_HOTPLUG_EN 0x61110 +# define SDVOB_HOTPLUG_INT_EN (1 << 26) +# define SDVOC_HOTPLUG_INT_EN (1 << 25) +# define TV_HOTPLUG_INT_EN (1 << 18) +# define CRT_HOTPLUG_INT_EN (1 << 9) +# define CRT_HOTPLUG_FORCE_DETECT (1 << 3) + +#define PORT_HOTPLUG_STAT 0x61114 +# define CRT_HOTPLUG_INT_STATUS (1 << 11) +# define TV_HOTPLUG_INT_STATUS (1 << 10) +# define CRT_HOTPLUG_MONITOR_MASK (3 << 8) +# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) +# define CRT_HOTPLUG_MONITOR_MONO (2 << 8) +# define CRT_HOTPLUG_MONITOR_NONE (0 << 8) +# define SDVOC_HOTPLUG_INT_STATUS (1 << 7) +# define SDVOB_HOTPLUG_INT_STATUS (1 << 6) + +#define SDVOB 0x61140 +#define SDVOC 0x61160 +#define SDVO_ENABLE (1 << 31) +#define SDVO_PIPE_B_SELECT (1 << 30) +#define SDVO_STALL_SELECT (1 << 29) +#define SDVO_INTERRUPT_ENABLE (1 << 26) +/** + * 915G/GM SDVO pixel multiplier. + * + * Programmed value is multiplier - 1, up to 5x. + * + * \sa DPLL_MD_UDI_MULTIPLIER_MASK + */ +#define SDVO_PORT_MULTIPLY_MASK (7 << 23) +#define SDVO_PORT_MULTIPLY_SHIFT 23 +#define SDVO_PHASE_SELECT_MASK (15 << 19) +#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) +#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) +#define SDVOC_GANG_MODE (1 << 16) +#define SDVO_BORDER_ENABLE (1 << 7) +#define SDVOB_PCIE_CONCURRENCY (1 << 3) +#define SDVO_DETECTED (1 << 2) +/* Bits to be preserved when writing */ +#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) +#define SDVOC_PRESERVE_MASK (1 << 17) + +/** @defgroup LVDS + * @{ + */ +/** + * This register controls the LVDS output enable, pipe selection, and data + * format selection. + * + * All of the clock/data pairs are force powered down by power sequencing. + */ +#define LVDS 0x61180 +/** + * Enables the LVDS port. This bit must be set before DPLLs are enabled, as + * the DPLL semantics change when the LVDS is assigned to that pipe. + */ +# define LVDS_PORT_EN (1 << 31) +/** Selects pipe B for LVDS data. Must be set on pre-965. */ +# define LVDS_PIPEB_SELECT (1 << 30) + +/** + * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per + * pixel. + */ +# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) +# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) +# define LVDS_A0A2_CLKA_POWER_UP (3 << 8) +/** + * Controls the A3 data pair, which contains the additional LSBs for 24 bit + * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be + * on. + */ +# define LVDS_A3_POWER_MASK (3 << 6) +# define LVDS_A3_POWER_DOWN (0 << 6) +# define LVDS_A3_POWER_UP (3 << 6) +/** + * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP + * is set. + */ +# define LVDS_CLKB_POWER_MASK (3 << 4) +# define LVDS_CLKB_POWER_DOWN (0 << 4) +# define LVDS_CLKB_POWER_UP (3 << 4) + +/** + * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 + * setting for whether we are in dual-channel mode. The B3 pair will + * additionally only be powered up when LVDS_A3_POWER_UP is set. + */ +# define LVDS_B0B3_POWER_MASK (3 << 2) +# define LVDS_B0B3_POWER_DOWN (0 << 2) +# define LVDS_B0B3_POWER_UP (3 << 2) + +#define PIPEACONF 0x70008 +#define PIPEACONF_ENABLE (1<<31) +#define PIPEACONF_DISABLE 0 +#define PIPEACONF_DOUBLE_WIDE (1<<30) +#define I965_PIPECONF_ACTIVE (1<<30) +#define PIPEACONF_SINGLE_WIDE 0 +#define PIPEACONF_PIPE_UNLOCKED 0 +#define PIPEACONF_PIPE_LOCKED (1<<25) +#define PIPEACONF_PALETTE 0 +#define PIPEACONF_GAMMA (1<<24) +#define PIPECONF_FORCE_BORDER (1<<25) +#define PIPECONF_PROGRESSIVE (0 << 21) +#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) +#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) + +#define PIPEBCONF 0x71008 +#define PIPEBCONF_ENABLE (1<<31) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_DOUBLE_WIDE (1<<30) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_GAMMA (1<<24) +#define PIPEBCONF_PALETTE 0 + +#define PIPEBGCMAXRED 0x71010 +#define PIPEBGCMAXGREEN 0x71014 +#define PIPEBGCMAXBLUE 0x71018 +#define PIPEBSTAT 0x71024 +#define PIPEBFRAMEHIGH 0x71040 +#define PIPEBFRAMEPIXEL 0x71044 + +#define DSPACNTR 0x70180 +#define DSPBCNTR 0x71180 +#define DISPLAY_PLANE_ENABLE (1<<31) +#define DISPLAY_PLANE_DISABLE 0 +#define DISPPLANE_GAMMA_ENABLE (1<<30) +#define DISPPLANE_GAMMA_DISABLE 0 +#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) +#define DISPPLANE_8BPP (0x2<<26) +#define DISPPLANE_15_16BPP (0x4<<26) +#define DISPPLANE_16BPP (0x5<<26) +#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) +#define DISPPLANE_32BPP (0x7<<26) +#define DISPPLANE_STEREO_ENABLE (1<<25) +#define DISPPLANE_STEREO_DISABLE 0 +#define DISPPLANE_SEL_PIPE_MASK (1<<24) +#define DISPPLANE_SEL_PIPE_A 0 +#define DISPPLANE_SEL_PIPE_B (1<<24) +#define DISPPLANE_SRC_KEY_ENABLE (1<<22) +#define DISPPLANE_SRC_KEY_DISABLE 0 +#define DISPPLANE_LINE_DOUBLE (1<<20) +#define DISPPLANE_NO_LINE_DOUBLE 0 +#define DISPPLANE_STEREO_POLARITY_FIRST 0 +#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) +/* plane B only */ +#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) +#define DISPPLANE_ALPHA_TRANS_DISABLE 0 +#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 +#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) + +#define DSPABASE 0x70184 +#define DSPASTRIDE 0x70188 + +#define DSPBBASE 0x71184 +#define DSPBADDR DSPBBASE +#define DSPBSTRIDE 0x71188 + +#define DSPAKEYVAL 0x70194 +#define DSPAKEYMASK 0x70198 + +#define DSPAPOS 0x7018C /* reserved */ +#define DSPASIZE 0x70190 +#define DSPBPOS 0x7118C +#define DSPBSIZE 0x71190 + +#define DSPASURF 0x7019C +#define DSPATILEOFF 0x701A4 + +#define DSPBSURF 0x7119C +#define DSPBTILEOFF 0x711A4 + +#define VGACNTRL 0x71400 +# define VGA_DISP_DISABLE (1 << 31) +# define VGA_2X_MODE (1 << 30) +# define VGA_PIPE_B_SELECT (1 << 29) + +/* + * Some BIOS scratch area registers. The 845 (and 830?) store the amount + * of video memory available to the BIOS in SWF1. + */ + +#define SWF0 0x71410 + +/* + * 855 scratch registers. + */ +#define SWF10 0x70410 + +#define SWF30 0x72414 + +/* + * Overlay registers. These are overlay registers accessed via MMIO. + * Those loaded via the overlay register page are defined in i830_video.c. + */ +#define OVADD 0x30000 + +#define DOVSTA 0x30008 +#define OC_BUF (0x3<<20) + +#define OGAMC5 0x30010 +#define OGAMC4 0x30014 +#define OGAMC3 0x30018 +#define OGAMC2 0x3001c +#define OGAMC1 0x30020 +#define OGAMC0 0x30024 +/* + * Palette registers + */ +#define PALETTE_A 0x0a000 +#define PALETTE_B 0x0a800 + +#define IS_I830(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82830_CGC) +#define IS_845G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82845G_IG) +#define IS_I85X(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG) +#define IS_I855(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG) +#define IS_I865G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82865_IG) + +#define IS_I915G(dev) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG)/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G)*/ +#define IS_I915GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG) +#define IS_I945G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945G_IG) +#define IS_I945GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GM_IG) + +#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \ + (dev)->pci_device == 0x2982 || \ + (dev)->pci_device == 0x2992 || \ + (dev)->pci_device == 0x29A2 || \ + (dev)->pci_device == 0x2A02 || \ + (dev)->pci_device == 0x2A12) + +#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) + +#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ + (dev)->pci_device == 0x29B2 || \ + (dev)->pci_device == 0x29D2) + +#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ + IS_I945GM(dev) || IS_I965G(dev)) -#define IS_G33(dev) (dev->pci_device == 0x29C2 || \ - dev->pci_device == 0x29B2 || \ - dev->pci_device == 0x29D2) +#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ + IS_I945GM(dev) || IS_I965GM(dev)) +#define PRIMARY_RINGBUFFER_SIZE (128*1024) #endif diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index c0c1bf9e..46d09663 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -38,47 +38,70 @@ #define MAX_NOPID ((u32)~0) /** + * i915_get_pipe - return the the pipe associated with a given plane + * @dev: DRM device + * @plane: plane to look for + * + * We need to get the pipe associated with a given plane to correctly perform + * vblank driven swapping, and they may not always be equal. So look up the + * pipe associated with @plane here. + */ +static int +i915_get_pipe(struct drm_device *dev, int plane) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 dspcntr; + + dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR); + + return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0; +} + +/** * Emit a synchronous flip. * * This function must be called with the drawable spinlock held. */ static void -i915_dispatch_vsync_flip(drm_device_t *dev, drm_drawable_info_t *drw, int pipe) +i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, + int plane) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; u16 x1, y1, x2, y2; - int pf_pipes = 1 << pipe; + int pf_planes = 1 << plane; + + DRM_SPINLOCK_ASSERT(&dev->drw_lock); - /* If the window is visible on the other pipe, we have to flip on that - * pipe as well. + /* If the window is visible on the other plane, we have to flip on that + * plane as well. */ - if (pipe == 1) { - x1 = sarea_priv->pipeA_x; - y1 = sarea_priv->pipeA_y; - x2 = x1 + sarea_priv->pipeA_w; - y2 = y1 + sarea_priv->pipeA_h; + if (plane == 1) { + x1 = sarea_priv->planeA_x; + y1 = sarea_priv->planeA_y; + x2 = x1 + sarea_priv->planeA_w; + y2 = y1 + sarea_priv->planeA_h; } else { - x1 = sarea_priv->pipeB_x; - y1 = sarea_priv->pipeB_y; - x2 = x1 + sarea_priv->pipeB_w; - y2 = y1 + sarea_priv->pipeB_h; + x1 = sarea_priv->planeB_x; + y1 = sarea_priv->planeB_y; + x2 = x1 + sarea_priv->planeB_w; + y2 = y1 + sarea_priv->planeB_h; } if (x2 > 0 && y2 > 0) { int i, num_rects = drw->num_rects; - drm_clip_rect_t *rect = drw->rects; + struct drm_clip_rect *rect = drw->rects; for (i = 0; i < num_rects; i++) if (!(rect[i].x1 >= x2 || rect[i].y1 >= y2 || rect[i].x2 <= x1 || rect[i].y2 <= y1)) { - pf_pipes = 0x3; + pf_planes = 0x3; break; } } - i915_dispatch_flip(dev, pf_pipes, 1); + i915_dispatch_flip(dev, pf_planes, 1); } /** @@ -86,14 +109,13 @@ i915_dispatch_vsync_flip(drm_device_t *dev, drm_drawable_info_t *drw, int pipe) * * This function will be called with the HW lock held. */ -static void i915_vblank_tasklet(drm_device_t *dev) +static void i915_vblank_tasklet(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; struct list_head *list, *tmp, hits, *hit; int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages; unsigned counter[2]; - drm_drawable_info_t *drw; + struct drm_drawable_info *drw; drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; u32 cpp = dev_priv->cpp, offsets[3]; u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | @@ -113,37 +135,42 @@ static void i915_vblank_tasklet(drm_device_t *dev) nhits = nrects = 0; - spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); + /* No irqsave/restore necessary. This tasklet may be run in an + * interrupt context or normal context, but we don't have to worry + * about getting interrupted by something acquiring the lock, because + * we are the interrupt context thing that acquires the lock. + */ + DRM_SPINLOCK(&dev_priv->swaps_lock); /* Find buffer swaps scheduled for this vertical blank */ list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { drm_i915_vbl_swap_t *vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); - int crtc = vbl_swap->pipe; + int crtc = i915_get_pipe(dev, vbl_swap->plane); - if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23)) + if ((counter[crtc] - vbl_swap->sequence) > (1<<23)) continue; list_del(list); dev_priv->swaps_pending--; drm_vblank_put(dev, crtc); - spin_unlock(&dev_priv->swaps_lock); - spin_lock(&dev->drw_lock); + DRM_SPINUNLOCK(&dev_priv->swaps_lock); + DRM_SPINLOCK(&dev->drw_lock); drw = drm_get_drawable_info(dev, vbl_swap->drw_id); if (!drw) { - spin_unlock(&dev->drw_lock); + DRM_SPINUNLOCK(&dev->drw_lock); drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); - spin_lock(&dev_priv->swaps_lock); + DRM_SPINLOCK(&dev_priv->swaps_lock); continue; } list_for_each(hit, &hits) { drm_i915_vbl_swap_t *swap_cmp = list_entry(hit, drm_i915_vbl_swap_t, head); - drm_drawable_info_t *drw_cmp = + struct drm_drawable_info *drw_cmp = drm_get_drawable_info(dev, swap_cmp->drw_id); if (drw_cmp && @@ -153,7 +180,7 @@ static void i915_vblank_tasklet(drm_device_t *dev) } } - spin_unlock(&dev->drw_lock); + DRM_SPINUNLOCK(&dev->drw_lock); /* List of hits was empty, or we reached the end of it */ if (hit == &hits) @@ -161,30 +188,29 @@ static void i915_vblank_tasklet(drm_device_t *dev) nhits++; - spin_lock(&dev_priv->swaps_lock); + DRM_SPINLOCK(&dev_priv->swaps_lock); } + DRM_SPINUNLOCK(&dev_priv->swaps_lock); + if (nhits == 0) { - spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); return; } - spin_unlock(&dev_priv->swaps_lock); - i915_kernel_lost_context(dev); upper[0] = upper[1] = 0; - slice[0] = max(sarea_priv->pipeA_h / nhits, 1); - slice[1] = max(sarea_priv->pipeB_h / nhits, 1); - lower[0] = sarea_priv->pipeA_y + slice[0]; - lower[1] = sarea_priv->pipeB_y + slice[0]; + slice[0] = max(sarea_priv->planeA_h / nhits, 1); + slice[1] = max(sarea_priv->planeB_h / nhits, 1); + lower[0] = sarea_priv->planeA_y + slice[0]; + lower[1] = sarea_priv->planeB_y + slice[0]; offsets[0] = sarea_priv->front_offset; offsets[1] = sarea_priv->back_offset; offsets[2] = sarea_priv->third_offset; num_pages = sarea_priv->third_handle ? 3 : 2; - spin_lock(&dev->drw_lock); + DRM_SPINLOCK(&dev->drw_lock); /* Emit blits for buffer swaps, partitioning both outputs into as many * slices as there are buffer swaps scheduled in order to avoid tearing @@ -202,8 +228,8 @@ static void i915_vblank_tasklet(drm_device_t *dev) list_for_each(hit, &hits) { drm_i915_vbl_swap_t *swap_hit = list_entry(hit, drm_i915_vbl_swap_t, head); - drm_clip_rect_t *rect; - int num_rects, pipe, front, back; + struct drm_clip_rect *rect; + int num_rects, plane, front, back; unsigned short top, bottom; drw = drm_get_drawable_info(dev, swap_hit->drw_id); @@ -211,10 +237,10 @@ static void i915_vblank_tasklet(drm_device_t *dev) if (!drw) continue; - pipe = swap_hit->pipe; + plane = swap_hit->plane; if (swap_hit->flip) { - i915_dispatch_vsync_flip(dev, drw, pipe); + i915_dispatch_vsync_flip(dev, drw, plane); continue; } @@ -236,11 +262,11 @@ static void i915_vblank_tasklet(drm_device_t *dev) } rect = drw->rects; - top = upper[pipe]; - bottom = lower[pipe]; + top = upper[plane]; + bottom = lower[plane]; front = (dev_priv->sarea_priv->pf_current_page >> - (2 * pipe)) & 0x3; + (2 * plane)) & 0x3; back = (front + 1) % num_pages; for (num_rects = drw->num_rects; num_rects--; rect++) { @@ -266,7 +292,7 @@ static void i915_vblank_tasklet(drm_device_t *dev) } } - spin_unlock_irqrestore(&dev->drw_lock, irqflags); + DRM_SPINUNLOCK(&dev->drw_lock); list_for_each_safe(hit, tmp, &hits) { drm_i915_vbl_swap_t *swap_hit = @@ -278,16 +304,13 @@ static void i915_vblank_tasklet(drm_device_t *dev) } } -u32 i915_get_vblank_counter(drm_device_t *dev, int crtc) +u32 i915_get_vblank_counter(struct drm_device *dev, int crtc) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long high_frame = crtc ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; unsigned long low_frame = crtc ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; u32 high1, high2, low, count; - if (!IS_I965G(dev)) - return 0; - /* * High & low register fields aren't synchronized, so make sure * we get a low value that's stable across two reads of the high @@ -309,7 +332,7 @@ u32 i915_get_vblank_counter(drm_device_t *dev, int crtc) irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) { - drm_device_t *dev = (drm_device_t *) arg; + struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u16 temp; u32 pipea_stats, pipeb_stats; @@ -340,13 +363,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) #endif } - if (!IS_I965G(dev)) { - if (temp & VSYNC_PIPEA_FLAG) - atomic_inc(&dev->_vblank_count[0]); - if (temp & VSYNC_PIPEB_FLAG) - atomic_inc(&dev->_vblank_count[1]); - } - /* * Use drm_update_vblank_counter here to deal with potential lost * interrupts @@ -370,7 +386,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_HANDLED; } -int i915_emit_irq(drm_device_t * dev) +int i915_emit_irq(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -394,27 +410,27 @@ int i915_emit_irq(drm_device_t * dev) void i915_user_irq_on(drm_i915_private_t *dev_priv) { - spin_lock(&dev_priv->user_irq_lock); + DRM_SPINLOCK(&dev_priv->user_irq_lock); if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){ dev_priv->irq_enable_reg |= USER_INT_FLAG; I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); } - spin_unlock(&dev_priv->user_irq_lock); + DRM_SPINUNLOCK(&dev_priv->user_irq_lock); } void i915_user_irq_off(drm_i915_private_t *dev_priv) { - spin_lock(&dev_priv->user_irq_lock); + DRM_SPINLOCK(&dev_priv->user_irq_lock); if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { // dev_priv->irq_enable_reg &= ~USER_INT_FLAG; // I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); } - spin_unlock(&dev_priv->user_irq_lock); + DRM_SPINUNLOCK(&dev_priv->user_irq_lock); } -static int i915_wait_irq(drm_device_t * dev, int irq_nr) +static int i915_wait_irq(struct drm_device * dev, int irq_nr) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int ret = 0; @@ -432,7 +448,7 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr) READ_BREADCRUMB(dev_priv) >= irq_nr); i915_user_irq_off(dev_priv); - if (ret == DRM_ERR(EBUSY)) { + if (ret == -EBUSY) { DRM_ERROR("%s: EBUSY -- rec: %d emitted: %d\n", __FUNCTION__, READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); @@ -444,28 +460,24 @@ static int i915_wait_irq(drm_device_t * dev, int irq_nr) /* Needs the lock as it touches the ring. */ -int i915_irq_emit(DRM_IOCTL_ARGS) +int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_irq_emit_t emit; + drm_i915_irq_emit_t *emit = data; int result; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(emit, (drm_i915_irq_emit_t __user *) data, - sizeof(emit)); - result = i915_emit_irq(dev); - if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof(int))) { + if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { DRM_ERROR("copy_to_user\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } return 0; @@ -473,30 +485,24 @@ int i915_irq_emit(DRM_IOCTL_ARGS) /* Doesn't need the hardware lock. */ -int i915_irq_wait(DRM_IOCTL_ARGS) +int i915_irq_wait(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_irq_wait_t irqwait; + drm_i915_irq_wait_t *irqwait = data; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_i915_irq_wait_t __user *) data, - sizeof(irqwait)); - - return i915_wait_irq(dev, irqwait.irq_seq); + return i915_wait_irq(dev, irqwait->irq_seq); } -int i915_enable_vblank(drm_device_t *dev, int crtc) +int i915_enable_vblank(struct drm_device *dev, int crtc) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - if (!IS_I965G(dev)) - return 0; - switch (crtc) { case 0: dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG; @@ -515,13 +521,10 @@ int i915_enable_vblank(drm_device_t *dev, int crtc) return 0; } -void i915_disable_vblank(drm_device_t *dev, int crtc) +void i915_disable_vblank(struct drm_device *dev, int crtc) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - if (!IS_I965G(dev)) - return; - switch (crtc) { case 0: dev_priv->irq_enable_reg &= ~VSYNC_PIPEA_FLAG; @@ -538,7 +541,7 @@ void i915_disable_vblank(drm_device_t *dev, int crtc) I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); } -static void i915_enable_interrupt (drm_device_t *dev) +static void i915_enable_interrupt (struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -550,176 +553,176 @@ static void i915_enable_interrupt (drm_device_t *dev) /* Set the vblank monitor pipe */ -int i915_vblank_pipe_set(DRM_IOCTL_ARGS) +int i915_vblank_pipe_set(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_vblank_pipe_t pipe; + drm_i915_vblank_pipe_t *pipe = data; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(pipe, (drm_i915_vblank_pipe_t __user *) data, - sizeof(pipe)); - - if (pipe.pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) { + if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) { DRM_ERROR("%s called with invalid pipe 0x%x\n", - __FUNCTION__, pipe.pipe); - return DRM_ERR(EINVAL); + __FUNCTION__, pipe->pipe); + return -EINVAL; } - dev_priv->vblank_pipe = pipe.pipe; + dev_priv->vblank_pipe = pipe->pipe; return 0; } -int i915_vblank_pipe_get(DRM_IOCTL_ARGS) +int i915_vblank_pipe_get(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_vblank_pipe_t pipe; + drm_i915_vblank_pipe_t *pipe = data; u16 flag; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } flag = I915_READ(I915REG_INT_ENABLE_R); - pipe.pipe = 0; + pipe->pipe = 0; if (flag & VSYNC_PIPEA_FLAG) - pipe.pipe |= DRM_I915_VBLANK_PIPE_A; + pipe->pipe |= DRM_I915_VBLANK_PIPE_A; if (flag & VSYNC_PIPEB_FLAG) - pipe.pipe |= DRM_I915_VBLANK_PIPE_B; - DRM_COPY_TO_USER_IOCTL((drm_i915_vblank_pipe_t __user *) data, pipe, - sizeof(pipe)); + pipe->pipe |= DRM_I915_VBLANK_PIPE_B; + return 0; } /** * Schedule buffer swap at given vertical blank. */ -int i915_vblank_swap(DRM_IOCTL_ARGS) +int i915_vblank_swap(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_vblank_swap_t swap; + drm_i915_vblank_swap_t *swap = data; drm_i915_vbl_swap_t *vbl_swap; - unsigned int pipe, seqtype, curseq; + unsigned int pipe, seqtype, curseq, plane; unsigned long irqflags; struct list_head *list; int ret; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __func__); - return DRM_ERR(EINVAL); + return -EINVAL; } if (dev_priv->sarea_priv->rotation) { DRM_DEBUG("Rotation not supported\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(swap, (drm_i915_vblank_swap_t __user *) data, - sizeof(swap)); - - if (swap.seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | + if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS | _DRM_VBLANK_FLIP)) { - DRM_ERROR("Invalid sequence type 0x%x\n", swap.seqtype); - return DRM_ERR(EINVAL); + DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype); + return -EINVAL; } - pipe = (swap.seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; + plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; + pipe = i915_get_pipe(dev, plane); - seqtype = swap.seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); + seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); if (!(dev_priv->vblank_pipe & (1 << pipe))) { DRM_ERROR("Invalid pipe %d\n", pipe); - return DRM_ERR(EINVAL); + return -EINVAL; } - spin_lock_irqsave(&dev->drw_lock, irqflags); + DRM_SPINLOCK_IRQSAVE(&dev->drw_lock, irqflags); - if (!drm_get_drawable_info(dev, swap.drawable)) { - spin_unlock_irqrestore(&dev->drw_lock, irqflags); - DRM_DEBUG("Invalid drawable ID %d\n", swap.drawable); - return DRM_ERR(EINVAL); + /* It makes no sense to schedule a swap for a drawable that doesn't have + * valid information at this point. E.g. this could mean that the X + * server is too old to push drawable information to the DRM, in which + * case all such swaps would become ineffective. + */ + if (!drm_get_drawable_info(dev, swap->drawable)) { + DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags); + DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable); + return -EINVAL; } - spin_unlock_irqrestore(&dev->drw_lock, irqflags); + DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags); drm_update_vblank_count(dev, pipe); curseq = drm_vblank_count(dev, pipe); if (seqtype == _DRM_VBLANK_RELATIVE) - swap.sequence += curseq; + swap->sequence += curseq; - if ((curseq - swap.sequence) <= (1<<23)) { - if (swap.seqtype & _DRM_VBLANK_NEXTONMISS) { - swap.sequence = curseq + 1; + if ((curseq - swap->sequence) <= (1<<23)) { + if (swap->seqtype & _DRM_VBLANK_NEXTONMISS) { + swap->sequence = curseq + 1; } else { DRM_DEBUG("Missed target sequence\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } } - if (swap.seqtype & _DRM_VBLANK_FLIP) { - swap.sequence--; + if (swap->seqtype & _DRM_VBLANK_FLIP) { + swap->sequence--; - if ((curseq - swap.sequence) <= (1<<23)) { - drm_drawable_info_t *drw; + if ((curseq - swap->sequence) <= (1<<23)) { + struct drm_drawable_info *drw; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); - spin_lock_irqsave(&dev->drw_lock, irqflags); + DRM_SPINLOCK_IRQSAVE(&dev->drw_lock, irqflags); - drw = drm_get_drawable_info(dev, swap.drawable); + drw = drm_get_drawable_info(dev, swap->drawable); if (!drw) { - spin_unlock_irqrestore(&dev->drw_lock, irqflags); + DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, + irqflags); DRM_DEBUG("Invalid drawable ID %d\n", - swap.drawable); - return DRM_ERR(EINVAL); + swap->drawable); + return -EINVAL; } - i915_dispatch_vsync_flip(dev, drw, pipe); + i915_dispatch_vsync_flip(dev, drw, plane); - spin_unlock_irqrestore(&dev->drw_lock, irqflags); + DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags); return 0; } } - spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); + DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags); list_for_each(list, &dev_priv->vbl_swaps.head) { vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head); - if (vbl_swap->drw_id == swap.drawable && - vbl_swap->pipe == pipe && - vbl_swap->sequence == swap.sequence) { - vbl_swap->flip = (swap.seqtype & _DRM_VBLANK_FLIP); - spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); + if (vbl_swap->drw_id == swap->drawable && + vbl_swap->plane == plane && + vbl_swap->sequence == swap->sequence) { + vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP); + DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags); DRM_DEBUG("Already scheduled\n"); return 0; } } - spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); + DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags); if (dev_priv->swaps_pending >= 100) { DRM_DEBUG("Too many swaps queued\n"); - return DRM_ERR(EBUSY); + return -EBUSY; } vbl_swap = drm_calloc(1, sizeof(*vbl_swap), DRM_MEM_DRIVER); if (!vbl_swap) { DRM_ERROR("Failed to allocate memory to queue swap\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } DRM_DEBUG("\n"); @@ -730,30 +733,27 @@ int i915_vblank_swap(DRM_IOCTL_ARGS) return ret; } - vbl_swap->drw_id = swap.drawable; - vbl_swap->pipe = pipe; - vbl_swap->sequence = swap.sequence; - vbl_swap->flip = (swap.seqtype & _DRM_VBLANK_FLIP); + vbl_swap->drw_id = swap->drawable; + vbl_swap->plane = plane; + vbl_swap->sequence = swap->sequence; + vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP); if (vbl_swap->flip) - swap.sequence++; + swap->sequence++; - spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); + DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags); list_add_tail((struct list_head *)vbl_swap, &dev_priv->vbl_swaps.head); dev_priv->swaps_pending++; - spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); - - DRM_COPY_TO_USER_IOCTL((drm_i915_vblank_swap_t __user *) data, swap, - sizeof(swap)); + DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags); return 0; } /* drm_dma.h hooks */ -void i915_driver_irq_preinstall(drm_device_t * dev) +void i915_driver_irq_preinstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -762,16 +762,16 @@ void i915_driver_irq_preinstall(drm_device_t * dev) I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); } -int i915_driver_irq_postinstall(drm_device_t * dev) +int i915_driver_irq_postinstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int ret, num_pipes = 2; - spin_lock_init(&dev_priv->swaps_lock); + DRM_SPININIT(&dev_priv->swaps_lock, "swap"); INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); dev_priv->swaps_pending = 0; - dev_priv->user_irq_lock = SPIN_LOCK_UNLOCKED; + DRM_SPININIT(&dev_priv->user_irq_lock, "userirq"); dev_priv->user_irq_refcount = 0; dev_priv->irq_enable_reg = 0; @@ -781,11 +781,6 @@ int i915_driver_irq_postinstall(drm_device_t * dev) dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ - if (!IS_I965G(dev)) { - dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG; - I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg); - } - i915_enable_interrupt(dev); DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); @@ -797,7 +792,7 @@ int i915_driver_irq_postinstall(drm_device_t * dev) return 0; } -void i915_driver_irq_uninstall(drm_device_t * dev) +void i915_driver_irq_uninstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u16 temp; diff --git a/shared-core/i915_mem.c b/shared-core/i915_mem.c index 13f19f3a..5bf29a1e 100644 --- a/shared-core/i915_mem.c +++ b/shared-core/i915_mem.c @@ -43,11 +43,11 @@ * block to allocate, and the ring is drained prior to allocations -- * in other words allocation is expensive. */ -static void mark_block(drm_device_t * dev, struct mem_block *p, int in_use) +static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use) { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_tex_region_t *list; + struct drm_tex_region *list; unsigned shift, nr; unsigned start; unsigned end; @@ -89,7 +89,7 @@ static void mark_block(drm_device_t * dev, struct mem_block *p, int in_use) */ static struct mem_block *split_block(struct mem_block *p, int start, int size, - DRMFILE filp) + struct drm_file *file_priv) { /* Maybe cut off the start of an existing block */ if (start > p->start) { @@ -99,7 +99,7 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, goto out; newblock->start = start; newblock->size = p->size - (start - p->start); - newblock->filp = NULL; + newblock->file_priv = NULL; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -116,7 +116,7 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, goto out; newblock->start = start + size; newblock->size = p->size - size; - newblock->filp = NULL; + newblock->file_priv = NULL; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -126,20 +126,20 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, out: /* Our block is in the middle */ - p->filp = filp; + p->file_priv = file_priv; return p; } static struct mem_block *alloc_block(struct mem_block *heap, int size, - int align2, DRMFILE filp) + int align2, struct drm_file *file_priv) { struct mem_block *p; int mask = (1 << align2) - 1; for (p = heap->next; p != heap; p = p->next) { int start = (p->start + mask) & ~mask; - if (p->filp == NULL && start + size <= p->start + p->size) - return split_block(p, start, size, filp); + if (p->file_priv == NULL && start + size <= p->start + p->size) + return split_block(p, start, size, file_priv); } return NULL; @@ -158,12 +158,12 @@ static struct mem_block *find_block(struct mem_block *heap, int start) static void free_block(struct mem_block *p) { - p->filp = NULL; + p->file_priv = NULL; - /* Assumes a single contiguous range. Needs a special filp in + /* Assumes a single contiguous range. Needs a special file_priv in * 'heap' to stop it being subsumed. */ - if (p->next->filp == NULL) { + if (p->next->file_priv == NULL) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; @@ -171,7 +171,7 @@ static void free_block(struct mem_block *p) drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS); } - if (p->prev->filp == NULL) { + if (p->prev->file_priv == NULL) { struct mem_block *q = p->prev; q->size += p->size; q->next = p->next; @@ -197,18 +197,19 @@ static int init_heap(struct mem_block **heap, int start, int size) blocks->start = start; blocks->size = size; - blocks->filp = NULL; + blocks->file_priv = NULL; blocks->next = blocks->prev = *heap; memset(*heap, 0, sizeof(**heap)); - (*heap)->filp = (DRMFILE) - 1; + (*heap)->file_priv = (struct drm_file *) - 1; (*heap)->next = (*heap)->prev = blocks; return 0; } /* Free all blocks associated with the releasing file. */ -void i915_mem_release(drm_device_t * dev, DRMFILE filp, struct mem_block *heap) +void i915_mem_release(struct drm_device * dev, struct drm_file *file_priv, + struct mem_block *heap) { struct mem_block *p; @@ -216,17 +217,17 @@ void i915_mem_release(drm_device_t * dev, DRMFILE filp, struct mem_block *heap) return; for (p = heap->next; p != heap; p = p->next) { - if (p->filp == filp) { - p->filp = NULL; + if (p->file_priv == file_priv) { + p->file_priv = NULL; mark_block(dev, p, 0); } } - /* Assumes a single contiguous range. Needs a special filp in + /* Assumes a single contiguous range. Needs a special file_priv in * 'heap' to stop it being subsumed. */ for (p = heap->next; p != heap; p = p->next) { - while (p->filp == NULL && p->next->filp == NULL) { + while (p->file_priv == NULL && p->next->file_priv == NULL) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; @@ -267,129 +268,117 @@ static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region) /* IOCTL HANDLERS */ -int i915_mem_alloc(DRM_IOCTL_ARGS) +int i915_mem_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_alloc_t alloc; + drm_i915_mem_alloc_t *alloc = data; struct mem_block *block, **heap; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(alloc, (drm_i915_mem_alloc_t __user *) data, - sizeof(alloc)); - - heap = get_heap(dev_priv, alloc.region); + heap = get_heap(dev_priv, alloc->region); if (!heap || !*heap) - return DRM_ERR(EFAULT); + return -EFAULT; /* Make things easier on ourselves: all allocations at least * 4k aligned. */ - if (alloc.alignment < 12) - alloc.alignment = 12; + if (alloc->alignment < 12) + alloc->alignment = 12; - block = alloc_block(*heap, alloc.size, alloc.alignment, filp); + block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv); if (!block) - return DRM_ERR(ENOMEM); + return -ENOMEM; mark_block(dev, block, 1); - if (DRM_COPY_TO_USER(alloc.region_offset, &block->start, sizeof(int))) { + if (DRM_COPY_TO_USER(alloc->region_offset, &block->start, + sizeof(int))) { DRM_ERROR("copy_to_user\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } return 0; } -int i915_mem_free(DRM_IOCTL_ARGS) +int i915_mem_free(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_free_t memfree; + drm_i915_mem_free_t *memfree = data; struct mem_block *block, **heap; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(memfree, (drm_i915_mem_free_t __user *) data, - sizeof(memfree)); - - heap = get_heap(dev_priv, memfree.region); + heap = get_heap(dev_priv, memfree->region); if (!heap || !*heap) - return DRM_ERR(EFAULT); + return -EFAULT; - block = find_block(*heap, memfree.region_offset); + block = find_block(*heap, memfree->region_offset); if (!block) - return DRM_ERR(EFAULT); + return -EFAULT; - if (block->filp != filp) - return DRM_ERR(EPERM); + if (block->file_priv != file_priv) + return -EPERM; mark_block(dev, block, 0); free_block(block); return 0; } -int i915_mem_init_heap(DRM_IOCTL_ARGS) +int i915_mem_init_heap(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_init_heap_t initheap; + drm_i915_mem_init_heap_t *initheap = data; struct mem_block **heap; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(initheap, - (drm_i915_mem_init_heap_t __user *) data, - sizeof(initheap)); - - heap = get_heap(dev_priv, initheap.region); + heap = get_heap(dev_priv, initheap->region); if (!heap) - return DRM_ERR(EFAULT); + return -EFAULT; if (*heap) { DRM_ERROR("heap already initialized?"); - return DRM_ERR(EFAULT); + return -EFAULT; } - return init_heap(heap, initheap.start, initheap.size); + return init_heap(heap, initheap->start, initheap->size); } -int i915_mem_destroy_heap( DRM_IOCTL_ARGS ) +int i915_mem_destroy_heap( struct drm_device *dev, void *data, + struct drm_file *file_priv ) { - DRM_DEVICE; drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_destroy_heap_t destroyheap; + drm_i915_mem_destroy_heap_t *destroyheap = data; struct mem_block **heap; if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL( destroyheap, (drm_i915_mem_destroy_heap_t *)data, - sizeof(destroyheap) ); - - heap = get_heap( dev_priv, destroyheap.region ); + heap = get_heap( dev_priv, destroyheap->region ); if (!heap) { DRM_ERROR("get_heap failed"); - return DRM_ERR(EFAULT); + return -EFAULT; } if (!*heap) { DRM_ERROR("heap not initialized?"); - return DRM_ERR(EFAULT); + return -EFAULT; } i915_mem_takedown( heap ); diff --git a/shared-core/mach64_dma.c b/shared-core/mach64_dma.c index 60f55900..e0a67458 100644 --- a/shared-core/mach64_dma.c +++ b/shared-core/mach64_dma.c @@ -70,7 +70,7 @@ int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv, int entries) DRM_INFO("%s failed! slots=%d entries=%d\n", __FUNCTION__, slots, entries); - return DRM_ERR(EBUSY); + return -EBUSY; } /** @@ -94,7 +94,7 @@ int mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv) DRM_INFO("%s failed! GUI_STAT=0x%08x\n", __FUNCTION__, MACH64_READ(MACH64_GUI_STAT)); mach64_dump_ring_info(dev_priv); - return DRM_ERR(EBUSY); + return -EBUSY; } /** @@ -135,7 +135,7 @@ int mach64_wait_ring(drm_mach64_private_t * dev_priv, int n) /* FIXME: This is being ignored... */ DRM_ERROR("failed!\n"); mach64_dump_ring_info(dev_priv); - return DRM_ERR(EBUSY); + return -EBUSY; } /** @@ -172,7 +172,7 @@ static int mach64_ring_idle(drm_mach64_private_t * dev_priv) DRM_INFO("%s failed! GUI_STAT=0x%08x\n", __FUNCTION__, MACH64_READ(MACH64_GUI_STAT)); mach64_dump_ring_info(dev_priv); - return DRM_ERR(EBUSY); + return -EBUSY; } /** @@ -418,7 +418,7 @@ void mach64_dump_engine_info(drm_mach64_private_t * dev_priv) * pointed by the ring head. */ static void mach64_dump_buf_info(drm_mach64_private_t * dev_priv, - drm_buf_t * buf) + struct drm_buf * buf) { u32 addr = GETBUFADDR(buf); u32 used = buf->used >> 2; @@ -522,7 +522,7 @@ void mach64_dump_ring_info(drm_mach64_private_t * dev_priv) list_for_each(ptr, &dev_priv->pending) { drm_mach64_freelist_t *entry = list_entry(ptr, drm_mach64_freelist_t, list); - drm_buf_t *buf = entry->buf; + struct drm_buf *buf = entry->buf; u32 buf_addr = GETBUFADDR(buf); @@ -572,7 +572,7 @@ void mach64_dump_ring_info(drm_mach64_private_t * dev_priv) * DMA operation. It is left here since it so tricky to get DMA operating * properly in some architectures and hardware. */ -static int mach64_bm_dma_test(drm_device_t * dev) +static int mach64_bm_dma_test(struct drm_device * dev) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_dma_handle_t *cpu_addr_dmah; @@ -592,7 +592,7 @@ static int mach64_bm_dma_test(drm_device_t * dev) drm_pci_alloc(dev, 0x1000, 0x1000, 0xfffffffful); if (!cpu_addr_dmah) { DRM_INFO("data-memory allocation failed!\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } else { data = (u32 *) cpu_addr_dmah->vaddr; data_addr = (u32) cpu_addr_dmah->busaddr; @@ -624,7 +624,7 @@ static int mach64_bm_dma_test(drm_device_t * dev) mach64_do_engine_reset(dev_priv); DRM_INFO("freeing data buffer memory.\n"); drm_pci_free(dev, cpu_addr_dmah); - return DRM_ERR(EIO); + return -EIO; } } @@ -752,7 +752,7 @@ static int mach64_bm_dma_test(drm_device_t * dev) * Called during the DMA initialization ioctl to initialize all the necessary * software and hardware state for DMA operation. */ -static int mach64_do_dma_init(drm_device_t * dev, drm_mach64_init_t * init) +static int mach64_do_dma_init(struct drm_device * dev, drm_mach64_init_t * init) { drm_mach64_private_t *dev_priv; u32 tmp; @@ -762,7 +762,7 @@ static int mach64_do_dma_init(drm_device_t * dev, drm_mach64_init_t * init) dev_priv = drm_alloc(sizeof(drm_mach64_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; memset(dev_priv, 0, sizeof(drm_mach64_private_t)); @@ -797,21 +797,21 @@ static int mach64_do_dma_init(drm_device_t * dev, drm_mach64_init_t * init) DRM_ERROR("can not find sarea!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->fb = drm_core_findmap(dev, init->fb_offset); if (!dev_priv->fb) { DRM_ERROR("can not find frame buffer map!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); if (!dev_priv->mmio) { DRM_ERROR("can not find mmio map!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->ring_map = drm_core_findmap(dev, init->ring_offset); @@ -819,7 +819,7 @@ static int mach64_do_dma_init(drm_device_t * dev, drm_mach64_init_t * init) DRM_ERROR("can not find ring map!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->sarea_priv = (drm_mach64_sarea_t *) @@ -832,7 +832,7 @@ static int mach64_do_dma_init(drm_device_t * dev, drm_mach64_init_t * init) " descriptor ring\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return DRM_ERR(ENOMEM); + return -ENOMEM; } dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = @@ -841,7 +841,7 @@ static int mach64_do_dma_init(drm_device_t * dev, drm_mach64_init_t * init) DRM_ERROR("can not find dma buffer map!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } /* there might be a nicer way to do this - dev isn't passed all the way though the mach64 - DA */ @@ -853,7 +853,7 @@ static int mach64_do_dma_init(drm_device_t * dev, drm_mach64_init_t * init) " dma buffer\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return DRM_ERR(ENOMEM); + return -ENOMEM; } dev_priv->agp_textures = drm_core_findmap(dev, init->agp_textures_offset); @@ -861,7 +861,7 @@ static int mach64_do_dma_init(drm_device_t * dev, drm_mach64_init_t * init) DRM_ERROR("can not find agp texture region!\n"); dev->dev_private = (void *)dev_priv; mach64_do_cleanup_dma(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } } @@ -974,7 +974,7 @@ int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv) volatile u32 *ring_read; struct list_head *ptr; drm_mach64_freelist_t *entry; - drm_buf_t *buf = NULL; + struct drm_buf *buf = NULL; u32 *buf_ptr; u32 used, reg, target; int fifo, count, found, ret, no_idle_wait; @@ -1035,7 +1035,7 @@ int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv) head, ring->tail, buf_addr, (eol ? "eol" : "")); mach64_dump_ring_info(dev_priv); mach64_do_engine_reset(dev_priv); - return DRM_ERR(EINVAL); + return -EINVAL; } /* Hand feed the buffer to the card via MMIO, waiting for the fifo @@ -1117,7 +1117,7 @@ int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv) /** \name DMA cleanup */ /*@{*/ -int mach64_do_cleanup_dma(drm_device_t * dev) +int mach64_do_cleanup_dma(struct drm_device * dev) { DRM_DEBUG("%s\n", __FUNCTION__); @@ -1158,60 +1158,57 @@ int mach64_do_cleanup_dma(drm_device_t * dev) /** \name IOCTL handlers */ /*@{*/ -int mach64_dma_init(DRM_IOCTL_ARGS) +int mach64_dma_init(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; - drm_mach64_init_t init; + drm_mach64_init_t *init = data; DRM_DEBUG("%s\n", __FUNCTION__); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_COPY_FROM_USER_IOCTL(init, (drm_mach64_init_t *) data, - sizeof(init)); - - switch (init.func) { + switch (init->func) { case DRM_MACH64_INIT_DMA: - return mach64_do_dma_init(dev, &init); + return mach64_do_dma_init(dev, init); case DRM_MACH64_CLEANUP_DMA: return mach64_do_cleanup_dma(dev); } - return DRM_ERR(EINVAL); + return -EINVAL; } -int mach64_dma_idle(DRM_IOCTL_ARGS) +int mach64_dma_idle(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_mach64_private_t *dev_priv = dev->dev_private; DRM_DEBUG("%s\n", __FUNCTION__); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); return mach64_do_dma_idle(dev_priv); } -int mach64_dma_flush(DRM_IOCTL_ARGS) +int mach64_dma_flush(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_mach64_private_t *dev_priv = dev->dev_private; DRM_DEBUG("%s\n", __FUNCTION__); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); return mach64_do_dma_flush(dev_priv); } -int mach64_engine_reset(DRM_IOCTL_ARGS) +int mach64_engine_reset(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_mach64_private_t *dev_priv = dev->dev_private; DRM_DEBUG("%s\n", __FUNCTION__); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); return mach64_do_engine_reset(dev_priv); } @@ -1223,9 +1220,9 @@ int mach64_engine_reset(DRM_IOCTL_ARGS) /** \name Freelist management */ /*@{*/ -int mach64_init_freelist(drm_device_t * dev) +int mach64_init_freelist(struct drm_device * dev) { - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_freelist_t *entry; struct list_head *ptr; @@ -1239,7 +1236,7 @@ int mach64_init_freelist(drm_device_t * dev) (drm_mach64_freelist_t *) drm_alloc(sizeof(drm_mach64_freelist_t), DRM_MEM_BUFLISTS)) == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; memset(entry, 0, sizeof(drm_mach64_freelist_t)); entry->buf = dma->buflist[i]; ptr = &entry->list; @@ -1249,7 +1246,7 @@ int mach64_init_freelist(drm_device_t * dev) return 0; } -void mach64_destroy_freelist(drm_device_t * dev) +void mach64_destroy_freelist(struct drm_device * dev) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_freelist_t *entry; @@ -1381,7 +1378,7 @@ static int mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv) return 1; } -drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv) +struct drm_buf *mach64_freelist_get(drm_mach64_private_t * dev_priv) { drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; drm_mach64_freelist_t *entry; @@ -1427,7 +1424,7 @@ drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv) return entry->buf; } -int mach64_freelist_put(drm_mach64_private_t * dev_priv, drm_buf_t * copy_buf) +int mach64_freelist_put(drm_mach64_private_t * dev_priv, struct drm_buf * copy_buf) { struct list_head *ptr; drm_mach64_freelist_t *entry; @@ -1438,7 +1435,7 @@ int mach64_freelist_put(drm_mach64_private_t * dev_priv, drm_buf_t * copy_buf) if (copy_buf == entry->buf) { DRM_ERROR("%s: Trying to release a pending buf\n", __FUNCTION__); - return DRM_ERR(EFAULT); + return -EFAULT; } } #endif @@ -1461,76 +1458,73 @@ int mach64_freelist_put(drm_mach64_private_t * dev_priv, drm_buf_t * copy_buf) /** \name DMA buffer request and submission IOCTL handler */ /*@{*/ -static int mach64_dma_get_buffers(DRMFILE filp, drm_device_t * dev, - drm_dma_t * d) +static int mach64_dma_get_buffers(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_dma * d) { int i; - drm_buf_t *buf; + struct drm_buf *buf; drm_mach64_private_t *dev_priv = dev->dev_private; for (i = d->granted_count; i < d->request_count; i++) { buf = mach64_freelist_get(dev_priv); #if MACH64_EXTRA_CHECKING if (!buf) - return DRM_ERR(EFAULT); + return -EFAULT; #else if (!buf) - return DRM_ERR(EAGAIN); + return -EAGAIN; #endif - buf->filp = filp; + buf->file_priv = file_priv; if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, sizeof(buf->idx))) - return DRM_ERR(EFAULT); + return -EFAULT; if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, sizeof(buf->total))) - return DRM_ERR(EFAULT); + return -EFAULT; d->granted_count++; } return 0; } -int mach64_dma_buffers(DRM_IOCTL_ARGS) +int mach64_dma_buffers(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; - drm_device_dma_t *dma = dev->dma; - drm_dma_t d; + struct drm_device_dma *dma = dev->dma; + struct drm_dma *d = data; int ret = 0; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t *) data, sizeof(d)); + LOCK_TEST_WITH_RETURN(dev, file_priv); /* Please don't send us buffers. */ - if (d.send_count != 0) { + if (d->send_count != 0) { DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d.send_count); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, d->send_count); + return -EINVAL; } /* We'll send you buffers. */ - if (d.request_count < 0 || d.request_count > dma->buf_count) { + if (d->request_count < 0 || d->request_count > dma->buf_count) { DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d.request_count, dma->buf_count); - ret = DRM_ERR(EINVAL); + DRM_CURRENTPID, d->request_count, dma->buf_count); + ret = -EINVAL; } - d.granted_count = 0; + d->granted_count = 0; - if (d.request_count) { - ret = mach64_dma_get_buffers(filp, dev, &d); + if (d->request_count) { + ret = mach64_dma_get_buffers(dev, file_priv, d); } - DRM_COPY_TO_USER_IOCTL((drm_dma_t *) data, d, sizeof(d)); - return ret; } -void mach64_driver_lastclose(drm_device_t * dev) +void mach64_driver_lastclose(struct drm_device * dev) { mach64_do_cleanup_dma(dev); } diff --git a/shared-core/mach64_drm.h b/shared-core/mach64_drm.h index 083f959d..1f5fd842 100644 --- a/shared-core/mach64_drm.h +++ b/shared-core/mach64_drm.h @@ -130,7 +130,7 @@ typedef struct drm_mach64_sarea { /* The current cliprects, or a subset thereof. */ - drm_clip_rect_t boxes[MACH64_NR_SAREA_CLIPRECTS]; + struct drm_clip_rect boxes[MACH64_NR_SAREA_CLIPRECTS]; unsigned int nbox; /* Counters for client-side throttling of rendering clients. @@ -139,7 +139,7 @@ typedef struct drm_mach64_sarea { /* Texture memory LRU. */ - drm_tex_region_t tex_list[MACH64_NR_TEX_HEAPS][MACH64_NR_TEX_REGIONS + + struct drm_tex_region tex_list[MACH64_NR_TEX_HEAPS][MACH64_NR_TEX_REGIONS + 1]; unsigned int tex_age[MACH64_NR_TEX_HEAPS]; int ctx_owner; diff --git a/shared-core/mach64_drv.h b/shared-core/mach64_drv.h index bb8b309e..cebd4c6e 100644 --- a/shared-core/mach64_drv.h +++ b/shared-core/mach64_drv.h @@ -55,7 +55,7 @@ typedef struct drm_mach64_freelist { struct list_head list; /* List pointers for free_list, placeholders, or pending list */ - drm_buf_t *buf; /* Pointer to the buffer */ + struct drm_buf *buf; /* Pointer to the buffer */ int discard; /* This flag is set when we're done (re)using a buffer */ u32 ring_ofs; /* dword offset in ring of last descriptor for this buffer */ } drm_mach64_freelist_t; @@ -108,22 +108,27 @@ typedef struct drm_mach64_private { drm_local_map_t *agp_textures; } drm_mach64_private_t; -extern drm_ioctl_desc_t mach64_ioctls[]; +extern struct drm_ioctl_desc mach64_ioctls[]; extern int mach64_max_ioctl; /* mach64_dma.c */ -extern int mach64_dma_init(DRM_IOCTL_ARGS); -extern int mach64_dma_idle(DRM_IOCTL_ARGS); -extern int mach64_dma_flush(DRM_IOCTL_ARGS); -extern int mach64_engine_reset(DRM_IOCTL_ARGS); -extern int mach64_dma_buffers(DRM_IOCTL_ARGS); -extern void mach64_driver_lastclose(drm_device_t * dev); - -extern int mach64_init_freelist(drm_device_t * dev); -extern void mach64_destroy_freelist(drm_device_t * dev); -extern drm_buf_t *mach64_freelist_get(drm_mach64_private_t * dev_priv); +extern int mach64_dma_init(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mach64_dma_idle(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mach64_dma_flush(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mach64_engine_reset(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mach64_dma_buffers(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern void mach64_driver_lastclose(struct drm_device * dev); + +extern int mach64_init_freelist(struct drm_device * dev); +extern void mach64_destroy_freelist(struct drm_device * dev); +extern struct drm_buf *mach64_freelist_get(drm_mach64_private_t * dev_priv); extern int mach64_freelist_put(drm_mach64_private_t * dev_priv, - drm_buf_t * copy_buf); + struct drm_buf * copy_buf); extern int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv, int entries); @@ -137,21 +142,26 @@ extern int mach64_do_engine_reset(drm_mach64_private_t * dev_priv); extern int mach64_do_dma_idle(drm_mach64_private_t * dev_priv); extern int mach64_do_dma_flush(drm_mach64_private_t * dev_priv); -extern int mach64_do_cleanup_dma(drm_device_t * dev); +extern int mach64_do_cleanup_dma(struct drm_device * dev); /* mach64_state.c */ -extern int mach64_dma_clear(DRM_IOCTL_ARGS); -extern int mach64_dma_swap(DRM_IOCTL_ARGS); -extern int mach64_dma_vertex(DRM_IOCTL_ARGS); -extern int mach64_dma_blit(DRM_IOCTL_ARGS); -extern int mach64_get_param(DRM_IOCTL_ARGS); -extern int mach64_driver_vblank_wait(drm_device_t * dev, +extern int mach64_dma_clear(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mach64_dma_swap(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mach64_dma_vertex(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mach64_dma_blit(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mach64_get_param(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mach64_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); extern irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS); -extern void mach64_driver_irq_preinstall(drm_device_t * dev); -extern void mach64_driver_irq_postinstall(drm_device_t * dev); -extern void mach64_driver_irq_uninstall(drm_device_t * dev); +extern void mach64_driver_irq_preinstall(struct drm_device * dev); +extern void mach64_driver_irq_postinstall(struct drm_device * dev); +extern void mach64_driver_irq_uninstall(struct drm_device * dev); /* ================================================================ * Registers @@ -798,7 +808,7 @@ do { \ #define DMALOCALS \ drm_mach64_freelist_t *_entry = NULL; \ - drm_buf_t *_buf = NULL; \ + struct drm_buf *_buf = NULL; \ u32 *_buf_wptr; int _outcount #define GETBUFPTR( __buf ) \ @@ -813,20 +823,20 @@ do { \ static __inline__ int mach64_find_pending_buf_entry(drm_mach64_private_t * dev_priv, drm_mach64_freelist_t ** - entry, drm_buf_t * buf) + entry, struct drm_buf * buf) { struct list_head *ptr; #if MACH64_EXTRA_CHECKING if (list_empty(&dev_priv->pending)) { DRM_ERROR("Empty pending list in %s\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } #endif ptr = dev_priv->pending.prev; *entry = list_entry(ptr, drm_mach64_freelist_t, list); while ((*entry)->buf != buf) { if (ptr == &dev_priv->pending) { - return DRM_ERR(EFAULT); + return -EFAULT; } ptr = ptr->prev; *entry = list_entry(ptr, drm_mach64_freelist_t, list); @@ -842,7 +852,7 @@ do { \ } while(0) /* FIXME: use a private set of smaller buffers for state emits, clears, and swaps? */ -#define DMAGETPTR( filp, dev_priv, n ) \ +#define DMAGETPTR( file_priv, dev_priv, n ) \ do { \ if ( MACH64_VERBOSE ) { \ DRM_INFO( "DMAGETPTR( %d ) in %s\n", \ @@ -852,14 +862,14 @@ do { \ if (_buf == NULL) { \ DRM_ERROR("%s: couldn't get buffer in DMAGETPTR\n", \ __FUNCTION__ ); \ - return DRM_ERR(EAGAIN); \ + return -EAGAIN; \ } \ if (_buf->pending) { \ DRM_ERROR("%s: pending buf in DMAGETPTR\n", \ __FUNCTION__ ); \ - return DRM_ERR(EFAULT); \ + return -EFAULT; \ } \ - _buf->filp = filp; \ + _buf->file_priv = file_priv; \ _outcount = 0; \ \ _buf_wptr = GETBUFPTR( _buf ); \ @@ -888,7 +898,7 @@ do { \ if (_buf->used <= 0) { \ DRM_ERROR( "DMAADVANCE() in %s: sending empty buf %d\n", \ __FUNCTION__, _buf->idx ); \ - return DRM_ERR(EFAULT); \ + return -EFAULT; \ } \ if (_buf->pending) { \ /* This is a resued buffer, so we need to find it in the pending list */ \ @@ -901,13 +911,13 @@ do { \ if (_entry->discard) { \ DRM_ERROR( "DMAADVANCE() in %s: sending discarded pending buf %d\n", \ __FUNCTION__, _buf->idx ); \ - return DRM_ERR(EFAULT); \ + return -EFAULT; \ } \ } else { \ if (list_empty(&dev_priv->placeholders)) { \ DRM_ERROR( "DMAADVANCE() in %s: empty placeholder list\n", \ __FUNCTION__ ); \ - return DRM_ERR(EFAULT); \ + return -EFAULT; \ } \ ptr = dev_priv->placeholders.next; \ list_del(ptr); \ @@ -983,12 +993,12 @@ do { \ if (_buf->used <= 0) { \ DRM_ERROR( "DMAADVANCEHOSTDATA() in %s: sending empty buf %d\n", \ __FUNCTION__, _buf->idx ); \ - return DRM_ERR(EFAULT); \ + return -EFAULT; \ } \ if (list_empty(&dev_priv->placeholders)) { \ DRM_ERROR( "%s: empty placeholder list in DMAADVANCEHOSTDATA()\n", \ __FUNCTION__ ); \ - return DRM_ERR(EFAULT); \ + return -EFAULT; \ } \ \ ptr = dev_priv->placeholders.next; \ diff --git a/shared-core/mach64_irq.c b/shared-core/mach64_irq.c index 663642db..4122dd91 100644 --- a/shared-core/mach64_irq.c +++ b/shared-core/mach64_irq.c @@ -42,7 +42,7 @@ irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS) { - drm_device_t *dev = (drm_device_t *) arg; + struct drm_device *dev = (struct drm_device *) arg; drm_mach64_private_t *dev_priv = (drm_mach64_private_t *) dev->dev_private; int status; @@ -70,7 +70,7 @@ irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_NONE; } -int mach64_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) +int mach64_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) { unsigned int cur_vblank; int ret = 0; @@ -90,7 +90,7 @@ int mach64_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) /* drm_dma.h hooks */ -void mach64_driver_irq_preinstall(drm_device_t * dev) +void mach64_driver_irq_preinstall(struct drm_device * dev) { drm_mach64_private_t *dev_priv = (drm_mach64_private_t *) dev->dev_private; @@ -104,7 +104,7 @@ void mach64_driver_irq_preinstall(drm_device_t * dev) | MACH64_CRTC_VBLANK_INT); } -void mach64_driver_irq_postinstall(drm_device_t * dev) +void mach64_driver_irq_postinstall(struct drm_device * dev) { drm_mach64_private_t *dev_priv = (drm_mach64_private_t *) dev->dev_private; @@ -118,7 +118,7 @@ void mach64_driver_irq_postinstall(drm_device_t * dev) } -void mach64_driver_irq_uninstall(drm_device_t * dev) +void mach64_driver_irq_uninstall(struct drm_device * dev) { drm_mach64_private_t *dev_priv = (drm_mach64_private_t *) dev->dev_private; diff --git a/shared-core/mach64_state.c b/shared-core/mach64_state.c index 38cefca9..89b6c6ce 100644 --- a/shared-core/mach64_state.c +++ b/shared-core/mach64_state.c @@ -40,16 +40,16 @@ * 1.0 - Initial mach64 DRM * */ -drm_ioctl_desc_t mach64_ioctls[] = { - [DRM_IOCTL_NR(DRM_MACH64_INIT)] = {mach64_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_MACH64_CLEAR)] = {mach64_dma_clear, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MACH64_SWAP)] = {mach64_dma_swap, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MACH64_IDLE)] = {mach64_dma_idle, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MACH64_RESET)] = {mach64_engine_reset, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MACH64_VERTEX)] = {mach64_dma_vertex, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MACH64_BLIT)] = {mach64_dma_blit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MACH64_FLUSH)] = {mach64_dma_flush, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MACH64_GETPARAM)] = {mach64_get_param, DRM_AUTH}, +struct drm_ioctl_desc mach64_ioctls[] = { + DRM_IOCTL_DEF(DRM_MACH64_INIT, mach64_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_MACH64_CLEAR, mach64_dma_clear, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MACH64_SWAP, mach64_dma_swap, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MACH64_IDLE, mach64_dma_idle, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MACH64_RESET, mach64_engine_reset, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MACH64_VERTEX, mach64_dma_vertex, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MACH64_BLIT, mach64_dma_blit, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MACH64_FLUSH, mach64_dma_flush, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MACH64_GETPARAM, mach64_get_param, DRM_AUTH), }; int mach64_max_ioctl = DRM_ARRAY_SIZE(mach64_ioctls); @@ -85,11 +85,12 @@ static void mach64_print_dirty(const char *msg, unsigned int flags) /* This function returns 0 on success, 1 for no intersection, and * negative for an error */ -static int mach64_emit_cliprect(DRMFILE filp, drm_mach64_private_t * dev_priv, - drm_clip_rect_t * box) +static int mach64_emit_cliprect(struct drm_file *file_priv, + drm_mach64_private_t * dev_priv, + struct drm_clip_rect * box) { u32 sc_left_right, sc_top_bottom; - drm_clip_rect_t scissor; + struct drm_clip_rect scissor; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mach64_context_regs_t *regs = &sarea_priv->context_state; DMALOCALS; @@ -120,7 +121,7 @@ static int mach64_emit_cliprect(DRMFILE filp, drm_mach64_private_t * dev_priv, if (scissor.y1 >= scissor.y2) return 1; - DMAGETPTR(filp, dev_priv, 2); /* returns on failure to get buffer */ + DMAGETPTR(file_priv, dev_priv, 2); /* returns on failure to get buffer */ sc_left_right = ((scissor.x1 << 0) | (scissor.x2 << 16)); sc_top_bottom = ((scissor.y1 << 0) | (scissor.y2 << 16)); @@ -133,7 +134,7 @@ static int mach64_emit_cliprect(DRMFILE filp, drm_mach64_private_t * dev_priv, return 0; } -static __inline__ int mach64_emit_state(DRMFILE filp, +static __inline__ int mach64_emit_state(struct drm_file *file_priv, drm_mach64_private_t * dev_priv) { drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -148,7 +149,7 @@ static __inline__ int mach64_emit_state(DRMFILE filp, DRM_DEBUG("%s: dirty=0x%08x\n", __FUNCTION__, dirty); } - DMAGETPTR(filp, dev_priv, 17); /* returns on failure to get buffer */ + DMAGETPTR(file_priv, dev_priv, 17); /* returns on failure to get buffer */ if (dirty & MACH64_UPLOAD_MISC) { DMAOUTREG(MACH64_DP_MIX, regs->dp_mix); @@ -212,7 +213,8 @@ static __inline__ int mach64_emit_state(DRMFILE filp, * DMA command dispatch functions */ -static int mach64_dma_dispatch_clear(DRMFILE filp, drm_device_t * dev, +static int mach64_dma_dispatch_clear(struct drm_device * dev, + struct drm_file *file_priv, unsigned int flags, int cx, int cy, int cw, int ch, unsigned int clear_color, @@ -222,7 +224,7 @@ static int mach64_dma_dispatch_clear(DRMFILE filp, drm_device_t * dev, drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mach64_context_regs_t *ctx = &sarea_priv->context_state; int nbox = sarea_priv->nbox; - drm_clip_rect_t *pbox = sarea_priv->boxes; + struct drm_clip_rect *pbox = sarea_priv->boxes; u32 fb_bpp, depth_bpp; int i; DMALOCALS; @@ -237,7 +239,7 @@ static int mach64_dma_dispatch_clear(DRMFILE filp, drm_device_t * dev, fb_bpp = MACH64_DATATYPE_ARGB8888; break; default: - return DRM_ERR(EINVAL); + return -EINVAL; } switch (dev_priv->depth_bpp) { case 16: @@ -248,13 +250,13 @@ static int mach64_dma_dispatch_clear(DRMFILE filp, drm_device_t * dev, depth_bpp = MACH64_DATATYPE_ARGB8888; break; default: - return DRM_ERR(EINVAL); + return -EINVAL; } if (!nbox) return 0; - DMAGETPTR(filp, dev_priv, nbox * 31); /* returns on failure to get buffer */ + DMAGETPTR(file_priv, dev_priv, nbox * 31); /* returns on failure to get buffer */ for (i = 0; i < nbox; i++) { int x = pbox[i].x1; @@ -355,12 +357,13 @@ static int mach64_dma_dispatch_clear(DRMFILE filp, drm_device_t * dev, return 0; } -static int mach64_dma_dispatch_swap(DRMFILE filp, drm_device_t * dev) +static int mach64_dma_dispatch_swap(struct drm_device * dev, + struct drm_file *file_priv) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; - drm_clip_rect_t *pbox = sarea_priv->boxes; + struct drm_clip_rect *pbox = sarea_priv->boxes; u32 fb_bpp; int i; DMALOCALS; @@ -380,7 +383,7 @@ static int mach64_dma_dispatch_swap(DRMFILE filp, drm_device_t * dev) if (!nbox) return 0; - DMAGETPTR(filp, dev_priv, 13 + nbox * 4); /* returns on failure to get buffer */ + DMAGETPTR(file_priv, dev_priv, 13 + nbox * 4); /* returns on failure to get buffer */ DMAOUTREG(MACH64_Z_CNTL, 0); DMAOUTREG(MACH64_SCALE_3D_CNTL, 0); @@ -489,11 +492,11 @@ static __inline__ int copy_from_user_vertex(u32 *to, from = drm_alloc(bytes, DRM_MEM_DRIVER); if (from == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; if (DRM_COPY_FROM_USER(from, ufrom, bytes)) { drm_free(from, bytes, DRM_MEM_DRIVER); - return DRM_ERR(EFAULT); + return -EFAULT; } orig_from = from; /* we'll be modifying the "from" ptr, so save it */ @@ -525,14 +528,14 @@ static __inline__ int copy_from_user_vertex(u32 *to, DRM_ERROR("%s: Got bad command: 0x%04x\n", __FUNCTION__, reg); drm_free(orig_from, bytes, DRM_MEM_DRIVER); - return DRM_ERR(EACCES); + return -EACCES; } } else { DRM_ERROR ("%s: Got bad command count(=%u) dwords remaining=%lu\n", __FUNCTION__, count, n); drm_free(orig_from, bytes, DRM_MEM_DRIVER); - return DRM_ERR(EINVAL); + return -EINVAL; } } @@ -541,16 +544,17 @@ static __inline__ int copy_from_user_vertex(u32 *to, return 0; else { DRM_ERROR("%s: Bad buf->used(=%lu)\n", __FUNCTION__, bytes); - return DRM_ERR(EINVAL); + return -EINVAL; } } -static int mach64_dma_dispatch_vertex(DRMFILE filp, drm_device_t * dev, +static int mach64_dma_dispatch_vertex(struct drm_device * dev, + struct drm_file *file_priv, drm_mach64_vertex_t * vertex) { drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_buf_t *copy_buf; + struct drm_buf *copy_buf; void *buf = vertex->buf; unsigned long used = vertex->used; int ret = 0; @@ -568,7 +572,7 @@ static int mach64_dma_dispatch_vertex(DRMFILE filp, drm_device_t * dev, copy_buf = mach64_freelist_get(dev_priv); if (copy_buf == NULL) { DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__); - return DRM_ERR(EAGAIN); + return -EAGAIN; } verify_ret = copy_from_user_vertex(GETBUFPTR(copy_buf), buf, used); @@ -583,7 +587,7 @@ static int mach64_dma_dispatch_vertex(DRMFILE filp, drm_device_t * dev, DMASETPTR(copy_buf); if (sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS) { - ret = mach64_emit_state(filp, dev_priv); + ret = mach64_emit_state(file_priv, dev_priv); if (ret < 0) return ret; } @@ -591,7 +595,7 @@ static int mach64_dma_dispatch_vertex(DRMFILE filp, drm_device_t * dev, do { /* Emit the next cliprect */ if (i < sarea_priv->nbox) { - ret = mach64_emit_cliprect(filp, dev_priv, + ret = mach64_emit_cliprect(file_priv, dev_priv, &sarea_priv->boxes[i]); if (ret < 0) { /* failed to get buffer */ @@ -634,19 +638,20 @@ static __inline__ int copy_from_user_blit(u32 *to, to = (u32 *)((char *)to + MACH64_HOSTDATA_BLIT_OFFSET); if (DRM_COPY_FROM_USER(to, ufrom, bytes)) { - return DRM_ERR(EFAULT); + return -EFAULT; } return 0; } -static int mach64_dma_dispatch_blit(DRMFILE filp, drm_device_t * dev, +static int mach64_dma_dispatch_blit(struct drm_device * dev, + struct drm_file *file_priv, drm_mach64_blit_t * blit) { drm_mach64_private_t *dev_priv = dev->dev_private; int dword_shift, dwords; unsigned long used; - drm_buf_t *copy_buf; + struct drm_buf *copy_buf; int verify_ret = 0; DMALOCALS; @@ -671,7 +676,7 @@ static int mach64_dma_dispatch_blit(DRMFILE filp, drm_device_t * dev, break; default: DRM_ERROR("invalid blit format %d\n", blit->format); - return DRM_ERR(EINVAL); + return -EINVAL; } /* Set buf->used to the bytes of blit data based on the blit dimensions @@ -684,13 +689,13 @@ static int mach64_dma_dispatch_blit(DRMFILE filp, drm_device_t * dev, if (used <= 0 || used > MACH64_BUFFER_SIZE - MACH64_HOSTDATA_BLIT_OFFSET) { DRM_ERROR("Invalid blit size: %lu bytes\n", used); - return DRM_ERR(EINVAL); + return -EINVAL; } copy_buf = mach64_freelist_get(dev_priv); if (copy_buf == NULL) { DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__); - return DRM_ERR(EAGAIN); + return -EAGAIN; } verify_ret = copy_from_user_blit(GETBUFPTR(copy_buf), blit->buf, used); @@ -753,27 +758,25 @@ _blit_done: * IOCTL functions */ -int mach64_dma_clear(DRM_IOCTL_ARGS) +int mach64_dma_clear(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mach64_clear_t clear; + drm_mach64_clear_t *clear = data; int ret; DRM_DEBUG("%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID); - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(clear, (drm_mach64_clear_t *) data, - sizeof(clear)); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; - ret = mach64_dma_dispatch_clear(filp, dev, clear.flags, - clear.x, clear.y, clear.w, clear.h, - clear.clear_color, clear.clear_depth); + ret = mach64_dma_dispatch_clear(dev, file_priv, clear->flags, + clear->x, clear->y, clear->w, clear->h, + clear->clear_color, + clear->clear_depth); /* Make sure we restore the 3D state next time. */ @@ -781,21 +784,21 @@ int mach64_dma_clear(DRM_IOCTL_ARGS) return ret; } -int mach64_dma_swap(DRM_IOCTL_ARGS) +int mach64_dma_swap(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; int ret; DRM_DEBUG("%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; - ret = mach64_dma_dispatch_swap(filp, dev); + ret = mach64_dma_dispatch_swap(dev, file_priv); /* Make sure we restore the 3D state next time. */ @@ -803,58 +806,52 @@ int mach64_dma_swap(DRM_IOCTL_ARGS) return ret; } -int mach64_dma_vertex(DRM_IOCTL_ARGS) +int mach64_dma_vertex(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mach64_vertex_t vertex; + drm_mach64_vertex_t *vertex = data; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(vertex, (drm_mach64_vertex_t *) data, - sizeof(vertex)); - DRM_DEBUG("%s: pid=%d buf=%p used=%lu discard=%d\n", __FUNCTION__, DRM_CURRENTPID, - vertex.buf, vertex.used, vertex.discard); + vertex->buf, vertex->used, vertex->discard); - if (vertex.prim < 0 || vertex.prim > MACH64_PRIM_POLYGON) { - DRM_ERROR("buffer prim %d\n", vertex.prim); - return DRM_ERR(EINVAL); + if (vertex->prim < 0 || vertex->prim > MACH64_PRIM_POLYGON) { + DRM_ERROR("buffer prim %d\n", vertex->prim); + return -EINVAL; } - if (vertex.used > MACH64_BUFFER_SIZE || (vertex.used & 3) != 0) { + if (vertex->used > MACH64_BUFFER_SIZE || (vertex->used & 3) != 0) { DRM_ERROR("Invalid vertex buffer size: %lu bytes\n", - vertex.used); - return DRM_ERR(EINVAL); + vertex->used); + return -EINVAL; } if (sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; - return mach64_dma_dispatch_vertex(filp, dev, &vertex); + return mach64_dma_dispatch_vertex(dev, file_priv, vertex); } -int mach64_dma_blit(DRM_IOCTL_ARGS) +int mach64_dma_blit(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_mach64_private_t *dev_priv = dev->dev_private; drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mach64_blit_t blit; + drm_mach64_blit_t *blit = data; int ret; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_COPY_FROM_USER_IOCTL(blit, (drm_mach64_blit_t *) data, - sizeof(blit)); - - ret = mach64_dma_dispatch_blit(filp, dev, &blit); + ret = mach64_dma_dispatch_blit(dev, file_priv, blit); /* Make sure we restore the 3D state next time. */ @@ -864,39 +861,36 @@ int mach64_dma_blit(DRM_IOCTL_ARGS) return ret; } -int mach64_get_param(DRM_IOCTL_ARGS) +int mach64_get_param(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_mach64_private_t *dev_priv = dev->dev_private; - drm_mach64_getparam_t param; + drm_mach64_getparam_t *param = data; int value; DRM_DEBUG("%s\n", __FUNCTION__); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(param, (drm_mach64_getparam_t *) data, - sizeof(param)); - - switch (param.param) { + switch (param->param) { case MACH64_PARAM_FRAMES_QUEUED: /* Needs lock since it calls mach64_ring_tick() */ - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); value = mach64_do_get_frames_queued(dev_priv); break; case MACH64_PARAM_IRQ_NR: value = dev->irq; break; default: - return DRM_ERR(EINVAL); + return -EINVAL; } - if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { + if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { DRM_ERROR("copy_to_user\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } return 0; diff --git a/shared-core/mga_dma.c b/shared-core/mga_dma.c index d48313c7..a86dd31c 100644 --- a/shared-core/mga_dma.c +++ b/shared-core/mga_dma.c @@ -46,7 +46,7 @@ #define MINIMAL_CLEANUP 0 #define FULL_CLEANUP 1 -static int mga_do_cleanup_dma(drm_device_t * dev, int full_cleanup); +static int mga_do_cleanup_dma(struct drm_device * dev, int full_cleanup); /* ================================================================ * Engine control @@ -71,7 +71,7 @@ int mga_do_wait_for_idle(drm_mga_private_t * dev_priv) DRM_ERROR("failed!\n"); DRM_INFO(" status=0x%08x\n", status); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } static int mga_do_dma_reset(drm_mga_private_t * dev_priv) @@ -224,7 +224,7 @@ void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv) #define MGA_BUFFER_FREE 0 #if MGA_FREELIST_DEBUG -static void mga_freelist_print(drm_device_t * dev) +static void mga_freelist_print(struct drm_device * dev) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *entry; @@ -245,10 +245,10 @@ static void mga_freelist_print(drm_device_t * dev) } #endif -static int mga_freelist_init(drm_device_t * dev, drm_mga_private_t * dev_priv) +static int mga_freelist_init(struct drm_device * dev, drm_mga_private_t * dev_priv) { - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; drm_mga_buf_priv_t *buf_priv; drm_mga_freelist_t *entry; int i; @@ -256,7 +256,7 @@ static int mga_freelist_init(drm_device_t * dev, drm_mga_private_t * dev_priv) dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); if (dev_priv->head == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t)); SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0); @@ -267,7 +267,7 @@ static int mga_freelist_init(drm_device_t * dev, drm_mga_private_t * dev_priv) entry = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); if (entry == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; memset(entry, 0, sizeof(drm_mga_freelist_t)); @@ -291,7 +291,7 @@ static int mga_freelist_init(drm_device_t * dev, drm_mga_private_t * dev_priv) return 0; } -static void mga_freelist_cleanup(drm_device_t * dev) +static void mga_freelist_cleanup(struct drm_device * dev) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *entry; @@ -311,10 +311,10 @@ static void mga_freelist_cleanup(drm_device_t * dev) #if 0 /* FIXME: Still needed? */ -static void mga_freelist_reset(drm_device_t * dev) +static void mga_freelist_reset(struct drm_device * dev) { drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; + struct drm_buf *buf; drm_mga_buf_priv_t *buf_priv; int i; @@ -326,7 +326,7 @@ static void mga_freelist_reset(drm_device_t * dev) } #endif -static drm_buf_t *mga_freelist_get(drm_device_t * dev) +static struct drm_buf *mga_freelist_get(struct drm_device * dev) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *next; @@ -359,7 +359,7 @@ static drm_buf_t *mga_freelist_get(drm_device_t * dev) return NULL; } -int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf) +int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; @@ -393,13 +393,13 @@ int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf) * DMA initialization, cleanup */ -int mga_driver_load(drm_device_t *dev, unsigned long flags) +int mga_driver_load(struct drm_device *dev, unsigned long flags) { drm_mga_private_t * dev_priv; dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); if (!dev_priv) - return DRM_ERR(ENOMEM); + return -ENOMEM; dev->dev_private = (void *)dev_priv; memset(dev_priv, 0, sizeof(drm_mga_private_t)); @@ -433,7 +433,7 @@ int mga_driver_load(drm_device_t *dev, unsigned long flags) * * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap */ -static int mga_do_agp_dma_bootstrap(drm_device_t * dev, +static int mga_do_agp_dma_bootstrap(struct drm_device *dev, drm_mga_dma_bootstrap_t * dma_bs) { drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private; @@ -443,11 +443,11 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, const unsigned secondary_size = dma_bs->secondary_bin_count * dma_bs->secondary_bin_size; const unsigned agp_size = (dma_bs->agp_size << 20); - drm_buf_desc_t req; - drm_agp_mode_t mode; - drm_agp_info_t info; - drm_agp_buffer_t agp_req; - drm_agp_binding_t bind_req; + struct drm_buf_desc req; + struct drm_agp_mode mode; + struct drm_agp_info info; + struct drm_agp_buffer agp_req; + struct drm_agp_binding bind_req; /* Acquire AGP. */ err = drm_agp_acquire(dev); @@ -548,7 +548,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, #ifdef __linux__ { - drm_map_list_t *_entry; + struct drm_map_list *_entry; unsigned long agp_token = 0; list_for_each_entry(_entry, &dev->maplist, head) { @@ -579,7 +579,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, DRM_ERROR("failed to ioremap agp regions! (%p, %p, %p)\n", dev_priv->warp->handle, dev_priv->primary->handle, dev->agp_buffer_map->handle); - return DRM_ERR(ENOMEM); + return -ENOMEM; } dev_priv->dma_access = MGA_PAGPXFER; @@ -603,7 +603,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev, * * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap */ -static int mga_do_pci_dma_bootstrap(drm_device_t * dev, +static int mga_do_pci_dma_bootstrap(struct drm_device * dev, drm_mga_dma_bootstrap_t * dma_bs) { drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private; @@ -611,12 +611,12 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, unsigned int primary_size; unsigned int bin_count; int err; - drm_buf_desc_t req; + struct drm_buf_desc req; if (dev->dma == NULL) { DRM_ERROR("dev->dma is NULL\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } /* Make drm_addbufs happy by not trying to create a mapping for less @@ -651,7 +651,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, if (err != 0) { DRM_ERROR("Unable to allocate primary DMA region: %d\n", err); - return DRM_ERR(ENOMEM); + return -ENOMEM; } if (dev_priv->primary->size != dma_bs->primary_size) { @@ -696,7 +696,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev, } -static int mga_do_dma_bootstrap(drm_device_t * dev, +static int mga_do_dma_bootstrap(struct drm_device * dev, drm_mga_dma_bootstrap_t * dma_bs) { const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev); @@ -762,44 +762,37 @@ static int mga_do_dma_bootstrap(drm_device_t * dev, return err; } -int mga_dma_bootstrap(DRM_IOCTL_ARGS) +int mga_dma_bootstrap(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; - drm_mga_dma_bootstrap_t bootstrap; + drm_mga_dma_bootstrap_t *bootstrap = data; int err; static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; const drm_mga_private_t * const dev_priv = (drm_mga_private_t *) dev->dev_private; - DRM_COPY_FROM_USER_IOCTL(bootstrap, - (drm_mga_dma_bootstrap_t __user *) data, - sizeof(bootstrap)); - - err = mga_do_dma_bootstrap(dev, & bootstrap); + err = mga_do_dma_bootstrap(dev, bootstrap); if (err) { mga_do_cleanup_dma(dev, FULL_CLEANUP); return err; } if (dev_priv->agp_textures != NULL) { - bootstrap.texture_handle = dev_priv->agp_textures->offset; - bootstrap.texture_size = dev_priv->agp_textures->size; + bootstrap->texture_handle = dev_priv->agp_textures->offset; + bootstrap->texture_size = dev_priv->agp_textures->size; } else { - bootstrap.texture_handle = 0; - bootstrap.texture_size = 0; + bootstrap->texture_handle = 0; + bootstrap->texture_size = 0; } - bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07]; - - DRM_COPY_TO_USER_IOCTL((drm_mga_dma_bootstrap_t __user *)data, - bootstrap, sizeof(bootstrap)); + bootstrap->agp_mode = modes[bootstrap->agp_mode & 0x07]; return 0; } -static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) +static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init) { drm_mga_private_t *dev_priv; int ret; @@ -833,7 +826,7 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) dev_priv->sarea = drm_getsarea(dev); if (!dev_priv->sarea) { DRM_ERROR("failed to find sarea!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (! dev_priv->used_new_dma_init) { @@ -844,28 +837,28 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) dev_priv->status = drm_core_findmap(dev, init->status_offset); if (!dev_priv->status) { DRM_ERROR("failed to find status page!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); if (!dev_priv->mmio) { DRM_ERROR("failed to find mmio region!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->warp = drm_core_findmap(dev, init->warp_offset); if (!dev_priv->warp) { DRM_ERROR("failed to find warp microcode region!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->primary = drm_core_findmap(dev, init->primary_offset); if (!dev_priv->primary) { DRM_ERROR("failed to find primary dma region!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); if (!dev->agp_buffer_map) { DRM_ERROR("failed to find dma buffer region!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } drm_core_ioremap(dev_priv->warp, dev); @@ -883,7 +876,7 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) ((dev->agp_buffer_map == NULL) || (dev->agp_buffer_map->handle == NULL)))) { DRM_ERROR("failed to ioremap agp regions!\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } ret = mga_warp_install_microcode(dev_priv); @@ -933,13 +926,13 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init) if (mga_freelist_init(dev, dev_priv) < 0) { DRM_ERROR("could not initialize freelist\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } return 0; } -static int mga_do_cleanup_dma(drm_device_t * dev, int full_cleanup) +static int mga_do_cleanup_dma(struct drm_device * dev, int full_cleanup) { int err = 0; DRM_DEBUG("\n"); @@ -967,8 +960,8 @@ static int mga_do_cleanup_dma(drm_device_t * dev, int full_cleanup) if (dev_priv->used_new_dma_init) { if (dev_priv->agp_handle != 0) { - drm_agp_binding_t unbind_req; - drm_agp_buffer_t free_req; + struct drm_agp_binding unbind_req; + struct drm_agp_buffer free_req; unbind_req.handle = dev_priv->agp_handle; drm_agp_unbind(dev, &unbind_req); @@ -1010,20 +1003,17 @@ static int mga_do_cleanup_dma(drm_device_t * dev, int full_cleanup) return 0; } -int mga_dma_init(DRM_IOCTL_ARGS) +int mga_dma_init(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; - drm_mga_init_t init; + drm_mga_init_t *init = data; int err; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_COPY_FROM_USER_IOCTL(init, (drm_mga_init_t __user *) data, - sizeof(init)); - - switch (init.func) { + switch (init->func) { case MGA_INIT_DMA: - err = mga_do_init_dma(dev, &init); + err = mga_do_init_dma(dev, init); if (err) { (void) mga_do_cleanup_dma(dev, FULL_CLEANUP); } @@ -1032,36 +1022,33 @@ int mga_dma_init(DRM_IOCTL_ARGS) return mga_do_cleanup_dma(dev, FULL_CLEANUP); } - return DRM_ERR(EINVAL); + return -EINVAL; } /* ================================================================ * Primary DMA stream management */ -int mga_dma_flush(DRM_IOCTL_ARGS) +int mga_dma_flush(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - drm_lock_t lock; - - LOCK_TEST_WITH_RETURN(dev, filp); + struct drm_lock *lock = data; - DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t __user *) data, - sizeof(lock)); + LOCK_TEST_WITH_RETURN(dev, file_priv); DRM_DEBUG("%s%s%s\n", - (lock.flags & _DRM_LOCK_FLUSH) ? "flush, " : "", - (lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "", - (lock.flags & _DRM_LOCK_QUIESCENT) ? "idle, " : ""); + (lock->flags & _DRM_LOCK_FLUSH) ? "flush, " : "", + (lock->flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "", + (lock->flags & _DRM_LOCK_QUIESCENT) ? "idle, " : ""); WRAP_WAIT_WITH_RETURN(dev_priv); - if (lock.flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) { + if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) { mga_do_dma_flush(dev_priv); } - if (lock.flags & _DRM_LOCK_QUIESCENT) { + if (lock->flags & _DRM_LOCK_QUIESCENT) { #if MGA_DMA_DEBUG int ret = mga_do_wait_for_idle(dev_priv); if (ret < 0) @@ -1075,12 +1062,12 @@ int mga_dma_flush(DRM_IOCTL_ARGS) } } -int mga_dma_reset(DRM_IOCTL_ARGS) +int mga_dma_reset(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); return mga_do_dma_reset(dev_priv); } @@ -1089,76 +1076,72 @@ int mga_dma_reset(DRM_IOCTL_ARGS) * DMA buffer management */ -static int mga_dma_get_buffers(DRMFILE filp, drm_device_t * dev, drm_dma_t * d) +static int mga_dma_get_buffers(struct drm_device * dev, + struct drm_file *file_priv, struct drm_dma * d) { - drm_buf_t *buf; + struct drm_buf *buf; int i; for (i = d->granted_count; i < d->request_count; i++) { buf = mga_freelist_get(dev); if (!buf) - return DRM_ERR(EAGAIN); + return -EAGAIN; - buf->filp = filp; + buf->file_priv = file_priv; if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, sizeof(buf->idx))) - return DRM_ERR(EFAULT); + return -EFAULT; if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, sizeof(buf->total))) - return DRM_ERR(EFAULT); + return -EFAULT; d->granted_count++; } return 0; } -int mga_dma_buffers(DRM_IOCTL_ARGS) +int mga_dma_buffers(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - drm_dma_t __user *argp = (void __user *)data; - drm_dma_t d; + struct drm_dma *d = data; int ret = 0; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d)); + LOCK_TEST_WITH_RETURN(dev, file_priv); /* Please don't send us buffers. */ - if (d.send_count != 0) { + if (d->send_count != 0) { DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d.send_count); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, d->send_count); + return -EINVAL; } /* We'll send you buffers. */ - if (d.request_count < 0 || d.request_count > dma->buf_count) { + if (d->request_count < 0 || d->request_count > dma->buf_count) { DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d.request_count, dma->buf_count); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, d->request_count, dma->buf_count); + return -EINVAL; } WRAP_TEST_WITH_RETURN(dev_priv); - d.granted_count = 0; + d->granted_count = 0; - if (d.request_count) { - ret = mga_dma_get_buffers(filp, dev, &d); + if (d->request_count) { + ret = mga_dma_get_buffers(dev, file_priv, d); } - DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d)); - return ret; } /** * Called just before the module is unloaded. */ -int mga_driver_unload(drm_device_t * dev) +int mga_driver_unload(struct drm_device * dev) { drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); dev->dev_private = NULL; @@ -1169,12 +1152,12 @@ int mga_driver_unload(drm_device_t * dev) /** * Called when the last opener of the device is closed. */ -void mga_driver_lastclose(drm_device_t * dev) +void mga_driver_lastclose(struct drm_device * dev) { mga_do_cleanup_dma(dev, FULL_CLEANUP); } -int mga_driver_dma_quiescent(drm_device_t * dev) +int mga_driver_dma_quiescent(struct drm_device * dev) { drm_mga_private_t *dev_priv = dev->dev_private; return mga_do_wait_for_idle(dev_priv); diff --git a/shared-core/mga_drm.h b/shared-core/mga_drm.h index 5bcdbfab..15c2dea2 100644 --- a/shared-core/mga_drm.h +++ b/shared-core/mga_drm.h @@ -181,7 +181,7 @@ typedef struct _drm_mga_sarea { /* The current cliprects, or a subset thereof. */ - drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS]; + struct drm_clip_rect boxes[MGA_NR_SAREA_CLIPRECTS]; unsigned int nbox; /* Information about the most recently used 3d drawable. The @@ -202,7 +202,7 @@ typedef struct _drm_mga_sarea { unsigned int exported_nback; int exported_back_x, exported_front_x, exported_w; int exported_back_y, exported_front_y, exported_h; - drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS]; + struct drm_clip_rect exported_boxes[MGA_NR_SAREA_CLIPRECTS]; /* Counters for aging textures and for client-side throttling. */ @@ -216,7 +216,7 @@ typedef struct _drm_mga_sarea { /* LRU lists for texture memory in agp space and on the card. */ - drm_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS + 1]; + struct drm_tex_region texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS + 1]; unsigned int texAge[MGA_NR_TEX_HEAPS]; /* Mechanism to validate card state. diff --git a/shared-core/mga_drv.h b/shared-core/mga_drv.h index 4764edab..b961155a 100644 --- a/shared-core/mga_drv.h +++ b/shared-core/mga_drv.h @@ -65,7 +65,7 @@ typedef struct drm_mga_freelist { struct drm_mga_freelist *next; struct drm_mga_freelist *prev; drm_mga_age_t age; - drm_buf_t *buf; + struct drm_buf *buf; } drm_mga_freelist_t; typedef struct { @@ -149,19 +149,24 @@ typedef struct drm_mga_private { unsigned int agp_size; } drm_mga_private_t; -extern drm_ioctl_desc_t mga_ioctls[]; +extern struct drm_ioctl_desc mga_ioctls[]; extern int mga_max_ioctl; /* mga_dma.c */ -extern int mga_dma_bootstrap(DRM_IOCTL_ARGS); -extern int mga_dma_init(DRM_IOCTL_ARGS); -extern int mga_dma_flush(DRM_IOCTL_ARGS); -extern int mga_dma_reset(DRM_IOCTL_ARGS); -extern int mga_dma_buffers(DRM_IOCTL_ARGS); -extern int mga_driver_load(drm_device_t *dev, unsigned long flags); -extern int mga_driver_unload(drm_device_t * dev); -extern void mga_driver_lastclose(drm_device_t * dev); -extern int mga_driver_dma_quiescent(drm_device_t * dev); +extern int mga_dma_bootstrap(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mga_dma_init(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mga_dma_flush(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mga_dma_reset(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mga_dma_buffers(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int mga_driver_load(struct drm_device *dev, unsigned long flags); +extern int mga_driver_unload(struct drm_device * dev); +extern void mga_driver_lastclose(struct drm_device * dev); +extern int mga_driver_dma_quiescent(struct drm_device * dev); extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv); @@ -169,7 +174,7 @@ extern void mga_do_dma_flush(drm_mga_private_t * dev_priv); extern void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv); extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv); -extern int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf); +extern int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf); /* mga_warp.c */ extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv); @@ -177,14 +182,15 @@ extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); extern int mga_warp_init(drm_mga_private_t * dev_priv); /* mga_irq.c */ -extern int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence); -extern int mga_enable_vblank(drm_device_t *dev, int crtc); -extern void mga_disable_vblank(drm_device_t *dev, int crtc); -extern u32 mga_get_vblank_counter(drm_device_t *dev, int crtc); +extern int mga_enable_vblank(struct drm_device *dev, int crtc); +extern void mga_disable_vblank(struct drm_device *dev, int crtc); +extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); +extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence); +extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence); extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); -extern void mga_driver_irq_preinstall(drm_device_t * dev); -extern int mga_driver_irq_postinstall(drm_device_t * dev); -extern void mga_driver_irq_uninstall(drm_device_t * dev); +extern void mga_driver_irq_preinstall(struct drm_device * dev); +extern int mga_driver_irq_postinstall(struct drm_device * dev); +extern void mga_driver_irq_uninstall(struct drm_device * dev); extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); @@ -248,7 +254,7 @@ do { \ dev_priv->prim.high_mark ) { \ if ( MGA_DMA_DEBUG ) \ DRM_INFO( "%s: wrap...\n", __FUNCTION__ ); \ - return DRM_ERR(EBUSY); \ + return -EBUSY; \ } \ } \ } while (0) @@ -259,7 +265,7 @@ do { \ if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { \ if ( MGA_DMA_DEBUG ) \ DRM_INFO( "%s: wrap...\n", __FUNCTION__ ); \ - return DRM_ERR(EBUSY); \ + return -EBUSY; \ } \ mga_do_dma_wrap_end( dev_priv ); \ } \ diff --git a/shared-core/mga_irq.c b/shared-core/mga_irq.c index a49a9b6e..0d4b473c 100644 --- a/shared-core/mga_irq.c +++ b/shared-core/mga_irq.c @@ -36,7 +36,7 @@ #include "mga_drm.h" #include "mga_drv.h" -u32 mga_get_vblank_counter(drm_device_t *dev, int crtc) +u32 mga_get_vblank_counter(struct drm_device *dev, int crtc) { const drm_mga_private_t *const dev_priv = (drm_mga_private_t *) dev->dev_private; @@ -52,7 +52,7 @@ u32 mga_get_vblank_counter(drm_device_t *dev, int crtc) irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) { - drm_device_t *dev = (drm_device_t *) arg; + struct drm_device *dev = (struct drm_device *) arg; drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; int status; int handled = 0; @@ -90,8 +90,7 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) return (handled) ? IRQ_HANDLED : IRQ_NONE; } - -int mga_enable_vblank(drm_device_t *dev, int crtc) +int mga_enable_vblank(struct drm_device *dev, int crtc) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; @@ -106,7 +105,7 @@ int mga_enable_vblank(drm_device_t *dev, int crtc) } -void mga_disable_vblank(drm_device_t *dev, int crtc) +void mga_disable_vblank(struct drm_device *dev, int crtc) { if (crtc != 0) { DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", @@ -121,8 +120,7 @@ void mga_disable_vblank(drm_device_t *dev, int crtc) /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ } - -int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence) +int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; unsigned int cur_fence; @@ -141,7 +139,7 @@ int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence) return ret; } -void mga_driver_irq_preinstall(drm_device_t * dev) +void mga_driver_irq_preinstall(struct drm_device * dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; @@ -151,7 +149,7 @@ void mga_driver_irq_preinstall(drm_device_t * dev) MGA_WRITE(MGA_ICLEAR, ~0); } -int mga_driver_irq_postinstall(drm_device_t * dev) +int mga_driver_irq_postinstall(struct drm_device * dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; int ret; @@ -169,8 +167,7 @@ int mga_driver_irq_postinstall(drm_device_t * dev) return 0; } - -void mga_driver_irq_uninstall(drm_device_t * dev) +void mga_driver_irq_uninstall(struct drm_device * dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; if (!dev_priv) diff --git a/shared-core/mga_state.c b/shared-core/mga_state.c index 8e5cb334..70b7caa0 100644 --- a/shared-core/mga_state.c +++ b/shared-core/mga_state.c @@ -43,7 +43,7 @@ */ static void mga_emit_clip_rect(drm_mga_private_t * dev_priv, - drm_clip_rect_t * box) + struct drm_clip_rect * box) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; @@ -416,7 +416,7 @@ static int mga_verify_context(drm_mga_private_t * dev_priv) ctx->dstorg, dev_priv->front_offset, dev_priv->back_offset); ctx->dstorg = 0; - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; @@ -435,7 +435,7 @@ static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit) if (org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI)) { DRM_ERROR("*** bad TEXORG: 0x%x, unit %d\n", tex->texorg, unit); tex->texorg = 0; - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; @@ -477,13 +477,13 @@ static int mga_verify_iload(drm_mga_private_t * dev_priv, dstorg + length > (dev_priv->texture_offset + dev_priv->texture_size)) { DRM_ERROR("*** bad iload DSTORG: 0x%x\n", dstorg); - return DRM_ERR(EINVAL); + return -EINVAL; } if (length & MGA_ILOAD_MASK) { DRM_ERROR("*** bad iload length: 0x%x\n", length & MGA_ILOAD_MASK); - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; @@ -495,7 +495,7 @@ static int mga_verify_blit(drm_mga_private_t * dev_priv, if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) || (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM)) { DRM_ERROR("*** bad blit: src=0x%x dst=0x%x\n", srcorg, dstorg); - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; } @@ -504,12 +504,12 @@ static int mga_verify_blit(drm_mga_private_t * dev_priv, * */ -static void mga_dma_dispatch_clear(drm_device_t * dev, drm_mga_clear_t * clear) +static void mga_dma_dispatch_clear(struct drm_device * dev, drm_mga_clear_t * clear) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - drm_clip_rect_t *pbox = sarea_priv->boxes; + struct drm_clip_rect *pbox = sarea_priv->boxes; int nbox = sarea_priv->nbox; int i; DMA_LOCALS; @@ -525,7 +525,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, drm_mga_clear_t * clear) ADVANCE_DMA(); for (i = 0; i < nbox; i++) { - drm_clip_rect_t *box = &pbox[i]; + struct drm_clip_rect *box = &pbox[i]; u32 height = box->y2 - box->y1; DRM_DEBUG(" from=%d,%d to=%d,%d\n", @@ -594,12 +594,12 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, drm_mga_clear_t * clear) FLUSH_DMA(); } -static void mga_dma_dispatch_swap(drm_device_t * dev) +static void mga_dma_dispatch_swap(struct drm_device * dev) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - drm_clip_rect_t *pbox = sarea_priv->boxes; + struct drm_clip_rect *pbox = sarea_priv->boxes; int nbox = sarea_priv->nbox; int i; DMA_LOCALS; @@ -626,7 +626,7 @@ static void mga_dma_dispatch_swap(drm_device_t * dev) MGA_DWGCTL, MGA_DWGCTL_COPY); for (i = 0; i < nbox; i++) { - drm_clip_rect_t *box = &pbox[i]; + struct drm_clip_rect *box = &pbox[i]; u32 height = box->y2 - box->y1; u32 start = box->y1 * dev_priv->front_pitch; @@ -651,7 +651,7 @@ static void mga_dma_dispatch_swap(drm_device_t * dev) DRM_DEBUG("%s... done.\n", __FUNCTION__); } -static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf) +static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; @@ -698,7 +698,7 @@ static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf) FLUSH_DMA(); } -static void mga_dma_dispatch_indices(drm_device_t * dev, drm_buf_t * buf, +static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * buf, unsigned int start, unsigned int end) { drm_mga_private_t *dev_priv = dev->dev_private; @@ -747,7 +747,7 @@ static void mga_dma_dispatch_indices(drm_device_t * dev, drm_buf_t * buf, /* This copies a 64 byte aligned agp region to the frambuffer with a * standard blit, the ioctl needs to do checking. */ -static void mga_dma_dispatch_iload(drm_device_t * dev, drm_buf_t * buf, +static void mga_dma_dispatch_iload(struct drm_device * dev, struct drm_buf * buf, unsigned int dstorg, unsigned int length) { drm_mga_private_t *dev_priv = dev->dev_private; @@ -800,12 +800,12 @@ static void mga_dma_dispatch_iload(drm_device_t * dev, drm_buf_t * buf, FLUSH_DMA(); } -static void mga_dma_dispatch_blit(drm_device_t * dev, drm_mga_blit_t * blit) +static void mga_dma_dispatch_blit(struct drm_device * dev, drm_mga_blit_t * blit) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - drm_clip_rect_t *pbox = sarea_priv->boxes; + struct drm_clip_rect *pbox = sarea_priv->boxes; int nbox = sarea_priv->nbox; u32 scandir = 0, i; DMA_LOCALS; @@ -865,24 +865,20 @@ static void mga_dma_dispatch_blit(drm_device_t * dev, drm_mga_blit_t * blit) * */ -static int mga_dma_clear(DRM_IOCTL_ARGS) +static int mga_dma_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_clear_t clear; + drm_mga_clear_t *clear = data; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(clear, (drm_mga_clear_t __user *) data, - sizeof(clear)); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; WRAP_TEST_WITH_RETURN(dev_priv); - mga_dma_dispatch_clear(dev, &clear); + mga_dma_dispatch_clear(dev, clear); /* Make sure we restore the 3D state next time. */ @@ -891,13 +887,12 @@ static int mga_dma_clear(DRM_IOCTL_ARGS) return 0; } -static int mga_dma_swap(DRM_IOCTL_ARGS) +static int mga_dma_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; @@ -913,37 +908,32 @@ static int mga_dma_swap(DRM_IOCTL_ARGS) return 0; } -static int mga_dma_vertex(DRM_IOCTL_ARGS) +static int mga_dma_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; drm_mga_buf_priv_t *buf_priv; - drm_mga_vertex_t vertex; - - LOCK_TEST_WITH_RETURN(dev, filp); + drm_mga_vertex_t *vertex = data; - DRM_COPY_FROM_USER_IOCTL(vertex, - (drm_mga_vertex_t __user *) data, - sizeof(vertex)); + LOCK_TEST_WITH_RETURN(dev, file_priv); - if (vertex.idx < 0 || vertex.idx > dma->buf_count) - return DRM_ERR(EINVAL); - buf = dma->buflist[vertex.idx]; + if (vertex->idx < 0 || vertex->idx > dma->buf_count) + return -EINVAL; + buf = dma->buflist[vertex->idx]; buf_priv = buf->dev_private; - buf->used = vertex.used; - buf_priv->discard = vertex.discard; + buf->used = vertex->used; + buf_priv->discard = vertex->discard; if (!mga_verify_state(dev_priv)) { - if (vertex.discard) { + if (vertex->discard) { if (buf_priv->dispatched == 1) AGE_BUFFER(buf_priv); buf_priv->dispatched = 0; mga_freelist_put(dev, buf); } - return DRM_ERR(EINVAL); + return -EINVAL; } WRAP_TEST_WITH_RETURN(dev_priv); @@ -953,82 +943,73 @@ static int mga_dma_vertex(DRM_IOCTL_ARGS) return 0; } -static int mga_dma_indices(DRM_IOCTL_ARGS) +static int mga_dma_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; drm_mga_buf_priv_t *buf_priv; - drm_mga_indices_t indices; - - LOCK_TEST_WITH_RETURN(dev, filp); + drm_mga_indices_t *indices = data; - DRM_COPY_FROM_USER_IOCTL(indices, - (drm_mga_indices_t __user *) data, - sizeof(indices)); + LOCK_TEST_WITH_RETURN(dev, file_priv); - if (indices.idx < 0 || indices.idx > dma->buf_count) - return DRM_ERR(EINVAL); + if (indices->idx < 0 || indices->idx > dma->buf_count) + return -EINVAL; - buf = dma->buflist[indices.idx]; + buf = dma->buflist[indices->idx]; buf_priv = buf->dev_private; - buf_priv->discard = indices.discard; + buf_priv->discard = indices->discard; if (!mga_verify_state(dev_priv)) { - if (indices.discard) { + if (indices->discard) { if (buf_priv->dispatched == 1) AGE_BUFFER(buf_priv); buf_priv->dispatched = 0; mga_freelist_put(dev, buf); } - return DRM_ERR(EINVAL); + return -EINVAL; } WRAP_TEST_WITH_RETURN(dev_priv); - mga_dma_dispatch_indices(dev, buf, indices.start, indices.end); + mga_dma_dispatch_indices(dev, buf, indices->start, indices->end); return 0; } -static int mga_dma_iload(DRM_IOCTL_ARGS) +static int mga_dma_iload(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; drm_mga_private_t *dev_priv = dev->dev_private; - drm_buf_t *buf; + struct drm_buf *buf; drm_mga_buf_priv_t *buf_priv; - drm_mga_iload_t iload; + drm_mga_iload_t *iload = data; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(iload, (drm_mga_iload_t __user *) data, - sizeof(iload)); + LOCK_TEST_WITH_RETURN(dev, file_priv); #if 0 if (mga_do_wait_for_idle(dev_priv) < 0) { if (MGA_DMA_DEBUG) DRM_INFO("%s: -EBUSY\n", __FUNCTION__); - return DRM_ERR(EBUSY); + return -EBUSY; } #endif - if (iload.idx < 0 || iload.idx > dma->buf_count) - return DRM_ERR(EINVAL); + if (iload->idx < 0 || iload->idx > dma->buf_count) + return -EINVAL; - buf = dma->buflist[iload.idx]; + buf = dma->buflist[iload->idx]; buf_priv = buf->dev_private; - if (mga_verify_iload(dev_priv, iload.dstorg, iload.length)) { + if (mga_verify_iload(dev_priv, iload->dstorg, iload->length)) { mga_freelist_put(dev, buf); - return DRM_ERR(EINVAL); + return -EINVAL; } WRAP_TEST_WITH_RETURN(dev_priv); - mga_dma_dispatch_iload(dev, buf, iload.dstorg, iload.length); + mga_dma_dispatch_iload(dev, buf, iload->dstorg, iload->length); /* Make sure we restore the 3D state next time. */ @@ -1037,28 +1018,24 @@ static int mga_dma_iload(DRM_IOCTL_ARGS) return 0; } -static int mga_dma_blit(DRM_IOCTL_ARGS) +static int mga_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_blit_t blit; + drm_mga_blit_t *blit = data; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(blit, (drm_mga_blit_t __user *) data, - sizeof(blit)); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - if (mga_verify_blit(dev_priv, blit.srcorg, blit.dstorg)) - return DRM_ERR(EINVAL); + if (mga_verify_blit(dev_priv, blit->srcorg, blit->dstorg)) + return -EINVAL; WRAP_TEST_WITH_RETURN(dev_priv); - mga_dma_dispatch_blit(dev, &blit); + mga_dma_dispatch_blit(dev, blit); /* Make sure we restore the 3D state next time. */ @@ -1067,24 +1044,20 @@ static int mga_dma_blit(DRM_IOCTL_ARGS) return 0; } -static int mga_getparam(DRM_IOCTL_ARGS) +static int mga_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_getparam_t param; + drm_mga_getparam_t *param = data; int value; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(param, (drm_mga_getparam_t __user *) data, - sizeof(param)); - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - switch (param.param) { + switch (param->param) { case MGA_PARAM_IRQ_NR: value = dev->irq; break; @@ -1092,36 +1065,35 @@ static int mga_getparam(DRM_IOCTL_ARGS) value = dev_priv->chipset; break; default: - return DRM_ERR(EINVAL); + return -EINVAL; } - if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { + if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { DRM_ERROR("copy_to_user\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } return 0; } -static int mga_set_fence(DRM_IOCTL_ARGS) +static int mga_set_fence(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; - u32 temp; + u32 *fence = data; DMA_LOCALS; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - /* I would normal do this assignment in the declaration of temp, + /* I would normal do this assignment in the declaration of fence, * but dev_priv may be NULL. */ - temp = dev_priv->next_fence_to_post; + *fence = dev_priv->next_fence_to_post; dev_priv->next_fence_to_post++; BEGIN_DMA(1); @@ -1131,47 +1103,40 @@ static int mga_set_fence(DRM_IOCTL_ARGS) MGA_SOFTRAP, 0x00000000); ADVANCE_DMA(); - DRM_COPY_TO_USER_IOCTL((u32 __user *)data, temp, sizeof(u32)); - return 0; } -static int mga_wait_fence(DRM_IOCTL_ARGS) +static int mga_wait_fence(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; - u32 fence; + u32 *fence = data; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(fence, (u32 __user *) data, sizeof(u32)); - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - mga_driver_fence_wait(dev, & fence); - - DRM_COPY_TO_USER_IOCTL((u32 __user *)data, fence, sizeof(u32)); + mga_driver_fence_wait(dev, fence); return 0; } -drm_ioctl_desc_t mga_ioctls[] = { - [DRM_IOCTL_NR(DRM_MGA_INIT)] = {mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_MGA_FLUSH)] = {mga_dma_flush, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_RESET)] = {mga_dma_reset, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_SWAP)] = {mga_dma_swap, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_CLEAR)] = {mga_dma_clear, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_VERTEX)] = {mga_dma_vertex, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_INDICES)] = {mga_dma_indices, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_ILOAD)] = {mga_dma_iload, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_BLIT)] = {mga_dma_blit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_GETPARAM)] = {mga_getparam, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_SET_FENCE)] = {mga_set_fence, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_WAIT_FENCE)] = {mga_wait_fence, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_MGA_DMA_BOOTSTRAP)] = {mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, +struct drm_ioctl_desc mga_ioctls[] = { + DRM_IOCTL_DEF(DRM_MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_MGA_FLUSH, mga_dma_flush, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MGA_RESET, mga_dma_reset, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MGA_SWAP, mga_dma_swap, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MGA_CLEAR, mga_dma_clear, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MGA_VERTEX, mga_dma_vertex, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MGA_INDICES, mga_dma_indices, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MGA_ILOAD, mga_dma_iload, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MGA_BLIT, mga_dma_blit, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MGA_GETPARAM, mga_getparam, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MGA_SET_FENCE, mga_set_fence, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), + DRM_IOCTL_DEF(DRM_MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), }; diff --git a/shared-core/mga_warp.c b/shared-core/mga_warp.c index 05ed8058..9a44bddb 100644 --- a/shared-core/mga_warp.c +++ b/shared-core/mga_warp.c @@ -146,7 +146,7 @@ int mga_warp_install_microcode(drm_mga_private_t * dev_priv) if (size > dev_priv->warp->size) { DRM_ERROR("microcode too large! (%u > %lu)\n", size, dev_priv->warp->size); - return DRM_ERR(ENOMEM); + return -ENOMEM; } switch (dev_priv->chipset) { @@ -156,7 +156,7 @@ int mga_warp_install_microcode(drm_mga_private_t * dev_priv) case MGA_CARD_TYPE_G200: return mga_warp_install_g200_microcode(dev_priv); default: - return DRM_ERR(EINVAL); + return -EINVAL; } } @@ -182,7 +182,7 @@ int mga_warp_init(drm_mga_private_t * dev_priv) MGA_WRITE(MGA_WVRTXSZ, 7); break; default: - return DRM_ERR(EINVAL); + return -EINVAL; } MGA_WRITE(MGA_WMISC, (MGA_WUCODECACHE_ENABLE | @@ -191,7 +191,7 @@ int mga_warp_init(drm_mga_private_t * dev_priv) if (wmisc != WMISC_EXPECTED) { DRM_ERROR("WARP engine config failed! 0x%x != 0x%x\n", wmisc, WMISC_EXPECTED); - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; diff --git a/shared-core/nouveau_dma.c b/shared-core/nouveau_dma.c new file mode 100644 index 00000000..b33df588 --- /dev/null +++ b/shared-core/nouveau_dma.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_dma.h" + +/* FIXME : should go into a nouveau_drm.h define ? + * (it's shared between DRI & DDX & DRM) + */ +#define SKIPS 8 + +int +nouveau_dma_channel_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_drm_channel *dchan = &dev_priv->channel; + struct nouveau_gpuobj *gpuobj = NULL; + struct mem_block *pushbuf; + int grclass, ret, i; + + DRM_DEBUG("\n"); + + pushbuf = nouveau_mem_alloc(dev, 0, 0x8000, + NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, + (struct drm_file *)-2); + if (!pushbuf) { + DRM_ERROR("Failed to allocate DMA push buffer\n"); + return -ENOMEM; + } + + /* Allocate channel */ + ret = nouveau_fifo_alloc(dev, &dchan->chan, (struct drm_file *)-2, + pushbuf, NvDmaFB, NvDmaTT); + if (ret) { + DRM_ERROR("Error allocating GPU channel: %d\n", ret); + return ret; + } + DRM_DEBUG("Using FIFO channel %d\n", dchan->chan->id); + + /* Map push buffer */ + drm_core_ioremap(dchan->chan->pushbuf_mem->map, dev); + if (!dchan->chan->pushbuf_mem->map->handle) { + DRM_ERROR("Failed to ioremap push buffer\n"); + return -EINVAL; + } + dchan->pushbuf = (void*)dchan->chan->pushbuf_mem->map->handle; + + /* Initialise DMA vars */ + dchan->max = (dchan->chan->pushbuf_mem->size >> 2) - 2; + dchan->put = dchan->chan->pushbuf_base >> 2; + dchan->cur = dchan->put; + dchan->free = dchan->max - dchan->cur; + + /* Insert NOPS for SKIPS */ + dchan->free -= SKIPS; + dchan->push_free = SKIPS; + for (i=0; i<SKIPS; i++) + OUT_RING(0); + + /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier */ + if ((ret = nouveau_notifier_alloc(dchan->chan, NvNotify0, 1, + &dchan->notify0_offset))) { + DRM_ERROR("Error allocating NvNotify0: %d\n", ret); + return ret; + } + + /* We use NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ + if (dev_priv->card_type < NV_50) grclass = NV_MEMORY_TO_MEMORY_FORMAT; + else grclass = NV50_MEMORY_TO_MEMORY_FORMAT; + if ((ret = nouveau_gpuobj_gr_new(dchan->chan, grclass, &gpuobj))) { + DRM_ERROR("Error creating NvM2MF: %d\n", ret); + return ret; + } + + if ((ret = nouveau_gpuobj_ref_add(dev, dchan->chan, NvM2MF, + gpuobj, NULL))) { + DRM_ERROR("Error referencing NvM2MF: %d\n", ret); + return ret; + } + dchan->m2mf_dma_source = NvDmaFB; + dchan->m2mf_dma_destin = NvDmaFB; + + BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1); + OUT_RING (NvM2MF); + BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_NOTIFY, 1); + OUT_RING (NvNotify0); + BEGIN_RING(NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_SOURCE, 2); + OUT_RING (dchan->m2mf_dma_source); + OUT_RING (dchan->m2mf_dma_destin); + FIRE_RING(); + + return 0; +} + +void +nouveau_dma_channel_takedown(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_drm_channel *dchan = &dev_priv->channel; + + DRM_DEBUG("\n"); + + if (dchan->chan) { + nouveau_fifo_free(dchan->chan); + dchan->chan = NULL; + } +} + +#define RING_SKIPS 8 + +#define READ_GET() ((NV_READ(NV03_FIFO_REGS_DMAGET(dchan->chan->id)) - \ + dchan->chan->pushbuf_base) >> 2) +#define WRITE_PUT(val) do { \ + NV_WRITE(NV03_FIFO_REGS_DMAPUT(dchan->chan->id), \ + ((val) << 2) + dchan->chan->pushbuf_base); \ +} while(0) + +int +nouveau_dma_wait(struct drm_device *dev, int size) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_drm_channel *dchan = &dev_priv->channel; + uint32_t get; + + while (dchan->free < size) { + get = READ_GET(); + + if (dchan->put >= get) { + dchan->free = dchan->max - dchan->cur; + + if (dchan->free < size) { + dchan->push_free = 1; + OUT_RING(0x20000000|dchan->chan->pushbuf_base); + if (get <= RING_SKIPS) { + /*corner case - will be idle*/ + if (dchan->put <= RING_SKIPS) + WRITE_PUT(RING_SKIPS + 1); + + do { + get = READ_GET(); + } while (get <= RING_SKIPS); + } + + WRITE_PUT(RING_SKIPS); + dchan->cur = dchan->put = RING_SKIPS; + dchan->free = get - (RING_SKIPS + 1); + } + } else { + dchan->free = get - dchan->cur - 1; + } + } + + return 0; +} + diff --git a/shared-core/nouveau_dma.h b/shared-core/nouveau_dma.h new file mode 100644 index 00000000..5e51c1c4 --- /dev/null +++ b/shared-core/nouveau_dma.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __NOUVEAU_DMA_H__ +#define __NOUVEAU_DMA_H__ + +typedef enum { + NvSubM2MF = 0, +} nouveau_subchannel_id_t; + +typedef enum { + NvM2MF = 0x80039001, + NvDmaFB = 0x8003d001, + NvDmaTT = 0x8003d002, + NvNotify0 = 0x8003d003 +} nouveau_object_handle_t; + +#define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039 +#define NV_MEMORY_TO_MEMORY_FORMAT_NAME 0x00000000 +#define NV_MEMORY_TO_MEMORY_FORMAT_SET_REF 0x00000050 +#define NV_MEMORY_TO_MEMORY_FORMAT_NOP 0x00000100 +#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 +#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE 0x00000000 +#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE_LE_AWAKEN 0x00000001 +#define NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_NOTIFY 0x00000180 +#define NV_MEMORY_TO_MEMORY_FORMAT_SET_DMA_SOURCE 0x00000184 +#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c + +#define NV50_MEMORY_TO_MEMORY_FORMAT 0x00005039 +#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK200 0x00000200 +#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK21C 0x0000021c +#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH 0x00000238 +#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH 0x0000023c + +#define BEGIN_RING(subc, mthd, cnt) do { \ + int push_size = (cnt) + 1; \ + if (dchan->push_free) { \ + DRM_ERROR("prior packet incomplete: %d\n", dchan->push_free); \ + break; \ + } \ + if (dchan->free < push_size) { \ + if (nouveau_dma_wait(dev, push_size)) { \ + DRM_ERROR("FIFO timeout\n"); \ + break; \ + } \ + } \ + dchan->free -= push_size; \ + dchan->push_free = push_size; \ + OUT_RING(((cnt)<<18) | ((subc)<<15) | mthd); \ +} while(0) + +#define OUT_RING(data) do { \ + if (dchan->push_free == 0) { \ + DRM_ERROR("no space left in packet\n"); \ + break; \ + } \ + dchan->pushbuf[dchan->cur++] = (data); \ + dchan->push_free--; \ +} while(0) + +#define FIRE_RING() do { \ + if (dchan->push_free) { \ + DRM_ERROR("packet incomplete: %d\n", dchan->push_free); \ + break; \ + } \ + if (dchan->cur != dchan->put) { \ + DRM_MEMORYBARRIER(); \ + dchan->put = dchan->cur; \ + NV_WRITE(NV03_FIFO_REGS_DMAPUT(dchan->chan->id), \ + (dchan->put<<2)); \ + } \ +} while(0) + +#endif + diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h index 1e7322e0..988d467a 100644 --- a/shared-core/nouveau_drm.h +++ b/shared-core/nouveau_drm.h @@ -25,9 +25,12 @@ #ifndef __NOUVEAU_DRM_H__ #define __NOUVEAU_DRM_H__ -#define NOUVEAU_DRM_HEADER_PATCHLEVEL 6 +#define NOUVEAU_DRM_HEADER_PATCHLEVEL 10 + +struct drm_nouveau_channel_alloc { + uint32_t fb_ctxdma_handle; + uint32_t tt_ctxdma_handle; -typedef struct drm_nouveau_fifo_alloc { int channel; uint32_t put_base; /* FIFO control regs */ @@ -36,52 +39,61 @@ typedef struct drm_nouveau_fifo_alloc { /* DMA command buffer */ drm_handle_t cmdbuf; int cmdbuf_size; -} -drm_nouveau_fifo_alloc_t; + /* Notifier memory */ + drm_handle_t notifier; + int notifier_size; +}; -typedef struct drm_nouveau_object_init { +struct drm_nouveau_channel_free { + int channel; +}; + +struct drm_nouveau_grobj_alloc { int channel; uint32_t handle; int class; -} -drm_nouveau_object_init_t; +}; #define NOUVEAU_MEM_ACCESS_RO 1 #define NOUVEAU_MEM_ACCESS_WO 2 #define NOUVEAU_MEM_ACCESS_RW 3 -typedef struct drm_nouveau_dma_object_init { +struct drm_nouveau_notifierobj_alloc { int channel; uint32_t handle; - int class; - int access; - int target; + int count; + uint32_t offset; - int size; -} -drm_nouveau_dma_object_init_t; +}; + +struct drm_nouveau_gpuobj_free { + int channel; + uint32_t handle; +}; #define NOUVEAU_MEM_FB 0x00000001 #define NOUVEAU_MEM_AGP 0x00000002 #define NOUVEAU_MEM_FB_ACCEPTABLE 0x00000004 #define NOUVEAU_MEM_AGP_ACCEPTABLE 0x00000008 -#define NOUVEAU_MEM_PINNED 0x00000010 -#define NOUVEAU_MEM_USER_BACKED 0x00000020 -#define NOUVEAU_MEM_MAPPED 0x00000040 -#define NOUVEAU_MEM_INSTANCE 0x00000080 /* internal */ - -typedef struct drm_nouveau_mem_alloc { +#define NOUVEAU_MEM_PCI 0x00000010 +#define NOUVEAU_MEM_PCI_ACCEPTABLE 0x00000020 +#define NOUVEAU_MEM_PINNED 0x00000040 +#define NOUVEAU_MEM_USER_BACKED 0x00000080 +#define NOUVEAU_MEM_MAPPED 0x00000100 +#define NOUVEAU_MEM_INSTANCE 0x00000200 /* internal */ +#define NOUVEAU_MEM_NOTIFIER 0x00000400 /* internal */ + +struct drm_nouveau_mem_alloc { int flags; int alignment; uint64_t size; // in bytes - uint64_t region_offset; -} -drm_nouveau_mem_alloc_t; + uint64_t offset; + drm_handle_t map_handle; +}; -typedef struct drm_nouveau_mem_free { - uint64_t region_offset; +struct drm_nouveau_mem_free { + uint64_t offset; int flags; -} -drm_nouveau_mem_free_t; +}; /* FIXME : maybe unify {GET,SET}PARAMs */ #define NOUVEAU_GETPARAM_PCI_VENDOR 3 @@ -91,34 +103,29 @@ drm_nouveau_mem_free_t; #define NOUVEAU_GETPARAM_AGP_PHYSICAL 7 #define NOUVEAU_GETPARAM_FB_SIZE 8 #define NOUVEAU_GETPARAM_AGP_SIZE 9 -typedef struct drm_nouveau_getparam { +#define NOUVEAU_GETPARAM_PCI_PHYSICAL 10 +#define NOUVEAU_GETPARAM_CHIPSET_ID 11 +struct drm_nouveau_getparam { uint64_t param; uint64_t value; -} -drm_nouveau_getparam_t; +}; #define NOUVEAU_SETPARAM_CMDBUF_LOCATION 1 #define NOUVEAU_SETPARAM_CMDBUF_SIZE 2 -typedef struct drm_nouveau_setparam { +struct drm_nouveau_setparam { uint64_t param; uint64_t value; -} -drm_nouveau_setparam_t; +}; enum nouveau_card_type { NV_UNKNOWN =0, - NV_01 =1, - NV_03 =3, NV_04 =4, NV_05 =5, NV_10 =10, - NV_11 =10, - NV_15 =10, + NV_11 =11, NV_17 =17, NV_20 =20, - NV_25 =20, NV_30 =30, - NV_34 =30, NV_40 =40, NV_44 =44, NV_50 =50, @@ -133,20 +140,22 @@ enum nouveau_bus_type { #define NOUVEAU_MAX_SAREA_CLIPRECTS 16 -typedef struct drm_nouveau_sarea { +struct drm_nouveau_sarea { /* the cliprects */ - drm_clip_rect_t boxes[NOUVEAU_MAX_SAREA_CLIPRECTS]; + struct drm_clip_rect boxes[NOUVEAU_MAX_SAREA_CLIPRECTS]; unsigned int nbox; -} -drm_nouveau_sarea_t; - -#define DRM_NOUVEAU_FIFO_ALLOC 0x00 -#define DRM_NOUVEAU_OBJECT_INIT 0x01 -#define DRM_NOUVEAU_DMA_OBJECT_INIT 0x02 -#define DRM_NOUVEAU_MEM_ALLOC 0x03 -#define DRM_NOUVEAU_MEM_FREE 0x04 -#define DRM_NOUVEAU_GETPARAM 0x05 -#define DRM_NOUVEAU_SETPARAM 0x06 +}; + +#define DRM_NOUVEAU_CARD_INIT 0x00 +#define DRM_NOUVEAU_GETPARAM 0x01 +#define DRM_NOUVEAU_SETPARAM 0x02 +#define DRM_NOUVEAU_CHANNEL_ALLOC 0x03 +#define DRM_NOUVEAU_CHANNEL_FREE 0x04 +#define DRM_NOUVEAU_GROBJ_ALLOC 0x05 +#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x06 +#define DRM_NOUVEAU_GPUOBJ_FREE 0x07 +#define DRM_NOUVEAU_MEM_ALLOC 0x08 +#define DRM_NOUVEAU_MEM_FREE 0x09 #endif /* __NOUVEAU_DRM_H__ */ diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index debee8e4..95878345 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -34,7 +34,7 @@ #define DRIVER_MAJOR 0 #define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 6 +#define DRIVER_PATCHLEVEL 10 #define NOUVEAU_FAMILY 0x0000FFFF #define NOUVEAU_FLAGS 0xFFFF0000 @@ -47,9 +47,10 @@ struct mem_block { struct mem_block *prev; uint64_t start; uint64_t size; - DRMFILE filp; /* 0: free, -1: heap, other: real files */ + struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ int flags; drm_local_map_t *map; + drm_handle_t map_handle; }; enum nouveau_flags { @@ -57,39 +58,97 @@ enum nouveau_flags { NV_NFORCE2 =0x20000000 }; -struct nouveau_object -{ - struct nouveau_object *next; - struct nouveau_object *prev; - int channel; +#define NVOBJ_ENGINE_SW 0 +#define NVOBJ_ENGINE_GR 1 +#define NVOBJ_ENGINE_INT 0xdeadbeef + +#define NVOBJ_FLAG_ALLOW_NO_REFS (1 << 0) +#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) +#define NVOBJ_FLAG_ZERO_FREE (1 << 2) +#define NVOBJ_FLAG_FAKE (1 << 3) +struct nouveau_gpuobj { + struct list_head list; + + int im_channel; + struct mem_block *im_pramin; + struct mem_block *im_backing; + int im_bound; + + uint32_t flags; + int refcount; + + uint32_t engine; + uint32_t class; - struct mem_block *instance; - uint32_t ht_loc; + void (*dtor)(struct drm_device *, struct nouveau_gpuobj *); + void *priv; +}; + +struct nouveau_gpuobj_ref { + struct list_head list; + + struct nouveau_gpuobj *gpuobj; + uint32_t instance; - uint32_t handle; - int class; - int engine; + int channel; + int handle; }; -struct nouveau_fifo +struct nouveau_channel { - int used; + struct drm_device *dev; + int id; + /* owner of this fifo */ - DRMFILE filp; + struct drm_file *file_priv; /* mapping of the fifo itself */ drm_local_map_t *map; /* mapping of the regs controling the fifo */ drm_local_map_t *regs; - /* dma object for the command buffer itself */ - struct mem_block *cmdbuf_mem; - struct nouveau_object *cmdbuf_obj; - /* PGRAPH context, for cards that keep it in RAMIN */ - struct mem_block *ramin_grctx; - /* objects belonging to this fifo */ - struct nouveau_object *objs; - - /* XXX dynamic alloc ? */ - uint32_t pgraph_ctx [340]; + + /* DMA push buffer */ + struct nouveau_gpuobj_ref *pushbuf; + struct mem_block *pushbuf_mem; + uint32_t pushbuf_base; + + /* Notifier memory */ + struct mem_block *notifier_block; + struct mem_block *notifier_heap; + drm_local_map_t *notifier_map; + + /* PFIFO context */ + struct nouveau_gpuobj_ref *ramfc; + + /* PGRAPH context */ + /* XXX may be merge 2 pointers as private data ??? */ + struct nouveau_gpuobj_ref *ramin_grctx; + void *pgraph_ctx; + + /* NV50 VM */ + struct nouveau_gpuobj *vm_pd; + struct nouveau_gpuobj_ref *vm_gart_pt; + + /* Objects */ + struct nouveau_gpuobj_ref *ramin; /* Private instmem */ + struct mem_block *ramin_heap; /* Private PRAMIN heap */ + struct nouveau_gpuobj_ref *ramht; /* Hash table */ + struct list_head ramht_refs; /* Objects referenced by RAMHT */ +}; + +struct nouveau_drm_channel { + struct nouveau_channel *chan; + + /* DMA state */ + int max, put, cur, free; + int push_free; + volatile uint32_t *pushbuf; + + /* Notifiers */ + uint32_t notify0_offset; + + /* Buffer moves */ + uint32_t m2mf_dma_source; + uint32_t m2mf_dma_destin; }; struct nouveau_config { @@ -99,34 +158,73 @@ struct nouveau_config { } cmdbuf; }; -struct nouveau_engine_func { - struct { - int (*Init)(drm_device_t *dev); - void (*Takedown)(drm_device_t *dev); - } Mc; +struct nouveau_instmem_engine { + void *priv; - struct { - int (*Init)(drm_device_t *dev); - void (*Takedown)(drm_device_t *dev); - } Timer; + int (*init)(struct drm_device *dev); + void (*takedown)(struct drm_device *dev); - struct { - int (*Init)(drm_device_t *dev); - void (*Takedown)(drm_device_t *dev); - } Fb; + int (*populate)(struct drm_device *, struct nouveau_gpuobj *, + uint32_t *size); + void (*clear)(struct drm_device *, struct nouveau_gpuobj *); + int (*bind)(struct drm_device *, struct nouveau_gpuobj *); + int (*unbind)(struct drm_device *, struct nouveau_gpuobj *); +}; - struct { - int (*Init)(drm_device_t *dev); - void (*Takedown)(drm_device_t *dev); - } Graph; +struct nouveau_mc_engine { + int (*init)(struct drm_device *dev); + void (*takedown)(struct drm_device *dev); +}; - struct { - int (*Init)(drm_device_t *dev); - void (*Takedown)(drm_device_t *dev); - } Fifo; +struct nouveau_timer_engine { + int (*init)(struct drm_device *dev); + void (*takedown)(struct drm_device *dev); + uint64_t (*read)(struct drm_device *dev); }; -typedef struct drm_nouveau_private { +struct nouveau_fb_engine { + int (*init)(struct drm_device *dev); + void (*takedown)(struct drm_device *dev); +}; + +struct nouveau_fifo_engine { + void *priv; + + int (*init)(struct drm_device *); + void (*takedown)(struct drm_device *); + + int (*create_context)(struct nouveau_channel *); + void (*destroy_context)(struct nouveau_channel *); + int (*load_context)(struct nouveau_channel *); + int (*save_context)(struct nouveau_channel *); +}; + +struct nouveau_pgraph_engine { + int (*init)(struct drm_device *); + void (*takedown)(struct drm_device *); + + int (*create_context)(struct nouveau_channel *); + void (*destroy_context)(struct nouveau_channel *); + int (*load_context)(struct nouveau_channel *); + int (*save_context)(struct nouveau_channel *); +}; + +struct nouveau_engine { + struct nouveau_instmem_engine instmem; + struct nouveau_mc_engine mc; + struct nouveau_timer_engine timer; + struct nouveau_fb_engine fb; + struct nouveau_pgraph_engine graph; + struct nouveau_fifo_engine fifo; +}; + +struct drm_nouveau_private { + enum { + NOUVEAU_CARD_INIT_DOWN, + NOUVEAU_CARD_INIT_DONE, + NOUVEAU_CARD_INIT_FAILED + } init_state; + /* the card type, takes NV_* as values */ int card_type; /* exact chipset, derived from NV_PMC_BOOT_0 */ @@ -138,12 +236,14 @@ typedef struct drm_nouveau_private { drm_local_map_t *ramin; /* NV40 onwards */ int fifo_alloc_count; - struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER]; + struct nouveau_channel *fifos[NV_MAX_FIFO_NUMBER]; - struct nouveau_engine_func Engine; + struct nouveau_engine Engine; + struct nouveau_drm_channel channel; /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ - uint32_t ramin_size; + struct nouveau_gpuobj *ramht; + uint32_t ramin_rsvd_vram; uint32_t ramht_offset; uint32_t ramht_size; uint32_t ramht_bits; @@ -155,8 +255,24 @@ typedef struct drm_nouveau_private { /* base physical adresses */ uint64_t fb_phys; uint64_t fb_available_size; - uint64_t agp_phys; - uint64_t agp_available_size; + + struct { + enum { + NOUVEAU_GART_NONE = 0, + NOUVEAU_GART_AGP, + NOUVEAU_GART_SGDMA + } type; + uint64_t aper_base; + uint64_t aper_size; + + struct nouveau_gpuobj *sg_ctxdma; + struct page *sg_dummy_page; + dma_addr_t sg_dummy_bus; + + /* nottm hack */ + struct drm_ttm_backend *sg_be; + unsigned long sg_handle; + } gart_info; /* the mtrr covering the FB */ int fb_mtrr; @@ -165,129 +281,277 @@ typedef struct drm_nouveau_private { struct mem_block *fb_heap; struct mem_block *fb_nomap_heap; struct mem_block *ramin_heap; + struct mem_block *pci_heap; /* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */ uint32_t ctx_table_size; - struct mem_block *ctx_table; + struct nouveau_gpuobj_ref *ctx_table; struct nouveau_config config; -} -drm_nouveau_private_t; + + struct list_head gpuobj_list; +}; + +#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do { \ + struct drm_nouveau_private *nv = dev->dev_private; \ + if (nv->init_state != NOUVEAU_CARD_INIT_DONE) { \ + DRM_ERROR("called without init\n"); \ + return -EINVAL; \ + } \ +} while(0) + +#define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id,cl,ch) do { \ + struct drm_nouveau_private *nv = dev->dev_private; \ + if (!nouveau_fifo_owner(dev, (cl), (id))) { \ + DRM_ERROR("pid %d doesn't own channel %d\n", \ + DRM_CURRENTPID, (id)); \ + return -EPERM; \ + } \ + (ch) = nv->fifos[(id)]; \ +} while(0) /* nouveau_state.c */ -extern void nouveau_preclose(drm_device_t * dev, DRMFILE filp); -extern int nouveau_load(struct drm_device *dev, unsigned long flags); -extern int nouveau_firstopen(struct drm_device *dev); -extern void nouveau_lastclose(struct drm_device *dev); -extern int nouveau_unload(struct drm_device *dev); -extern int nouveau_ioctl_getparam(DRM_IOCTL_ARGS); -extern int nouveau_ioctl_setparam(DRM_IOCTL_ARGS); -extern void nouveau_wait_for_idle(struct drm_device *dev); -extern int nouveau_ioctl_card_init(DRM_IOCTL_ARGS); +extern void nouveau_preclose(struct drm_device *dev, struct drm_file *); +extern int nouveau_load(struct drm_device *, unsigned long flags); +extern int nouveau_firstopen(struct drm_device *); +extern void nouveau_lastclose(struct drm_device *); +extern int nouveau_unload(struct drm_device *); +extern int nouveau_ioctl_getparam(struct drm_device *, void *data, + struct drm_file *); +extern int nouveau_ioctl_setparam(struct drm_device *, void *data, + struct drm_file *); +extern void nouveau_wait_for_idle(struct drm_device *); +extern int nouveau_card_init(struct drm_device *); +extern int nouveau_ioctl_card_init(struct drm_device *, void *data, + struct drm_file *); /* nouveau_mem.c */ -extern uint64_t nouveau_mem_fb_amount(struct drm_device *dev); -extern void nouveau_mem_release(DRMFILE filp, struct mem_block *heap); -extern int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS); -extern int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS); -extern struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, int flags, DRMFILE filp); -extern void nouveau_mem_free(struct drm_device* dev, struct mem_block*); -extern int nouveau_mem_init(struct drm_device *dev); -extern void nouveau_mem_close(struct drm_device *dev); -extern int nouveau_instmem_init(struct drm_device *dev); -extern struct mem_block* nouveau_instmem_alloc(struct drm_device *dev, - uint32_t size, uint32_t align); -extern void nouveau_instmem_free(struct drm_device *dev, - struct mem_block *block); -extern uint32_t nouveau_instmem_r32(drm_nouveau_private_t *dev_priv, - struct mem_block *mem, int index); -extern void nouveau_instmem_w32(drm_nouveau_private_t *dev_priv, - struct mem_block *mem, int index, - uint32_t val); +extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start, + uint64_t size); +extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *, + uint64_t size, int align2, + struct drm_file *); +extern void nouveau_mem_takedown(struct mem_block **heap); +extern void nouveau_mem_free_block(struct mem_block *); +extern uint64_t nouveau_mem_fb_amount(struct drm_device *); +extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); +extern int nouveau_ioctl_mem_alloc(struct drm_device *, void *data, + struct drm_file *); +extern int nouveau_ioctl_mem_free(struct drm_device *, void *data, + struct drm_file *); +extern struct mem_block* nouveau_mem_alloc(struct drm_device *, + int alignment, uint64_t size, + int flags, struct drm_file *); +extern void nouveau_mem_free(struct drm_device *dev, struct mem_block*); +extern int nouveau_mem_init(struct drm_device *); +extern void nouveau_mem_close(struct drm_device *); + +/* nouveau_notifier.c */ +extern int nouveau_notifier_init_channel(struct nouveau_channel *); +extern void nouveau_notifier_takedown_channel(struct nouveau_channel *); +extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, + int cout, uint32_t *offset); +extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data, + struct drm_file *); +extern int nouveau_ioctl_notifier_free(struct drm_device *, void *data, + struct drm_file *); /* nouveau_fifo.c */ -extern int nouveau_fifo_init(drm_device_t *dev); -extern int nouveau_fifo_number(drm_device_t *dev); -extern int nouveau_fifo_ctx_size(drm_device_t *dev); -extern void nouveau_fifo_cleanup(drm_device_t *dev, DRMFILE filp); -extern int nouveau_fifo_owner(drm_device_t *dev, DRMFILE filp, int channel); -extern void nouveau_fifo_free(drm_device_t *dev, int channel); +extern int nouveau_fifo_init(struct drm_device *); +extern int nouveau_fifo_number(struct drm_device *); +extern int nouveau_fifo_ctx_size(struct drm_device *); +extern void nouveau_fifo_cleanup(struct drm_device *, struct drm_file *); +extern int nouveau_fifo_owner(struct drm_device *, struct drm_file *, + int channel); +extern int nouveau_fifo_alloc(struct drm_device *dev, + struct nouveau_channel **chan, + struct drm_file *file_priv, + struct mem_block *pushbuf, + uint32_t fb_ctxdma, uint32_t tt_ctxdma); +extern void nouveau_fifo_free(struct nouveau_channel *); /* nouveau_object.c */ -extern void nouveau_object_cleanup(drm_device_t *dev, int channel); -extern struct nouveau_object * -nouveau_object_gr_create(drm_device_t *dev, int channel, int class); -extern struct nouveau_object * -nouveau_object_dma_create(drm_device_t *dev, int channel, int class, - uint32_t offset, uint32_t size, - int access, int target); -extern void nouveau_object_free(drm_device_t *dev, struct nouveau_object *obj); -extern int nouveau_ioctl_object_init(DRM_IOCTL_ARGS); -extern int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS); -extern uint32_t nouveau_chip_instance_get(drm_device_t *dev, struct mem_block *mem); +extern int nouveau_gpuobj_early_init(struct drm_device *); +extern int nouveau_gpuobj_init(struct drm_device *); +extern void nouveau_gpuobj_takedown(struct drm_device *); +extern void nouveau_gpuobj_late_takedown(struct drm_device *); +extern int nouveau_gpuobj_channel_init(struct nouveau_channel *, + uint32_t vram_h, uint32_t tt_h); +extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *); +extern int nouveau_gpuobj_new(struct drm_device *, struct nouveau_channel *, + int size, int align, uint32_t flags, + struct nouveau_gpuobj **); +extern int nouveau_gpuobj_del(struct drm_device *, struct nouveau_gpuobj **); +extern int nouveau_gpuobj_ref_add(struct drm_device *, struct nouveau_channel *, + uint32_t handle, struct nouveau_gpuobj *, + struct nouveau_gpuobj_ref **); +extern int nouveau_gpuobj_ref_del(struct drm_device *, + struct nouveau_gpuobj_ref **); +extern int nouveau_gpuobj_ref_find(struct nouveau_channel *, uint32_t handle, + struct nouveau_gpuobj_ref **ref_ret); +extern int nouveau_gpuobj_new_ref(struct drm_device *, + struct nouveau_channel *alloc_chan, + struct nouveau_channel *ref_chan, + uint32_t handle, int size, int align, + uint32_t flags, struct nouveau_gpuobj_ref **); +extern int nouveau_gpuobj_new_fake(struct drm_device *, + uint32_t p_offset, uint32_t b_offset, + uint32_t size, uint32_t flags, + struct nouveau_gpuobj **, + struct nouveau_gpuobj_ref**); +extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class, + uint64_t offset, uint64_t size, int access, + int target, struct nouveau_gpuobj **); +extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *, + uint64_t offset, uint64_t size, + int access, struct nouveau_gpuobj **, + uint32_t *o_ret); +extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, + struct nouveau_gpuobj **); +extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, + struct drm_file *); +extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, + struct drm_file *); /* nouveau_irq.c */ extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); -extern void nouveau_irq_preinstall(drm_device_t*); -extern void nouveau_irq_postinstall(drm_device_t*); -extern void nouveau_irq_uninstall(drm_device_t*); +extern void nouveau_irq_preinstall(struct drm_device *); +extern int nouveau_irq_postinstall(struct drm_device *); +extern void nouveau_irq_uninstall(struct drm_device *); + +/* nouveau_sgdma.c */ +extern int nouveau_sgdma_init(struct drm_device *); +extern void nouveau_sgdma_takedown(struct drm_device *); +extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset, + uint32_t *page); +extern struct drm_ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *); +extern int nouveau_sgdma_nottm_hack_init(struct drm_device *); +extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *); + +/* nouveau_dma.c */ +extern int nouveau_dma_channel_init(struct drm_device *); +extern void nouveau_dma_channel_takedown(struct drm_device *); +extern int nouveau_dma_wait(struct drm_device *, int size); /* nv04_fb.c */ -extern int nv04_fb_init(drm_device_t *dev); -extern void nv04_fb_takedown(drm_device_t *dev); +extern int nv04_fb_init(struct drm_device *); +extern void nv04_fb_takedown(struct drm_device *); /* nv10_fb.c */ -extern int nv10_fb_init(drm_device_t *dev); -extern void nv10_fb_takedown(drm_device_t *dev); +extern int nv10_fb_init(struct drm_device *); +extern void nv10_fb_takedown(struct drm_device *); /* nv40_fb.c */ -extern int nv40_fb_init(drm_device_t *dev); -extern void nv40_fb_takedown(drm_device_t *dev); +extern int nv40_fb_init(struct drm_device *); +extern void nv40_fb_takedown(struct drm_device *); + +/* nv04_fifo.c */ +extern int nv04_fifo_create_context(struct nouveau_channel *); +extern void nv04_fifo_destroy_context(struct nouveau_channel *); +extern int nv04_fifo_load_context(struct nouveau_channel *); +extern int nv04_fifo_save_context(struct nouveau_channel *); + +/* nv10_fifo.c */ +extern int nv10_fifo_create_context(struct nouveau_channel *); +extern void nv10_fifo_destroy_context(struct nouveau_channel *); +extern int nv10_fifo_load_context(struct nouveau_channel *); +extern int nv10_fifo_save_context(struct nouveau_channel *); + +/* nv40_fifo.c */ +extern int nv40_fifo_init(struct drm_device *); +extern int nv40_fifo_create_context(struct nouveau_channel *); +extern void nv40_fifo_destroy_context(struct nouveau_channel *); +extern int nv40_fifo_load_context(struct nouveau_channel *); +extern int nv40_fifo_save_context(struct nouveau_channel *); + +/* nv50_fifo.c */ +extern int nv50_fifo_init(struct drm_device *); +extern void nv50_fifo_takedown(struct drm_device *); +extern int nv50_fifo_create_context(struct nouveau_channel *); +extern void nv50_fifo_destroy_context(struct nouveau_channel *); +extern int nv50_fifo_load_context(struct nouveau_channel *); +extern int nv50_fifo_save_context(struct nouveau_channel *); /* nv04_graph.c */ -extern void nouveau_nv04_context_switch(drm_device_t *dev); -extern int nv04_graph_init(drm_device_t *dev); -extern void nv04_graph_takedown(drm_device_t *dev); -extern int nv04_graph_context_create(drm_device_t *dev, int channel); +extern void nouveau_nv04_context_switch(struct drm_device *); +extern int nv04_graph_init(struct drm_device *); +extern void nv04_graph_takedown(struct drm_device *); +extern int nv04_graph_create_context(struct nouveau_channel *); +extern void nv04_graph_destroy_context(struct nouveau_channel *); +extern int nv04_graph_load_context(struct nouveau_channel *); +extern int nv04_graph_save_context(struct nouveau_channel *); /* nv10_graph.c */ -extern void nouveau_nv10_context_switch(drm_device_t *dev); -extern int nv10_graph_init(drm_device_t *dev); -extern void nv10_graph_takedown(drm_device_t *dev); -extern int nv10_graph_context_create(drm_device_t *dev, int channel); +extern void nouveau_nv10_context_switch(struct drm_device *); +extern int nv10_graph_init(struct drm_device *); +extern void nv10_graph_takedown(struct drm_device *); +extern int nv10_graph_create_context(struct nouveau_channel *); +extern void nv10_graph_destroy_context(struct nouveau_channel *); +extern int nv10_graph_load_context(struct nouveau_channel *); +extern int nv10_graph_save_context(struct nouveau_channel *); /* nv20_graph.c */ -extern void nouveau_nv20_context_switch(drm_device_t *dev); -extern int nv20_graph_init(drm_device_t *dev); -extern void nv20_graph_takedown(drm_device_t *dev); -extern int nv20_graph_context_create(drm_device_t *dev, int channel); - -/* nv30_graph.c */ -extern int nv30_graph_init(drm_device_t *dev); -extern void nv30_graph_takedown(drm_device_t *dev); -extern int nv30_graph_context_create(drm_device_t *dev, int channel); +extern int nv20_graph_create_context(struct nouveau_channel *); +extern void nv20_graph_destroy_context(struct nouveau_channel *); +extern int nv20_graph_load_context(struct nouveau_channel *); +extern int nv20_graph_save_context(struct nouveau_channel *); +extern int nv20_graph_init(struct drm_device *); +extern void nv20_graph_takedown(struct drm_device *); +extern int nv30_graph_init(struct drm_device *); /* nv40_graph.c */ -extern int nv40_graph_init(drm_device_t *dev); -extern void nv40_graph_takedown(drm_device_t *dev); -extern int nv40_graph_context_create(drm_device_t *dev, int channel); -extern void nv40_graph_context_save_current(drm_device_t *dev); -extern void nv40_graph_context_restore(drm_device_t *dev, int channel); +extern int nv40_graph_init(struct drm_device *); +extern void nv40_graph_takedown(struct drm_device *); +extern int nv40_graph_create_context(struct nouveau_channel *); +extern void nv40_graph_destroy_context(struct nouveau_channel *); +extern int nv40_graph_load_context(struct nouveau_channel *); +extern int nv40_graph_save_context(struct nouveau_channel *); + +/* nv50_graph.c */ +extern int nv50_graph_init(struct drm_device *); +extern void nv50_graph_takedown(struct drm_device *); +extern int nv50_graph_create_context(struct nouveau_channel *); +extern void nv50_graph_destroy_context(struct nouveau_channel *); +extern int nv50_graph_load_context(struct nouveau_channel *); +extern int nv50_graph_save_context(struct nouveau_channel *); + +/* nv04_instmem.c */ +extern int nv04_instmem_init(struct drm_device *); +extern void nv04_instmem_takedown(struct drm_device *); +extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, + uint32_t *size); +extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); +extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); +extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); + +/* nv50_instmem.c */ +extern int nv50_instmem_init(struct drm_device *); +extern void nv50_instmem_takedown(struct drm_device *); +extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, + uint32_t *size); +extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); +extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); +extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); /* nv04_mc.c */ -extern int nv04_mc_init(drm_device_t *dev); -extern void nv04_mc_takedown(drm_device_t *dev); +extern int nv04_mc_init(struct drm_device *); +extern void nv04_mc_takedown(struct drm_device *); /* nv40_mc.c */ -extern int nv40_mc_init(drm_device_t *dev); -extern void nv40_mc_takedown(drm_device_t *dev); +extern int nv40_mc_init(struct drm_device *); +extern void nv40_mc_takedown(struct drm_device *); + +/* nv50_mc.c */ +extern int nv50_mc_init(struct drm_device *); +extern void nv50_mc_takedown(struct drm_device *); /* nv04_timer.c */ -extern int nv04_timer_init(drm_device_t *dev); -extern void nv04_timer_takedown(drm_device_t *dev); +extern int nv04_timer_init(struct drm_device *); +extern uint64_t nv04_timer_read(struct drm_device *); +extern void nv04_timer_takedown(struct drm_device *); -extern long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); +extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); #if defined(__powerpc__) #define NV_READ(reg) in_be32((void __iomem *)(dev_priv->mmio)->handle + (reg) ) @@ -297,8 +561,17 @@ extern long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, #define NV_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) #endif -#define INSTANCE_WR(mem,ofs,val) nouveau_instmem_w32(dev_priv,(mem),(ofs),(val)) -#define INSTANCE_RD(mem,ofs) nouveau_instmem_r32(dev_priv,(mem),(ofs)) +/* PRAMIN access */ +#if defined(__powerpc__) +#define NV_RI32(o) in_be32((void __iomem *)(dev_priv->ramin)->handle+(o)) +#define NV_WI32(o,v) out_be32((void __iomem*)(dev_priv->ramin)->handle+(o), (v)) +#else +#define NV_RI32(o) DRM_READ32(dev_priv->ramin, (o)) +#define NV_WI32(o,v) DRM_WRITE32(dev_priv->ramin, (o), (v)) +#endif + +#define INSTANCE_RD(o,i) NV_RI32((o)->im_pramin->start + ((i)<<2)) +#define INSTANCE_WR(o,i,v) NV_WI32((o)->im_pramin->start + ((i)<<2), (v)) #endif /* __NOUVEAU_DRV_H__ */ diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 8e66ca2e..f82d130b 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -29,25 +29,25 @@ /* returns the number of hw fifos */ -int nouveau_fifo_number(drm_device_t* dev) +int nouveau_fifo_number(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_nouveau_private *dev_priv=dev->dev_private; switch(dev_priv->card_type) { - case NV_03: - return 8; case NV_04: case NV_05: return 16; + case NV_50: + return 128; default: return 32; } } /* returns the size of fifo context */ -int nouveau_fifo_ctx_size(drm_device_t* dev) +int nouveau_fifo_ctx_size(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_nouveau_private *dev_priv=dev->dev_private; if (dev_priv->card_type >= NV_40) return 128; @@ -66,9 +66,9 @@ int nouveau_fifo_ctx_size(drm_device_t* dev) * voir nv_driver.c : NVPreInit */ -static int nouveau_fifo_instmem_configure(drm_device_t *dev) +static int nouveau_fifo_instmem_configure(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; NV_WRITE(NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | @@ -82,6 +82,15 @@ static int nouveau_fifo_instmem_configure(drm_device_t *dev) { case NV_50: case NV_40: + switch (dev_priv->chipset) { + case 0x47: + case 0x49: + case 0x4b: + NV_WRITE(0x2230, 1); + break; + default: + break; + } NV_WRITE(NV40_PFIFO_RAMFC, 0x30002); break; case NV_44: @@ -95,9 +104,9 @@ static int nouveau_fifo_instmem_configure(drm_device_t *dev) (1 << 16) /* 64 Bytes entry*/); /* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */ break; + case NV_11: case NV_10: case NV_04: - case NV_03: NV_WRITE(NV03_PFIFO_RAMFC, dev_priv->ramfc_offset>>8); break; } @@ -105,9 +114,9 @@ static int nouveau_fifo_instmem_configure(drm_device_t *dev) return 0; } -int nouveau_fifo_init(drm_device_t *dev) +int nouveau_fifo_init(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; int ret; NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & @@ -115,6 +124,10 @@ int nouveau_fifo_init(drm_device_t *dev) NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | NV_PMC_ENABLE_PFIFO); + /* Enable PFIFO error reporting */ + NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF); + NV_WRITE(NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF); + NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); ret = nouveau_fifo_instmem_configure(dev); @@ -181,286 +194,90 @@ int nouveau_fifo_init(drm_device_t *dev) } static int -nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) +nouveau_fifo_pushbuf_ctxdma_init(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_config *config = &dev_priv->config; - struct mem_block *cb; - struct nouveau_object *cb_dma = NULL; - int cb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE); - - /* Defaults for unconfigured values */ - if (!config->cmdbuf.location) - config->cmdbuf.location = NOUVEAU_MEM_FB; - if (!config->cmdbuf.size || config->cmdbuf.size < cb_min_size) - config->cmdbuf.size = cb_min_size; - - cb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, - config->cmdbuf.location | NOUVEAU_MEM_MAPPED, - (DRMFILE)-2); - if (!cb) { - DRM_ERROR("Couldn't allocate DMA command buffer.\n"); - return DRM_ERR(ENOMEM); - } + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct mem_block *pb = chan->pushbuf_mem; + struct nouveau_gpuobj *pushbuf = NULL; + int ret; - if (cb->flags & NOUVEAU_MEM_AGP) { - cb_dma = nouveau_object_dma_create(dev, channel, - NV_CLASS_DMA_IN_MEMORY, - cb->start - dev_priv->agp_phys, - cb->size, - NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP); + if (pb->flags & NOUVEAU_MEM_AGP) { + ret = nouveau_gpuobj_gart_dma_new(chan, pb->start, pb->size, + NV_DMA_ACCESS_RO, + &pushbuf, + &chan->pushbuf_base); + } else + if (pb->flags & NOUVEAU_MEM_PCI) { + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + pb->start, pb->size, + NV_DMA_ACCESS_RO, + NV_DMA_TARGET_PCI_NONLINEAR, + &pushbuf); + chan->pushbuf_base = 0; } else if (dev_priv->card_type != NV_04) { - cb_dma = nouveau_object_dma_create(dev, channel, - NV_CLASS_DMA_IN_MEMORY, - cb->start - drm_get_resource_start(dev, 1), - cb->size, - NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM); + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + pb->start, pb->size, + NV_DMA_ACCESS_RO, + NV_DMA_TARGET_VIDMEM, &pushbuf); + chan->pushbuf_base = 0; } else { /* NV04 cmdbuf hack, from original ddx.. not sure of it's * exact reason for existing :) PCI access to cmdbuf in * VRAM. */ - cb_dma = nouveau_object_dma_create(dev, channel, - NV_CLASS_DMA_IN_MEMORY, - cb->start, cb->size, - NV_DMA_ACCESS_RO, NV_DMA_TARGET_PCI); + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + pb->start + + drm_get_resource_start(dev, 1), + pb->size, NV_DMA_ACCESS_RO, + NV_DMA_TARGET_PCI, &pushbuf); + chan->pushbuf_base = 0; } - if (!cb_dma) { - nouveau_mem_free(dev, cb); - DRM_ERROR("Failed to alloc DMA object for command buffer\n"); - return DRM_ERR(ENOMEM); + if ((ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, + &chan->pushbuf))) { + DRM_ERROR("Error referencing push buffer ctxdma: %d\n", ret); + if (pushbuf != dev_priv->gart_info.sg_ctxdma) + nouveau_gpuobj_del(dev, &pushbuf); + return ret; } - dev_priv->fifos[channel].cmdbuf_mem = cb; - dev_priv->fifos[channel].cmdbuf_obj = cb_dma; return 0; } -#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV04_RAMFC_##offset, (val)) -static void nouveau_nv04_context_init(drm_device_t *dev, int channel) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_object *cb_obj; - uint32_t fifoctx, ctx_size = 32; - int i; - - cb_obj = dev_priv->fifos[channel].cmdbuf_obj; - - fifoctx=NV_RAMIN+dev_priv->ramfc_offset+channel*ctx_size; - - // clear the fifo context - for(i=0;i<ctx_size/4;i++) - NV_WRITE(fifoctx+4*i,0x0); - - RAMFC_WR(DMA_INSTANCE , nouveau_chip_instance_get(dev, cb_obj->instance)); - - RAMFC_WR(DMA_FETCH, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0x00000000); -} -#undef RAMFC_WR - -#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV10_RAMFC_##offset, (val)) -static void nouveau_nv10_context_init(drm_device_t *dev, int channel) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_object *cb_obj; - uint32_t fifoctx; - int ctx_size = nouveau_fifo_ctx_size(dev); - int i; - cb_obj = dev_priv->fifos[channel].cmdbuf_obj; - fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*ctx_size; - - for (i=0;i<ctx_size;i+=4) - NV_WRITE(fifoctx + i, 0); - - /* Fill entries that are seen filled in dumps of nvidia driver just - * after channel's is put into DMA mode - */ - - RAMFC_WR(DMA_INSTANCE , nouveau_chip_instance_get(dev, - cb_obj->instance)); - - RAMFC_WR(DMA_FETCH, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0x00000000); -} - -static void nouveau_nv30_context_init(drm_device_t *dev, int channel) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - struct nouveau_object *cb_obj; - uint32_t fifoctx, grctx_inst, cb_inst, ctx_size = 64; - int i; - - cb_obj = dev_priv->fifos[channel].cmdbuf_obj; - cb_inst = nouveau_chip_instance_get(dev, chan->cmdbuf_obj->instance); - grctx_inst = nouveau_chip_instance_get(dev, chan->ramin_grctx); - fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel * ctx_size; - - for (i = 0; i < ctx_size; i += 4) - NV_WRITE(fifoctx + i, 0); - - RAMFC_WR(REF_CNT, NV_READ(NV10_PFIFO_CACHE1_REF_CNT)); - RAMFC_WR(DMA_INSTANCE, cb_inst); - RAMFC_WR(DMA_STATE, NV_READ(NV04_PFIFO_CACHE1_DMA_STATE)); - RAMFC_WR(DMA_FETCH, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0x00000000); - - RAMFC_WR(ENGINE, NV_READ(NV04_PFIFO_CACHE1_ENGINE)); - RAMFC_WR(PULL1_ENGINE, NV_READ(NV04_PFIFO_CACHE1_PULL1)); - RAMFC_WR(ACQUIRE_VALUE, NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); - RAMFC_WR(ACQUIRE_TIMESTAMP, NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP)); - RAMFC_WR(ACQUIRE_TIMEOUT, NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); - RAMFC_WR(SEMAPHORE, NV_READ(NV10_PFIFO_CACHE1_SEMAPHORE)); -} - -#if 0 -static void nouveau_nv10_context_save(drm_device_t *dev) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - uint32_t fifoctx; - int channel; - - channel = NV_READ(NV03_PFIFO_CACHE1_PUSH1) & (nouveau_fifo_number(dev)-1); - fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*64; - - RAMFC_WR(DMA_PUT , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT)); - RAMFC_WR(DMA_GET , NV_READ(NV04_PFIFO_CACHE1_DMA_GET)); - RAMFC_WR(REF_CNT , NV_READ(NV10_PFIFO_CACHE1_REF_CNT)); - RAMFC_WR(DMA_INSTANCE , NV_READ(NV04_PFIFO_CACHE1_DMA_INSTANCE)); - RAMFC_WR(DMA_STATE , NV_READ(NV04_PFIFO_CACHE1_DMA_STATE)); - RAMFC_WR(DMA_FETCH , NV_READ(NV04_PFIFO_CACHE1_DMA_FETCH)); - RAMFC_WR(ENGINE , NV_READ(NV04_PFIFO_CACHE1_ENGINE)); - RAMFC_WR(PULL1_ENGINE , NV_READ(NV04_PFIFO_CACHE1_PULL1)); - RAMFC_WR(ACQUIRE_VALUE , NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); - RAMFC_WR(ACQUIRE_TIMESTAMP, NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP)); - RAMFC_WR(ACQUIRE_TIMEOUT , NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); - RAMFC_WR(SEMAPHORE , NV_READ(NV10_PFIFO_CACHE1_SEMAPHORE)); - RAMFC_WR(DMA_SUBROUTINE , NV_READ(NV10_PFIFO_CACHE1_DMA_SUBROUTINE)); -} -#endif -#undef RAMFC_WR - -#define RAMFC_WR(offset, val) NV_WRITE(fifoctx + NV40_RAMFC_##offset, (val)) -static void nouveau_nv40_context_init(drm_device_t *dev, int channel) +static struct mem_block * +nouveau_fifo_user_pushbuf_alloc(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - uint32_t fifoctx, cb_inst, grctx_inst; - int i; - - cb_inst = nouveau_chip_instance_get(dev, chan->cmdbuf_obj->instance); - grctx_inst = nouveau_chip_instance_get(dev, chan->ramin_grctx); - fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*128; - for (i=0;i<128;i+=4) - NV_WRITE(fifoctx + i, 0); - - /* Fill entries that are seen filled in dumps of nvidia driver just - * after channel's is put into DMA mode - */ - RAMFC_WR(DMA_INSTANCE , cb_inst); - RAMFC_WR(DMA_FETCH , NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0x30000000 /* no idea.. */); - RAMFC_WR(GRCTX_INSTANCE, grctx_inst); - RAMFC_WR(DMA_TIMESLICE , 0x0001FFFF); -} - -static void nouveau_nv40_context_save(drm_device_t *dev) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - uint32_t fifoctx; - int channel; - - channel = NV_READ(NV03_PFIFO_CACHE1_PUSH1) & (nouveau_fifo_number(dev)-1); - fifoctx = NV_RAMIN + dev_priv->ramfc_offset + channel*128; - - RAMFC_WR(DMA_PUT , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT)); - RAMFC_WR(DMA_GET , NV_READ(NV04_PFIFO_CACHE1_DMA_GET)); - RAMFC_WR(REF_CNT , NV_READ(NV10_PFIFO_CACHE1_REF_CNT)); - RAMFC_WR(DMA_INSTANCE , NV_READ(NV04_PFIFO_CACHE1_DMA_INSTANCE)); - RAMFC_WR(DMA_DCOUNT , NV_READ(NV10_PFIFO_CACHE1_DMA_DCOUNT)); - RAMFC_WR(DMA_STATE , NV_READ(NV04_PFIFO_CACHE1_DMA_STATE)); - RAMFC_WR(DMA_FETCH , NV_READ(NV04_PFIFO_CACHE1_DMA_FETCH)); - RAMFC_WR(ENGINE , NV_READ(NV04_PFIFO_CACHE1_ENGINE)); - RAMFC_WR(PULL1_ENGINE , NV_READ(NV04_PFIFO_CACHE1_PULL1)); - RAMFC_WR(ACQUIRE_VALUE , NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); - RAMFC_WR(ACQUIRE_TIMESTAMP, NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP)); - RAMFC_WR(ACQUIRE_TIMEOUT , NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); - RAMFC_WR(SEMAPHORE , NV_READ(NV10_PFIFO_CACHE1_SEMAPHORE)); - RAMFC_WR(DMA_SUBROUTINE , NV_READ(NV04_PFIFO_CACHE1_DMA_GET)); - RAMFC_WR(GRCTX_INSTANCE , NV_READ(NV40_PFIFO_GRCTX_INSTANCE)); - RAMFC_WR(DMA_TIMESLICE , NV_READ(NV04_PFIFO_DMA_TIMESLICE) & 0x1FFFF); - RAMFC_WR(UNK_40 , NV_READ(NV40_PFIFO_UNK32E4)); -} -#undef RAMFC_WR - -/* This function should load values from RAMFC into PFIFO, but for now - * it just clobbers PFIFO with what nouveau_fifo_alloc used to setup - * unconditionally. - */ -static void -nouveau_fifo_context_restore(drm_device_t *dev, int channel) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - uint32_t cb_inst; - - cb_inst = nouveau_chip_instance_get(dev, chan->cmdbuf_obj->instance); - - // FIXME check if we need to refill the time quota with something like NV_WRITE(0x204C, 0x0003FFFF); - - if (dev_priv->card_type >= NV_40) - NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, 0x00010000|channel); - else - NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, 0x00000100|channel); + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_config *config = &dev_priv->config; + struct mem_block *pb; + int pb_min_size = max(NV03_FIFO_SIZE,PAGE_SIZE); - NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT, 0 /*RAMFC_DMA_PUT*/); - NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET, 0 /*RAMFC_DMA_GET*/); - NV_WRITE(NV04_PFIFO_CACHE1_DMA_INSTANCE, cb_inst); - NV_WRITE(NV04_PFIFO_SIZE , 0x0000FFFF); - NV_WRITE(NV04_PFIFO_CACHE1_HASH, 0x0000FFFF); + /* Defaults for unconfigured values */ + if (!config->cmdbuf.location) + config->cmdbuf.location = NOUVEAU_MEM_FB; + if (!config->cmdbuf.size || config->cmdbuf.size < pb_min_size) + config->cmdbuf.size = pb_min_size; - NV_WRITE(NV04_PFIFO_CACHE0_PULL1, 0x00000001); - NV_WRITE(NV04_PFIFO_CACHE1_DMA_CTL, 0x00000000); - NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000); - NV_WRITE(NV04_PFIFO_CACHE1_ENGINE, 0x00000000); + pb = nouveau_mem_alloc(dev, 0, config->cmdbuf.size, + config->cmdbuf.location | NOUVEAU_MEM_MAPPED, + (struct drm_file *)-2); + if (!pb) + DRM_ERROR("Couldn't allocate DMA push buffer.\n"); - NV_WRITE(NV04_PFIFO_CACHE1_DMA_FETCH, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0x00000000); + return pb; } /* allocates and initializes a fifo for user space consumption */ -static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) +int +nouveau_fifo_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, + struct drm_file *file_priv, struct mem_block *pushbuf, + uint32_t vram_handle, uint32_t tt_handle) { int ret; - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_object *cb_obj; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; + struct nouveau_channel *chan; int channel; /* @@ -471,29 +288,47 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) * (woo, full userspace command submission !) * When there are no more contexts, you lost */ - for(channel=0; channel<nouveau_fifo_number(dev); channel++) - if (dev_priv->fifos[channel].used==0) + for(channel=0; channel<nouveau_fifo_number(dev); channel++) { + if (dev_priv->fifos[channel] == NULL) break; + } /* no more fifos. you lost. */ if (channel==nouveau_fifo_number(dev)) - return DRM_ERR(EINVAL); - (*chan_ret) = channel; + return -EINVAL; + + dev_priv->fifos[channel] = drm_calloc(1, sizeof(struct nouveau_channel), + DRM_MEM_DRIVER); + if (!dev_priv->fifos[channel]) + return -ENOMEM; + dev_priv->fifo_alloc_count++; + chan = dev_priv->fifos[channel]; + chan->dev = dev; + chan->id = channel; + chan->file_priv = file_priv; + chan->pushbuf_mem = pushbuf; DRM_INFO("Allocating FIFO number %d\n", channel); - /* that fifo is used */ - dev_priv->fifos[channel].used = 1; - dev_priv->fifos[channel].filp = filp; - /* FIFO has no objects yet */ - dev_priv->fifos[channel].objs = NULL; + /* Allocate space for per-channel fixed notifier memory */ + ret = nouveau_notifier_init_channel(chan); + if (ret) { + nouveau_fifo_free(chan); + return ret; + } + + /* Setup channel's default objects */ + ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle); + if (ret) { + nouveau_fifo_free(chan); + return ret; + } - /* allocate a command buffer, and create a dma object for the gpu */ - ret = nouveau_fifo_cmdbuf_alloc(dev, channel); + /* Create a dma object for the push buffer */ + ret = nouveau_fifo_pushbuf_ctxdma_init(chan); if (ret) { - nouveau_fifo_free(dev, channel); + nouveau_fifo_free(chan); return ret; } - cb_obj = dev_priv->fifos[channel].cmdbuf_obj; nouveau_wait_for_idle(dev); @@ -503,200 +338,215 @@ static int nouveau_fifo_alloc(drm_device_t* dev, int *chan_ret, DRMFILE filp) NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000); NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000); - /* Construct inital RAMFC for new channel */ - switch(dev_priv->card_type) - { - case NV_04: - case NV_05: - nv04_graph_context_create(dev, channel); - nouveau_nv04_context_init(dev, channel); - break; - case NV_10: - case NV_17: - nv10_graph_context_create(dev, channel); - nouveau_nv10_context_init(dev, channel); - break; - case NV_20: - ret = nv20_graph_context_create(dev, channel); - if (ret) { - nouveau_fifo_free(dev, channel); - return ret; - } - nouveau_nv10_context_init(dev, channel); - break; - case NV_30: - ret = nv30_graph_context_create(dev, channel); - if (ret) { - nouveau_fifo_free(dev, channel); - return ret; - } - nouveau_nv30_context_init(dev, channel); - break; - case NV_40: - case NV_44: - case NV_50: - ret = nv40_graph_context_create(dev, channel); - if (ret) { - nouveau_fifo_free(dev, channel); - return ret; - } - nouveau_nv40_context_init(dev, channel); - break; + /* Create a graphics context for new channel */ + ret = engine->graph.create_context(chan); + if (ret) { + nouveau_fifo_free(chan); + return ret; } - /* enable the fifo dma operation */ - NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)|(1<<channel)); + /* Construct inital RAMFC for new channel */ + ret = engine->fifo.create_context(chan); + if (ret) { + nouveau_fifo_free(chan); + return ret; + } /* setup channel's default get/put values */ - NV_WRITE(NV03_FIFO_REGS_DMAPUT(channel), 0); - NV_WRITE(NV03_FIFO_REGS_DMAGET(channel), 0); + if (dev_priv->card_type < NV_50) { + NV_WRITE(NV03_FIFO_REGS_DMAPUT(channel), chan->pushbuf_base); + NV_WRITE(NV03_FIFO_REGS_DMAGET(channel), chan->pushbuf_base); + } else { + NV_WRITE(NV50_FIFO_REGS_DMAPUT(channel), chan->pushbuf_base); + NV_WRITE(NV50_FIFO_REGS_DMAGET(channel), chan->pushbuf_base); + } /* If this is the first channel, setup PFIFO ourselves. For any * other case, the GPU will handle this when it switches contexts. */ - if (dev_priv->fifo_alloc_count == 0) { - nouveau_fifo_context_restore(dev, channel); - if (dev_priv->card_type >= NV_30) { - struct nouveau_fifo *chan; - uint32_t inst; - - chan = &dev_priv->fifos[channel]; - inst = nouveau_chip_instance_get(dev, - chan->ramin_grctx); - - /* see comments in nv40_graph_context_restore() */ - NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_SIZE, inst); - if (dev_priv->card_type >= NV_40) { - NV_WRITE(0x40032C, inst | 0x01000000); - NV_WRITE(NV40_PFIFO_GRCTX_INSTANCE, inst); - } + if (dev_priv->fifo_alloc_count == 1) { + ret = engine->fifo.load_context(chan); + if (ret) { + nouveau_fifo_free(chan); + return ret; + } + + ret = engine->graph.load_context(chan); + if (ret) { + nouveau_fifo_free(chan); + return ret; } } - NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, + NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) | 1); NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001); NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001); NV_WRITE(NV04_PFIFO_CACHE1_PULL1, 0x00000001); /* reenable the fifo caches */ - NV_WRITE(NV03_PFIFO_CACHES, 0x00000001); - - dev_priv->fifo_alloc_count++; + NV_WRITE(NV03_PFIFO_CACHES, 1); DRM_INFO("%s: initialised FIFO %d\n", __func__, channel); + *chan_ret = chan; return 0; } /* stops a fifo */ -void nouveau_fifo_free(drm_device_t* dev, int channel) +void nouveau_fifo_free(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - int i; - int ctx_size = nouveau_fifo_ctx_size(dev); + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; - chan->used = 0; - DRM_INFO("%s: freeing fifo %d\n", __func__, channel); + DRM_INFO("%s: freeing fifo %d\n", __func__, chan->id); /* disable the fifo caches */ NV_WRITE(NV03_PFIFO_CACHES, 0x00000000); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH)&(~0x1)); + NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000); + NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000); - NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<channel)); - // FIXME XXX needs more code - - /* Clean RAMFC */ - for (i=0;i<ctx_size;i+=4) { - DRM_DEBUG("RAMFC +%02x: 0x%08x\n", i, NV_READ(NV_RAMIN + - dev_priv->ramfc_offset + - channel*ctx_size + i)); - NV_WRITE(NV_RAMIN + dev_priv->ramfc_offset + - channel*ctx_size + i, 0); + /* stop the fifo, otherwise it could be running and + * it will crash when removing gpu objects */ + if (dev_priv->card_type < NV_50) { + NV_WRITE(NV03_FIFO_REGS_DMAPUT(chan->id), chan->pushbuf_base); + NV_WRITE(NV03_FIFO_REGS_DMAGET(chan->id), chan->pushbuf_base); + } else { + NV_WRITE(NV50_FIFO_REGS_DMAPUT(chan->id), chan->pushbuf_base); + NV_WRITE(NV50_FIFO_REGS_DMAGET(chan->id), chan->pushbuf_base); } + // FIXME XXX needs more code + + engine->fifo.destroy_context(chan); /* Cleanup PGRAPH state */ - if (dev_priv->card_type >= NV_40) - nouveau_instmem_free(dev, chan->ramin_grctx); - else if (dev_priv->card_type >= NV_30) { - } - else if (dev_priv->card_type >= NV_20) { - /* clear ctx table */ - INSTANCE_WR(dev_priv->ctx_table, channel, 0); - nouveau_instmem_free(dev, chan->ramin_grctx); - } + engine->graph.destroy_context(chan); /* reenable the fifo caches */ + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH, + NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) | 1); + NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001); + NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001); NV_WRITE(NV03_PFIFO_CACHES, 0x00000001); - /* Deallocate command buffer */ - if (chan->cmdbuf_mem) - nouveau_mem_free(dev, chan->cmdbuf_mem); + /* Deallocate push buffer */ + nouveau_gpuobj_ref_del(dev, &chan->pushbuf); + if (chan->pushbuf_mem) { + nouveau_mem_free(dev, chan->pushbuf_mem); + chan->pushbuf_mem = NULL; + } /* Destroy objects belonging to the channel */ - nouveau_object_cleanup(dev, channel); + nouveau_gpuobj_channel_takedown(chan); + + nouveau_notifier_takedown_channel(chan); + dev_priv->fifos[chan->id] = NULL; dev_priv->fifo_alloc_count--; + drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER); } -/* cleanups all the fifos from filp */ -void nouveau_fifo_cleanup(drm_device_t* dev, DRMFILE filp) +/* cleanups all the fifos from file_priv */ +void nouveau_fifo_cleanup(struct drm_device *dev, struct drm_file *file_priv) { + struct drm_nouveau_private *dev_priv = dev->dev_private; int i; - drm_nouveau_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("clearing FIFO enables from filp\n"); - for(i=0;i<nouveau_fifo_number(dev);i++) - if (dev_priv->fifos[i].used && dev_priv->fifos[i].filp==filp) - nouveau_fifo_free(dev,i); + DRM_DEBUG("clearing FIFO enables from file_priv\n"); + for(i = 0; i < nouveau_fifo_number(dev); i++) { + struct nouveau_channel *chan = dev_priv->fifos[i]; + + if (chan && chan->file_priv == file_priv) + nouveau_fifo_free(chan); + } } int -nouveau_fifo_owner(drm_device_t *dev, DRMFILE filp, int channel) +nouveau_fifo_owner(struct drm_device *dev, struct drm_file *file_priv, + int channel) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; if (channel >= nouveau_fifo_number(dev)) return 0; - if (dev_priv->fifos[channel].used == 0) + if (dev_priv->fifos[channel] == NULL) return 0; - return (dev_priv->fifos[channel].filp == filp); + return (dev_priv->fifos[channel]->file_priv == file_priv); } /*********************************** * ioctls wrapping the functions ***********************************/ -static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) +static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; - drm_nouveau_private_t *dev_priv = dev->dev_private; - drm_nouveau_fifo_alloc_t init; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_channel_alloc *init = data; + struct drm_map_list *entry; + struct nouveau_channel *chan; + struct mem_block *pushbuf; int res; - DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_alloc_t __user *) data, - sizeof(init)); + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + + if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) + return -EINVAL; - res = nouveau_fifo_alloc(dev, &init.channel, filp); + pushbuf = nouveau_fifo_user_pushbuf_alloc(dev); + if (!pushbuf) + return -ENOMEM; + + res = nouveau_fifo_alloc(dev, &chan, file_priv, pushbuf, + init->fb_ctxdma_handle, + init->tt_ctxdma_handle); if (res) return res; - - /* this should probably disappear in the next abi break? */ - init.put_base = 0; + init->channel = chan->id; + init->put_base = chan->pushbuf_base; /* make the fifo available to user space */ /* first, the fifo control regs */ - init.ctrl = dev_priv->mmio->offset + NV03_FIFO_REGS(init.channel); - init.ctrl_size = NV03_FIFO_REGS_SIZE; - res = drm_addmap(dev, init.ctrl, init.ctrl_size, _DRM_REGISTERS, - 0, &dev_priv->fifos[init.channel].regs); + init->ctrl = dev_priv->mmio->offset; + if (dev_priv->card_type < NV_50) { + init->ctrl += NV03_FIFO_REGS(init->channel); + init->ctrl_size = NV03_FIFO_REGS_SIZE; + } else { + init->ctrl += NV50_FIFO_REGS(init->channel); + init->ctrl_size = NV50_FIFO_REGS_SIZE; + } + res = drm_addmap(dev, init->ctrl, init->ctrl_size, _DRM_REGISTERS, + 0, &chan->regs); if (res != 0) return res; + entry = drm_find_matching_map(dev, chan->regs); + if (!entry) + return -EINVAL; + init->ctrl = entry->user_token; + /* pass back FIFO map info to the caller */ - init.cmdbuf = dev_priv->fifos[init.channel].cmdbuf_mem->start; - init.cmdbuf_size = dev_priv->fifos[init.channel].cmdbuf_mem->size; + init->cmdbuf = chan->pushbuf_mem->map_handle; + init->cmdbuf_size = chan->pushbuf_mem->size; + + /* and the notifier block */ + init->notifier = chan->notifier_block->map_handle; + init->notifier_size = chan->notifier_block->size; + + return 0; +} + +static int nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_nouveau_channel_free *cfree = data; + struct nouveau_channel *chan; + + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan); - DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_alloc_t __user *)data, - init, sizeof(init)); + nouveau_fifo_free(chan); return 0; } @@ -704,14 +554,17 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS) * finally, the ioctl table ***********************************/ -drm_ioctl_desc_t nouveau_ioctls[] = { - [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_ALLOC)] = {nouveau_ioctl_fifo_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_NOUVEAU_OBJECT_INIT)] = {nouveau_ioctl_object_init, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_NOUVEAU_DMA_OBJECT_INIT)] = {nouveau_ioctl_dma_object_init, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_ALLOC)] = {nouveau_ioctl_mem_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_FREE)] = {nouveau_ioctl_mem_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_NOUVEAU_GETPARAM)] = {nouveau_ioctl_getparam, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_NOUVEAU_SETPARAM)] = {nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, +struct drm_ioctl_desc nouveau_ioctls[] = { + DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, 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_FREE, nouveau_ioctl_mem_free, DRM_AUTH), }; int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 8de6e705..e4b76766 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -35,370 +35,378 @@ #include "nouveau_drm.h" #include "nouveau_drv.h" #include "nouveau_reg.h" +#include "nouveau_swmthd.h" -void nouveau_irq_preinstall(drm_device_t *dev) +void +nouveau_irq_preinstall(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; - DRM_DEBUG("IRQ: preinst\n"); - - if (!dev_priv) { - DRM_ERROR("AIII, no dev_priv\n"); - return; - } - if (!dev_priv->mmio) { - DRM_ERROR("AIII, no dev_priv->mmio\n"); - return; - } - - /* Disable/Clear PFIFO interrupts */ - NV_WRITE(NV03_PFIFO_INTR_EN_0, 0); - NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF); - /* Disable/Clear PGRAPH interrupts */ - if (dev_priv->card_type<NV_40) - NV_WRITE(NV03_PGRAPH_INTR_EN, 0); - else - NV_WRITE(NV40_PGRAPH_INTR_EN, 0); - NV_WRITE(NV03_PGRAPH_INTR, 0xFFFFFFFF); -#if 0 - /* Disable/Clear CRTC0/1 interrupts */ - NV_WRITE(NV_CRTC0_INTEN, 0); - NV_WRITE(NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK); - NV_WRITE(NV_CRTC1_INTEN, 0); - NV_WRITE(NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK); -#endif /* Master disable */ NV_WRITE(NV03_PMC_INTR_EN_0, 0); } -void nouveau_irq_postinstall(drm_device_t *dev) +int +nouveau_irq_postinstall(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - - if (!dev_priv) { - DRM_ERROR("AIII, no dev_priv\n"); - return; - } - if (!dev_priv->mmio) { - DRM_ERROR("AIII, no dev_priv->mmio\n"); - return; - } - - DRM_DEBUG("IRQ: postinst\n"); - - /* Enable PFIFO error reporting */ - NV_WRITE(NV03_PFIFO_INTR_EN_0 , - NV_PFIFO_INTR_CACHE_ERROR | - NV_PFIFO_INTR_RUNOUT | - NV_PFIFO_INTR_RUNOUT_OVERFLOW | - NV_PFIFO_INTR_DMA_PUSHER | - NV_PFIFO_INTR_DMA_PT | - NV_PFIFO_INTR_SEMAPHORE | - NV_PFIFO_INTR_ACQUIRE_TIMEOUT - ); - NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF); - - /* Enable PGRAPH interrupts */ - if (dev_priv->card_type<NV_40) - NV_WRITE(NV03_PGRAPH_INTR_EN, - NV_PGRAPH_INTR_NOTIFY | - NV_PGRAPH_INTR_MISSING_HW | - NV_PGRAPH_INTR_CONTEXT_SWITCH | - NV_PGRAPH_INTR_BUFFER_NOTIFY | - NV_PGRAPH_INTR_ERROR - ); - else - NV_WRITE(NV40_PGRAPH_INTR_EN, - NV_PGRAPH_INTR_NOTIFY | - NV_PGRAPH_INTR_MISSING_HW | - NV_PGRAPH_INTR_CONTEXT_SWITCH | - NV_PGRAPH_INTR_BUFFER_NOTIFY | - NV_PGRAPH_INTR_ERROR - ); - NV_WRITE(NV03_PGRAPH_INTR, 0xFFFFFFFF); - -#if 0 - /* Enable CRTC0/1 interrupts */ - NV_WRITE(NV_CRTC0_INTEN, NV_CRTC_INTR_VBLANK); - NV_WRITE(NV_CRTC1_INTEN, NV_CRTC_INTR_VBLANK); -#endif + struct drm_nouveau_private *dev_priv = dev->dev_private; /* Master enable */ NV_WRITE(NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE); + + return 0; } -void nouveau_irq_uninstall(drm_device_t *dev) +void +nouveau_irq_uninstall(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; - if (!dev_priv) { - DRM_ERROR("AIII, no dev_priv\n"); - return; - } - if (!dev_priv->mmio) { - DRM_ERROR("AIII, no dev_priv->mmio\n"); - return; - } - - DRM_DEBUG("IRQ: uninst\n"); - - /* Disable PFIFO interrupts */ - NV_WRITE(NV03_PFIFO_INTR_EN_0, 0); - /* Disable PGRAPH interrupts */ - if (dev_priv->card_type<NV_40) - NV_WRITE(NV03_PGRAPH_INTR_EN, 0); - else - NV_WRITE(NV40_PGRAPH_INTR_EN, 0); -#if 0 - /* Disable CRTC0/1 interrupts */ - NV_WRITE(NV_CRTC0_INTEN, 0); - NV_WRITE(NV_CRTC1_INTEN, 0); -#endif /* Master disable */ NV_WRITE(NV03_PMC_INTR_EN_0, 0); } -static void nouveau_fifo_irq_handler(drm_device_t *dev) +static void +nouveau_fifo_irq_handler(struct drm_device *dev) { - uint32_t status, chmode, chstat, channel; - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t status; - status = NV_READ(NV03_PFIFO_INTR_0); - if (!status) - return; - chmode = NV_READ(NV04_PFIFO_MODE); - chstat = NV_READ(NV04_PFIFO_DMA); - channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1); + while ((status = NV_READ(NV03_PFIFO_INTR_0))) { + uint32_t chid, get; + + NV_WRITE(NV03_PFIFO_CACHES, 0); + + chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1) & + (nouveau_fifo_number(dev) - 1); + get = NV_READ(NV03_PFIFO_CACHE1_GET); + + if (status & NV_PFIFO_INTR_CACHE_ERROR) { + uint32_t mthd, data; + int ptr; + + ptr = get >> 2; + if (dev_priv->card_type < NV_40) { + mthd = NV_READ(NV04_PFIFO_CACHE1_METHOD(ptr)); + data = NV_READ(NV04_PFIFO_CACHE1_DATA(ptr)); + } else { + mthd = NV_READ(NV40_PFIFO_CACHE1_METHOD(ptr)); + data = NV_READ(NV40_PFIFO_CACHE1_DATA(ptr)); + } - DRM_DEBUG("NV: PFIFO interrupt! Channel=%d, INTSTAT=0x%08x/MODE=0x%08x/PEND=0x%08x\n", channel, status, chmode, chstat); + DRM_INFO("PFIFO_CACHE_ERROR - " + "Ch %d/%d Mthd 0x%04x Data 0x%08x\n", + chid, (mthd >> 13) & 7, mthd & 0x1ffc, data); - if (status & NV_PFIFO_INTR_CACHE_ERROR) { - uint32_t c1get, c1method, c1data; + NV_WRITE(NV03_PFIFO_CACHE1_GET, get + 4); + NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 1); - DRM_ERROR("NV: PFIFO error interrupt\n"); + status &= ~NV_PFIFO_INTR_CACHE_ERROR; + NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR); + } - c1get = NV_READ(NV03_PFIFO_CACHE1_GET) >> 2; - if (dev_priv->card_type < NV_40) { - /* Untested, so it may not work.. */ - c1method = NV_READ(NV04_PFIFO_CACHE1_METHOD(c1get)); - c1data = NV_READ(NV04_PFIFO_CACHE1_DATA(c1get)); - } else { - c1method = NV_READ(NV40_PFIFO_CACHE1_METHOD(c1get)); - c1data = NV_READ(NV40_PFIFO_CACHE1_DATA(c1get)); + if (status & NV_PFIFO_INTR_DMA_PUSHER) { + DRM_INFO("PFIFO_DMA_PUSHER - Ch %d\n", chid); + + status &= ~NV_PFIFO_INTR_DMA_PUSHER; + NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_DMA_PUSHER); + + NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000); + if (NV_READ(NV04_PFIFO_CACHE1_DMA_PUT) != get) + NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET, get + 4); } - DRM_ERROR("NV: Channel %d/%d - Method 0x%04x, Data 0x%08x\n", - channel, (c1method >> 13) & 7, - c1method & 0x1ffc, c1data - ); + if (status) { + DRM_INFO("Unhandled PFIFO_INTR - 0x%8x\n", status); + NV_WRITE(NV03_PFIFO_INTR_0, status); + } - status &= ~NV_PFIFO_INTR_CACHE_ERROR; - NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR); + NV_WRITE(NV03_PFIFO_CACHES, 1); } - if (status & NV_PFIFO_INTR_DMA_PUSHER) { - DRM_INFO("NV: PFIFO DMA pusher interrupt\n"); + NV_WRITE(NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING); +} - status &= ~NV_PFIFO_INTR_DMA_PUSHER; - NV_WRITE(NV03_PFIFO_INTR_0, NV_PFIFO_INTR_DMA_PUSHER); +struct nouveau_bitfield_names { + uint32_t mask; + const char * name; +}; - NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE, 0x00000000); - if (NV_READ(NV04_PFIFO_CACHE1_DMA_PUT)!=NV_READ(NV04_PFIFO_CACHE1_DMA_GET)) - { - uint32_t getval=NV_READ(NV04_PFIFO_CACHE1_DMA_GET)+4; - NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET,getval); - } - } +static struct nouveau_bitfield_names nouveau_nstatus_names[] = +{ + { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, + { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, + { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, + { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" } +}; - if (status) { - DRM_INFO("NV: unknown PFIFO interrupt. status=0x%08x\n", status); +static struct nouveau_bitfield_names nouveau_nstatus_names_nv10[] = +{ + { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, + { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, + { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, + { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" } +}; - NV_WRITE(NV03_PFIFO_INTR_0, status); - } +static struct nouveau_bitfield_names nouveau_nsource_names[] = +{ + { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, + { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, + { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" }, + { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" }, + { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" }, + { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" }, + { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" }, + { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" }, + { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" }, + { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" }, + { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" }, + { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" }, + { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" }, + { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" }, + { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" }, + { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" }, + { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" }, + { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" }, + { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" }, +}; - NV_WRITE(NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING); +static void +nouveau_print_bitfield_names(uint32_t value, + const struct nouveau_bitfield_names *namelist, + const int namelist_len) +{ + int i; + for(i=0; i<namelist_len; ++i) { + uint32_t mask = namelist[i].mask; + if(value & mask) { + printk(" %s", namelist[i].name); + value &= ~mask; + } + } + if(value) + printk(" (unknown bits 0x%08x)", value); } -#if 0 -static void nouveau_nv04_context_switch(drm_device_t *dev) +static int +nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - uint32_t channel,i; - uint32_t max=0; - NV_WRITE(NV04_PGRAPH_FIFO,0x0); - channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1); - //DRM_INFO("raw PFIFO_CACH1_PHS1 reg is %x\n",NV_READ(NV03_PFIFO_CACHE1_PUSH1)); - //DRM_INFO("currently on channel %d\n",channel); - for (i=0;i<nouveau_fifo_number(dev);i++) - if ((dev_priv->fifos[i].used)&&(i!=channel)) { - uint32_t put,get,pending; - //put=NV_READ(dev_priv->ramfc_offset+i*32); - //get=NV_READ(dev_priv->ramfc_offset+4+i*32); - put=NV_READ(NV03_FIFO_REGS_DMAPUT(i)); - get=NV_READ(NV03_FIFO_REGS_DMAGET(i)); - pending=NV_READ(NV04_PFIFO_DMA); - //DRM_INFO("Channel %d (put/get %x/%x)\n",i,put,get); - /* mark all pending channels as such */ - if ((put!=get)&!(pending&(1<<i))) - { - pending|=(1<<i); - NV_WRITE(NV04_PFIFO_DMA,pending); - } - max++; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int channel; + + if (dev_priv->card_type < NV_10) { + channel = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0xf; + } else if (dev_priv->card_type < NV_40) { + channel = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; + } else + if (dev_priv->card_type < NV_50) { + uint32_t cur_grctx = (NV_READ(0x40032C) & 0xfffff) << 4; + + /* 0x400704 *sometimes* contains a sensible channel ID, but + * mostly not.. for now lookup which channel owns the active + * PGRAPH context. Probably a better way, but this'll do + * for now. + */ + for (channel = 0; channel < 32; channel++) { + if (dev_priv->fifos[channel] == NULL) + continue; + if (cur_grctx == + dev_priv->fifos[channel]->ramin_grctx->instance) + break; + } + if (channel == 32) { + DRM_ERROR("AIII, unable to determine active channel " + "from PGRAPH context 0x%08x\n", cur_grctx); + return -EINVAL; + } + } else { + uint32_t cur_grctx = (NV_READ(0x40032C) & 0xfffff) << 12; + + for (channel = 0; channel < 128; channel++) { + if (dev_priv->fifos[channel] == NULL) + continue; + if (cur_grctx == + dev_priv->fifos[channel]->ramin_grctx->instance) + break; + } + if (channel == 128) { + DRM_ERROR("AIII, unable to determine active channel " + "from PGRAPH context 0x%08x\n", cur_grctx); + return -EINVAL; } - nouveau_wait_for_idle(dev); + } -#if 1 - /* 2-channel commute */ - // NV_WRITE(NV03_PFIFO_CACHE1_PUSH1,channel|0x100); - if (channel==0) - channel=1; - else - channel=0; - // dev_priv->cur_fifo=channel; - NV_WRITE(NV04_PFIFO_NEXT_CHANNEL,channel|0x100); -#endif - //NV_WRITE(NV03_PFIFO_CACHE1_PUSH1,max|0x100); - //NV_WRITE(0x2050,max|0x100); - - NV_WRITE(NV04_PGRAPH_FIFO,0x1); - + if (channel > nouveau_fifo_number(dev) || + dev_priv->fifos[channel] == NULL) { + DRM_ERROR("AIII, invalid/inactive channel id %d\n", channel); + return -EINVAL; + } + + *channel_ret = channel; + return 0; } -#endif static void -nouveau_graph_dump_trap_info(drm_device_t *dev) +nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t address; - uint32_t channel; - uint32_t method, subc, data; + uint32_t channel, class; + uint32_t method, subc, data, data2; + uint32_t nsource, nstatus; + + if (nouveau_graph_trapped_channel(dev, &channel)) + channel = -1; - address = NV_READ(0x400704); - data = NV_READ(0x400708); - channel = (address >> 20) & 0x1F; - subc = (address >> 16) & 0x7; + data = NV_READ(NV04_PGRAPH_TRAPPED_DATA); + address = NV_READ(NV04_PGRAPH_TRAPPED_ADDR); method = address & 0x1FFC; + if (dev_priv->card_type < NV_10) { + subc = (address >> 13) & 0x7; + data2= 0; + } else { + subc = (address >> 16) & 0x7; + data2= NV_READ(NV10_PGRAPH_TRAPPED_DATA_HIGH); + } + nsource = NV_READ(NV03_PGRAPH_NSOURCE); + nstatus = NV_READ(NV03_PGRAPH_NSTATUS); + if (dev_priv->card_type < NV_10) { + class = NV_READ(0x400180 + subc*4) & 0xFF; + } else if (dev_priv->card_type < NV_40) { + class = NV_READ(0x400160 + subc*4) & 0xFFF; + } else if (dev_priv->card_type < NV_50) { + class = NV_READ(0x400160 + subc*4) & 0xFFFF; + } else { + class = NV_READ(0x400814); + } - DRM_ERROR("NV: nSource: 0x%08x, nStatus: 0x%08x\n", - NV_READ(0x400108), NV_READ(0x400104)); - DRM_ERROR("NV: Channel %d/%d (class 0x%04x) -" - "Method 0x%04x, Data 0x%08x\n", - channel, subc, - NV_READ(0x400160+subc*4) & 0xFFFF, - method, data - ); + DRM_INFO("%s - nSource:", id); + nouveau_print_bitfield_names(nsource, nouveau_nsource_names, + ARRAY_SIZE(nouveau_nsource_names)); + printk(", nStatus:"); + if (dev_priv->card_type < NV_10) + nouveau_print_bitfield_names(nstatus, nouveau_nstatus_names, + ARRAY_SIZE(nouveau_nstatus_names)); + else + nouveau_print_bitfield_names(nstatus, nouveau_nstatus_names_nv10, + ARRAY_SIZE(nouveau_nstatus_names_nv10)); + printk("\n"); + + DRM_INFO("%s - Ch %d/%d Class 0x%04x Mthd 0x%04x Data 0x%08x:0x%08x\n", + id, channel, subc, class, method, data2, data); } -static void nouveau_pgraph_irq_handler(drm_device_t *dev) +static inline void +nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) { - uint32_t status; - drm_nouveau_private_t *dev_priv = dev->dev_private; - - status = NV_READ(NV03_PGRAPH_INTR); - if (!status) - return; - - if (status & NV_PGRAPH_INTR_NOTIFY) { - uint32_t nsource, nstatus, instance, notify; - DRM_DEBUG("NV: PGRAPH notify interrupt\n"); - - nstatus = NV_READ(0x00400104); - nsource = NV_READ(0x00400108); - DRM_DEBUG("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus); - - /* if this wasn't NOTIFICATION_PENDING, dump extra trap info */ - if (nsource & ~(1<<0)) { - nouveau_graph_dump_trap_info(dev); + struct drm_nouveau_private *dev_priv = dev->dev_private; + int handled = 0; + + DRM_DEBUG("PGRAPH notify interrupt\n"); + if (dev_priv->card_type == NV_04 && + (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) { + uint32_t class, mthd; + + /* NV4 (nvidia TNT 1) reports software methods with + * PGRAPH NOTIFY ILLEGAL_MTHD + */ + mthd = NV_READ(NV04_PGRAPH_TRAPPED_ADDR) & 0x1FFC; + class = NV_READ(NV04_PGRAPH_CTX_SWITCH1) & 0xFFF; + DRM_DEBUG("Got NV04 software method method %x for class %#x\n", + mthd, class); + + if (nouveau_sw_method_execute(dev, class, mthd)) { + DRM_ERROR("Unable to execute NV04 software method %x " + "for object class %x. Please report.\n", + mthd, class); } else { - instance = NV_READ(0x00400158); - notify = NV_READ(0x00400150) >> 16; - DRM_DEBUG("instance:0x%08x\tnotify:0x%08x\n", - nsource, nstatus); + handled = 1; } - - status &= ~NV_PGRAPH_INTR_NOTIFY; - NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_NOTIFY); } - if (status & NV_PGRAPH_INTR_BUFFER_NOTIFY) { - uint32_t nsource, nstatus, instance, notify; - DRM_DEBUG("NV: PGRAPH buffer notify interrupt\n"); - - nstatus = NV_READ(0x00400104); - nsource = NV_READ(0x00400108); - DRM_DEBUG("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus); + if (!handled) + nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY"); +} - instance = NV_READ(0x00400158); - notify = NV_READ(0x00400150) >> 16; - DRM_DEBUG("instance:0x%08x\tnotify:0x%08x\n", instance, notify); +static inline void +nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource) +{ + nouveau_graph_dump_trap_info(dev, "PGRAPH_ERROR"); +} - status &= ~NV_PGRAPH_INTR_BUFFER_NOTIFY; - NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_BUFFER_NOTIFY); +static inline void +nouveau_pgraph_intr_context_switch(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t chid; + + chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1) & (nouveau_fifo_number(dev)-1); + DRM_DEBUG("PGRAPH context switch interrupt channel %x\n", chid); + + switch(dev_priv->card_type) { + case NV_04: + case NV_05: + nouveau_nv04_context_switch(dev); + break; + case NV_10: + case NV_11: + case NV_17: + nouveau_nv10_context_switch(dev); + break; + default: + DRM_ERROR("Context switch not implemented\n"); + break; } +} - if (status & NV_PGRAPH_INTR_MISSING_HW) { - DRM_ERROR("NV: PGRAPH missing hw interrupt\n"); - - status &= ~NV_PGRAPH_INTR_MISSING_HW; - NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_MISSING_HW); - } +static void +nouveau_pgraph_irq_handler(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t status; - if (status & NV_PGRAPH_INTR_ERROR) { - uint32_t nsource, nstatus, instance; + while ((status = NV_READ(NV03_PGRAPH_INTR))) { + uint32_t nsource = NV_READ(NV03_PGRAPH_NSOURCE); - DRM_ERROR("NV: PGRAPH error interrupt\n"); + if (status & NV_PGRAPH_INTR_NOTIFY) { + nouveau_pgraph_intr_notify(dev, nsource); - nstatus = NV_READ(0x00400104); - nsource = NV_READ(0x00400108); - DRM_ERROR("nsource:0x%08x\tnstatus:0x%08x\n", nsource, nstatus); + status &= ~NV_PGRAPH_INTR_NOTIFY; + NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_NOTIFY); + } - instance = NV_READ(0x00400158); - DRM_ERROR("instance:0x%08x\n", instance); + if (status & NV_PGRAPH_INTR_ERROR) { + nouveau_pgraph_intr_error(dev, nsource); - nouveau_graph_dump_trap_info(dev); + status &= ~NV_PGRAPH_INTR_ERROR; + NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_ERROR); + } - status &= ~NV_PGRAPH_INTR_ERROR; - NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_ERROR); - } + if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) { + nouveau_pgraph_intr_context_switch(dev); - if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) { - uint32_t channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1); - DRM_INFO("NV: PGRAPH context switch interrupt channel %x\n",channel); - switch(dev_priv->card_type) - { - case NV_04: - case NV_05: - nouveau_nv04_context_switch(dev); - break; - case NV_10: - case NV_17: - nouveau_nv10_context_switch(dev); - break; - case NV_20: - case NV_30: - nouveau_nv20_context_switch(dev); - break; - default: - DRM_INFO("NV: Context switch not implemented\n"); - break; + status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; + NV_WRITE(NV03_PGRAPH_INTR, + NV_PGRAPH_INTR_CONTEXT_SWITCH); } - status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; - NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); - } + if (status) { + DRM_INFO("Unhandled PGRAPH_INTR - 0x%8x\n", status); + NV_WRITE(NV03_PGRAPH_INTR, status); + } - if (status) { - DRM_INFO("NV: Unknown PGRAPH interrupt! STAT=0x%08x\n", status); - NV_WRITE(NV03_PGRAPH_INTR, status); + if ((NV_READ(NV04_PGRAPH_FIFO) & (1 << 0)) == 0) + NV_WRITE(NV04_PGRAPH_FIFO, 1); } NV_WRITE(NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); } -static void nouveau_crtc_irq_handler(drm_device_t *dev, int crtc) +static void +nouveau_crtc_irq_handler(struct drm_device *dev, int crtc) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; + if (crtc&1) { NV_WRITE(NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK); } @@ -408,26 +416,27 @@ static void nouveau_crtc_irq_handler(drm_device_t *dev, int crtc) } } -irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS) +irqreturn_t +nouveau_irq_handler(DRM_IRQ_ARGS) { - drm_device_t *dev = (drm_device_t*)arg; - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_device *dev = (struct drm_device*)arg; + struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t status; status = NV_READ(NV03_PMC_INTR_0); if (!status) return IRQ_NONE; - DRM_DEBUG("PMC INTSTAT: 0x%08x\n", status); - if (status & NV_PMC_INTR_0_PFIFO_PENDING) { nouveau_fifo_irq_handler(dev); status &= ~NV_PMC_INTR_0_PFIFO_PENDING; } + if (status & NV_PMC_INTR_0_PGRAPH_PENDING) { nouveau_pgraph_irq_handler(dev); status &= ~NV_PMC_INTR_0_PGRAPH_PENDING; } + if (status & NV_PMC_INTR_0_CRTCn_PENDING) { nouveau_crtc_irq_handler(dev, (status>>24)&3); status &= ~NV_PMC_INTR_0_CRTCn_PENDING; diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index a5343b99..448b69d3 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -36,7 +36,7 @@ #include "nouveau_drv.h" static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64_t size, - DRMFILE filp) + struct drm_file *file_priv) { /* Maybe cut off the start of an existing block */ if (start > p->start) { @@ -46,7 +46,7 @@ static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64 goto out; newblock->start = start; newblock->size = p->size - (start - p->start); - newblock->filp = NULL; + newblock->file_priv = NULL; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -63,7 +63,7 @@ static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64 goto out; newblock->start = start + size; newblock->size = p->size - size; - newblock->filp = NULL; + newblock->file_priv = NULL; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -73,12 +73,14 @@ static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64 out: /* Our block is in the middle */ - p->filp = filp; + p->file_priv = file_priv; return p; } -static struct mem_block *alloc_block(struct mem_block *heap, uint64_t size, - int align2, DRMFILE filp) +struct mem_block *nouveau_mem_alloc_block(struct mem_block *heap, + uint64_t size, + int align2, + struct drm_file *file_priv) { struct mem_block *p; uint64_t mask = (1 << align2) - 1; @@ -88,8 +90,8 @@ static struct mem_block *alloc_block(struct mem_block *heap, uint64_t size, list_for_each(p, heap) { uint64_t start = (p->start + mask) & ~mask; - if (p->filp == 0 && start + size <= p->start + p->size) - return split_block(p, start, size, filp); + if (p->file_priv == 0 && start + size <= p->start + p->size) + return split_block(p, start, size, file_priv); } return NULL; @@ -106,14 +108,14 @@ static struct mem_block *find_block(struct mem_block *heap, uint64_t start) return NULL; } -static void free_block(struct mem_block *p) +void nouveau_mem_free_block(struct mem_block *p) { - p->filp = NULL; + p->file_priv = NULL; - /* Assumes a single contiguous range. Needs a special filp in + /* Assumes a single contiguous range. Needs a special file_priv in * 'heap' to stop it being subsumed. */ - if (p->next->filp == 0) { + if (p->next->file_priv == 0) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; @@ -121,7 +123,7 @@ static void free_block(struct mem_block *p) drm_free(q, sizeof(*q), DRM_MEM_BUFS); } - if (p->prev->filp == 0) { + if (p->prev->file_priv == 0) { struct mem_block *q = p->prev; q->size += p->size; q->next = p->next; @@ -132,34 +134,35 @@ static void free_block(struct mem_block *p) /* Initialize. How to check for an uninitialized heap? */ -static int init_heap(struct mem_block **heap, uint64_t start, uint64_t size) +int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start, + uint64_t size) { struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS); if (!blocks) - return DRM_ERR(ENOMEM); + return -ENOMEM; *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS); if (!*heap) { drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS); - return DRM_ERR(ENOMEM); + return -ENOMEM; } blocks->start = start; blocks->size = size; - blocks->filp = NULL; + blocks->file_priv = NULL; blocks->next = blocks->prev = *heap; memset(*heap, 0, sizeof(**heap)); - (*heap)->filp = (DRMFILE) - 1; + (*heap)->file_priv = (struct drm_file *) - 1; (*heap)->next = (*heap)->prev = blocks; return 0; } /* - * Free all blocks associated with the releasing filp + * Free all blocks associated with the releasing file_priv */ -void nouveau_mem_release(DRMFILE filp, struct mem_block *heap) +void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap) { struct mem_block *p; @@ -167,15 +170,16 @@ void nouveau_mem_release(DRMFILE filp, struct mem_block *heap) return; list_for_each(p, heap) { - if (p->filp == filp) - p->filp = NULL; + if (p->file_priv == file_priv) + p->file_priv = NULL; } - /* Assumes a single contiguous range. Needs a special filp in + /* Assumes a single contiguous range. Needs a special file_priv in * 'heap' to stop it being subsumed. */ list_for_each(p, heap) { - while ((p->filp == 0) && (p->next->filp == 0) && (p->next!=heap)) { + while ((p->file_priv == 0) && (p->next->file_priv == 0) && + (p->next!=heap)) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; @@ -188,7 +192,7 @@ void nouveau_mem_release(DRMFILE filp, struct mem_block *heap) /* * Cleanup everything */ -static void nouveau_mem_takedown(struct mem_block **heap) +void nouveau_mem_takedown(struct mem_block **heap) { struct mem_block *p; @@ -207,29 +211,52 @@ static void nouveau_mem_takedown(struct mem_block **heap) void nouveau_mem_close(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; + nouveau_mem_takedown(&dev_priv->agp_heap); nouveau_mem_takedown(&dev_priv->fb_heap); + if (dev_priv->pci_heap) + nouveau_mem_takedown(&dev_priv->pci_heap); +} + +/*XXX won't work on BSD because of pci_read_config_dword */ +static uint32_t +nouveau_mem_fb_amount_igp(struct drm_device *dev) +{ +#if defined(__linux__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct pci_dev *bridge; + uint32_t mem; + + bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0,1)); + if (!bridge) { + DRM_ERROR("no bridge device\n"); + return 0; + } + + if (dev_priv->flags&NV_NFORCE) { + pci_read_config_dword(bridge, 0x7C, &mem); + return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024; + } else + if(dev_priv->flags&NV_NFORCE2) { + pci_read_config_dword(bridge, 0x84, &mem); + return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024; + } + + DRM_ERROR("impossible!\n"); +#else + DRM_ERROR("Linux kernel >= 2.6.19 required to check for igp memory amount\n"); +#endif + + return 0; } /* returns the amount of FB ram in bytes */ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_nouveau_private *dev_priv=dev->dev_private; switch(dev_priv->card_type) { - case NV_03: - switch(NV_READ(NV03_BOOT_0)&NV03_BOOT_0_RAM_AMOUNT) - { - case NV03_BOOT_0_RAM_AMOUNT_8MB: - case NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM: - return 8*1024*1024; - case NV03_BOOT_0_RAM_AMOUNT_4MB: - return 4*1024*1024; - case NV03_BOOT_0_RAM_AMOUNT_2MB: - return 2*1024*1024; - } - break; case NV_04: case NV_05: if (NV_READ(NV03_BOOT_0) & 0x00000100) { @@ -248,6 +275,7 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) } break; case NV_10: + case NV_11: case NV_17: case NV_20: case NV_30: @@ -255,18 +283,14 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) case NV_44: case NV_50: default: - // XXX won't work on BSD because of pci_read_config_dword - if (dev_priv->flags&NV_NFORCE) { - uint32_t mem; - pci_read_config_dword(dev->pdev, 0x7C, &mem); - return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024; - } else if(dev_priv->flags&NV_NFORCE2) { - uint32_t mem; - pci_read_config_dword(dev->pdev, 0x84, &mem); - return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024; + if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { + return nouveau_mem_fb_amount_igp(dev); } else { uint64_t mem; - mem=(NV_READ(NV04_FIFO_DATA)&NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >> NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT; + + mem = (NV_READ(NV04_FIFO_DATA) & + NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >> + NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT; return mem*1024*1024; } break; @@ -276,68 +300,67 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) return 0; } - - -int nouveau_mem_init(struct drm_device *dev) +static int +nouveau_mem_init_agp(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - uint32_t fb_size; - dev_priv->agp_phys=0; - dev_priv->fb_phys=0; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_agp_info info; + struct drm_agp_mode mode; + struct drm_agp_buffer agp_req; + struct drm_agp_binding bind_req; + int ret; + + ret = drm_agp_acquire(dev); + if (ret) { + DRM_ERROR("Unable to acquire AGP: %d\n", ret); + return ret; + } - /* init AGP */ - dev_priv->agp_heap=NULL; - if (drm_device_is_agp(dev)) - { - int err; - drm_agp_info_t info; - drm_agp_mode_t mode; - drm_agp_buffer_t agp_req; - drm_agp_binding_t bind_req; - - err = drm_agp_acquire(dev); - if (err) { - DRM_ERROR("Unable to acquire AGP: %d\n", err); - goto no_agp; - } + ret = drm_agp_info(dev, &info); + if (ret) { + DRM_ERROR("Unable to get AGP info: %d\n", ret); + return ret; + } - err = drm_agp_info(dev, &info); - if (err) { - DRM_ERROR("Unable to get AGP info: %d\n", err); - goto no_agp; - } + /* see agp.h for the AGPSTAT_* modes available */ + mode.mode = info.mode; + ret = drm_agp_enable(dev, mode); + if (ret) { + DRM_ERROR("Unable to enable AGP: %d\n", ret); + return ret; + } - /* see agp.h for the AGPSTAT_* modes available */ - mode.mode = info.mode; - err = drm_agp_enable(dev, mode); - if (err) { - DRM_ERROR("Unable to enable AGP: %d\n", err); - goto no_agp; - } + agp_req.size = info.aperture_size; + agp_req.type = 0; + ret = drm_agp_alloc(dev, &agp_req); + if (ret) { + DRM_ERROR("Unable to alloc AGP: %d\n", ret); + return ret; + } - agp_req.size = info.aperture_size; - agp_req.type = 0; - err = drm_agp_alloc(dev, &agp_req); - if (err) { - DRM_ERROR("Unable to alloc AGP: %d\n", err); - goto no_agp; - } + bind_req.handle = agp_req.handle; + bind_req.offset = 0; + ret = drm_agp_bind(dev, &bind_req); + if (ret) { + DRM_ERROR("Unable to bind AGP: %d\n", ret); + return ret; + } - bind_req.handle = agp_req.handle; - bind_req.offset = 0; - err = drm_agp_bind(dev, &bind_req); - if (err) { - DRM_ERROR("Unable to bind AGP: %d\n", err); - goto no_agp; - } + dev_priv->gart_info.type = NOUVEAU_GART_AGP; + dev_priv->gart_info.aper_base = info.aperture_base; + dev_priv->gart_info.aper_size = info.aperture_size; + return 0; +} - if (init_heap(&dev_priv->agp_heap, info.aperture_base, info.aperture_size)) - goto no_agp; +int nouveau_mem_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t fb_size; + int ret = 0; - dev_priv->agp_phys = info.aperture_base; - dev_priv->agp_available_size = info.aperture_size; - } -no_agp: + dev_priv->agp_heap = dev_priv->pci_heap = dev_priv->fb_heap = NULL; + dev_priv->fb_phys = 0; + dev_priv->gart_info.type = NOUVEAU_GART_NONE; /* setup a mtrr over the FB */ dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1), @@ -350,31 +373,83 @@ no_agp: /* On at least NV40, RAMIN is actually at the end of vram. * We don't want to allocate this... */ if (dev_priv->card_type >= NV_40) - fb_size -= dev_priv->ramin_size; + fb_size -= dev_priv->ramin_rsvd_vram; dev_priv->fb_available_size = fb_size; DRM_DEBUG("Available VRAM: %dKiB\n", fb_size>>10); if (fb_size>256*1024*1024) { /* On cards with > 256Mb, you can't map everything. * So we create a second FB heap for that type of memory */ - if (init_heap(&dev_priv->fb_heap, drm_get_resource_start(dev,1), 256*1024*1024)) - return DRM_ERR(ENOMEM); - if (init_heap(&dev_priv->fb_nomap_heap, drm_get_resource_start(dev,1)+256*1024*1024, fb_size-256*1024*1024)) - return DRM_ERR(ENOMEM); + if (nouveau_mem_init_heap(&dev_priv->fb_heap, + 0, 256*1024*1024)) + return -ENOMEM; + if (nouveau_mem_init_heap(&dev_priv->fb_nomap_heap, + 256*1024*1024, fb_size-256*1024*1024)) + return -ENOMEM; } else { - if (init_heap(&dev_priv->fb_heap, drm_get_resource_start(dev,1), fb_size)) - return DRM_ERR(ENOMEM); + if (nouveau_mem_init_heap(&dev_priv->fb_heap, 0, fb_size)) + return -ENOMEM; dev_priv->fb_nomap_heap=NULL; } + /* Init AGP / NV50 PCIEGART */ + if (drm_device_is_agp(dev) && dev->agp) { + if ((ret = nouveau_mem_init_agp(dev))) + DRM_ERROR("Error initialising AGP: %d\n", ret); + } + + /*Note: this is *not* just NV50 code, but only used on NV50 for now */ + if (dev_priv->gart_info.type == NOUVEAU_GART_NONE && + dev_priv->card_type >= NV_50) { + ret = nouveau_sgdma_init(dev); + if (!ret) { + ret = nouveau_sgdma_nottm_hack_init(dev); + if (ret) + nouveau_sgdma_takedown(dev); + } + + if (ret) + DRM_ERROR("Error initialising SG DMA: %d\n", ret); + } + + if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) { + if (nouveau_mem_init_heap(&dev_priv->agp_heap, + 0, dev_priv->gart_info.aper_size)) { + if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) { + nouveau_sgdma_nottm_hack_takedown(dev); + nouveau_sgdma_takedown(dev); + } + } + } + + /* NV04-NV40 PCIEGART */ + if (!dev_priv->agp_heap && dev_priv->card_type < NV_50) { + struct drm_scatter_gather sgreq; + + DRM_DEBUG("Allocating sg memory for PCI DMA\n"); + sgreq.size = 16 << 20; //16MB of PCI scatter-gather zone + + if (drm_sg_alloc(dev, &sgreq)) { + DRM_ERROR("Unable to allocate %ldMB of scatter-gather" + " pages for PCI DMA!",sgreq.size>>20); + } else { + if (nouveau_mem_init_heap(&dev_priv->pci_heap, 0, + dev->sg->pages * PAGE_SIZE)) { + DRM_ERROR("Unable to initialize pci_heap!"); + } + } + } + return 0; } -struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, int flags, DRMFILE filp) +struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, + uint64_t size, int flags, + struct drm_file *file_priv) { struct mem_block *block; int type; - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; /* * Make things easier on ourselves: all allocations are page-aligned. @@ -395,25 +470,42 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint6 if (size & (~PAGE_MASK)) size = ((size/PAGE_SIZE) + 1) * PAGE_SIZE; - if (flags&NOUVEAU_MEM_AGP) { - type=NOUVEAU_MEM_AGP; - block = alloc_block(dev_priv->agp_heap, size, alignment, filp); - if (block) goto alloc_ok; - } - if (flags&(NOUVEAU_MEM_FB|NOUVEAU_MEM_FB_ACCEPTABLE)) { - type=NOUVEAU_MEM_FB; - if (!(flags&NOUVEAU_MEM_MAPPED)) { - block = alloc_block(dev_priv->fb_nomap_heap, size, alignment, filp); - if (block) goto alloc_ok; - } - block = alloc_block(dev_priv->fb_heap, size, alignment, filp); - if (block) goto alloc_ok; - } - if (flags&NOUVEAU_MEM_AGP_ACCEPTABLE) { - type=NOUVEAU_MEM_AGP; - block = alloc_block(dev_priv->agp_heap, size, alignment, filp); - if (block) goto alloc_ok; - } + +#define NOUVEAU_MEM_ALLOC_AGP {\ + type=NOUVEAU_MEM_AGP;\ + block = nouveau_mem_alloc_block(dev_priv->agp_heap, size,\ + alignment, file_priv); \ + if (block) goto alloc_ok;\ + } + +#define NOUVEAU_MEM_ALLOC_PCI {\ + type = NOUVEAU_MEM_PCI;\ + block = nouveau_mem_alloc_block(dev_priv->pci_heap, size, \ + alignment, file_priv); \ + if ( block ) goto alloc_ok;\ + } + +#define NOUVEAU_MEM_ALLOC_FB {\ + type=NOUVEAU_MEM_FB;\ + if (!(flags&NOUVEAU_MEM_MAPPED)) {\ + block = nouveau_mem_alloc_block(dev_priv->fb_nomap_heap,\ + size, alignment, \ + file_priv); \ + if (block) goto alloc_ok;\ + }\ + block = nouveau_mem_alloc_block(dev_priv->fb_heap, size,\ + alignment, file_priv);\ + if (block) goto alloc_ok;\ + } + + + if (flags&NOUVEAU_MEM_FB) NOUVEAU_MEM_ALLOC_FB + if (flags&NOUVEAU_MEM_AGP) NOUVEAU_MEM_ALLOC_AGP + if (flags&NOUVEAU_MEM_PCI) NOUVEAU_MEM_ALLOC_PCI + if (flags&NOUVEAU_MEM_FB_ACCEPTABLE) NOUVEAU_MEM_ALLOC_FB + if (flags&NOUVEAU_MEM_AGP_ACCEPTABLE) NOUVEAU_MEM_ALLOC_AGP + if (flags&NOUVEAU_MEM_PCI_ACCEPTABLE) NOUVEAU_MEM_ALLOC_PCI + return NULL; @@ -422,252 +514,92 @@ alloc_ok: if (flags&NOUVEAU_MEM_MAPPED) { - int ret; + struct drm_map_list *entry; + int ret = 0; block->flags|=NOUVEAU_MEM_MAPPED; - if (type == NOUVEAU_MEM_AGP) - ret = drm_addmap(dev, block->start - dev->agp->base, block->size, - _DRM_AGP, 0, &block->map); - else + if (type == NOUVEAU_MEM_AGP) { + if (dev_priv->gart_info.type != NOUVEAU_GART_SGDMA) + ret = drm_addmap(dev, block->start, block->size, + _DRM_AGP, 0, &block->map); + else ret = drm_addmap(dev, block->start, block->size, - _DRM_FRAME_BUFFER, 0, &block->map); + _DRM_SCATTER_GATHER, 0, &block->map); + } + else if (type == NOUVEAU_MEM_FB) + ret = drm_addmap(dev, block->start + dev_priv->fb_phys, + block->size, _DRM_FRAME_BUFFER, + 0, &block->map); + else if (type == NOUVEAU_MEM_PCI) + ret = drm_addmap(dev, block->start, block->size, + _DRM_SCATTER_GATHER, 0, &block->map); + if (ret) { - free_block(block); + nouveau_mem_free_block(block); + return NULL; + } + + entry = drm_find_matching_map(dev, block->map); + if (!entry) { + nouveau_mem_free_block(block); return NULL; } + block->map_handle = entry->user_token; } - DRM_INFO("allocated 0x%llx\n", block->start); + DRM_DEBUG("allocated 0x%llx type=0x%08x\n", block->start, block->flags); return block; } void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) { - DRM_INFO("freeing 0x%llx\n", block->start); + DRM_DEBUG("freeing 0x%llx type=0x%08x\n", block->start, block->flags); if (block->flags&NOUVEAU_MEM_MAPPED) drm_rmmap(dev, block->map); - free_block(block); -} - -static void -nouveau_instmem_determine_amount(struct drm_device *dev) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - int i; - - /* Figure out how much instance memory we need */ - switch (dev_priv->card_type) { - case NV_40: - /* We'll want more instance memory than this on some NV4x cards. - * There's a 16MB aperture to play with that maps onto the end - * of vram. For now, only reserve a small piece until we know - * more about what each chipset requires. - */ - dev_priv->ramin_size = (1*1024* 1024); - break; - default: - /*XXX: what *are* the limits on <NV40 cards?, and does RAMIN - * exist in vram on those cards as well? - */ - dev_priv->ramin_size = (512*1024); - break; - } - DRM_DEBUG("RAMIN size: %dKiB\n", dev_priv->ramin_size>>10); - - /* Clear all of it, except the BIOS image that's in the first 64KiB */ - if (dev_priv->ramin) { - for (i=(64*1024); i<dev_priv->ramin_size; i+=4) - DRM_WRITE32(dev_priv->ramin, i, 0x00000000); - } else { - for (i=(64*1024); i<dev_priv->ramin_size; i+=4) - DRM_WRITE32(dev_priv->mmio, NV_RAMIN + i, 0x00000000); - } -} - -static void -nouveau_instmem_configure_fixed_tables(struct drm_device *dev) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - - /* FIFO hash table (RAMHT) - * use 4k hash table at RAMIN+0x10000 - * TODO: extend the hash table - */ - dev_priv->ramht_offset = 0x10000; - dev_priv->ramht_bits = 9; - dev_priv->ramht_size = (1 << dev_priv->ramht_bits); - DRM_DEBUG("RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset, - dev_priv->ramht_size); - - /* FIFO runout table (RAMRO) - 512k at 0x11200 */ - dev_priv->ramro_offset = 0x11200; - dev_priv->ramro_size = 512; - DRM_DEBUG("RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset, - dev_priv->ramro_size); - - /* FIFO context table (RAMFC) - * NV40 : Not sure exactly how to position RAMFC on some cards, - * 0x30002 seems to position it at RAMIN+0x20000 on these - * cards. RAMFC is 4kb (32 fifos, 128byte entries). - * Others: Position RAMFC at RAMIN+0x11400 - */ - switch(dev_priv->card_type) - { - case NV_50: - case NV_40: - case NV_44: - dev_priv->ramfc_offset = 0x20000; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * - nouveau_fifo_ctx_size(dev); - break; - case NV_30: - case NV_20: - case NV_17: - case NV_10: - case NV_04: - case NV_03: - default: - dev_priv->ramfc_offset = 0x11400; - dev_priv->ramfc_size = nouveau_fifo_number(dev) * - nouveau_fifo_ctx_size(dev); - break; - } - DRM_DEBUG("RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset, - dev_priv->ramfc_size); -} - -int nouveau_instmem_init(struct drm_device *dev) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - uint32_t offset; - int ret = 0; - - nouveau_instmem_determine_amount(dev); - nouveau_instmem_configure_fixed_tables(dev); - - /* Create a heap to manage RAMIN allocations, we don't allocate - * the space that was reserved for RAMHT/FC/RO. - */ - offset = dev_priv->ramfc_offset + dev_priv->ramfc_size; - ret = init_heap(&dev_priv->ramin_heap, - offset, dev_priv->ramin_size - offset); - if (ret) { - dev_priv->ramin_heap = NULL; - DRM_ERROR("Failed to init RAMIN heap\n"); - } - - return ret; -} - -struct mem_block *nouveau_instmem_alloc(struct drm_device *dev, - uint32_t size, uint32_t align) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct mem_block *block; - - if (!dev_priv->ramin_heap) { - DRM_ERROR("instmem alloc called without init\n"); - return NULL; - } - - block = alloc_block(dev_priv->ramin_heap, size, align, (DRMFILE)-2); - if (block) { - block->flags = NOUVEAU_MEM_INSTANCE; - DRM_DEBUG("instance(size=%d, align=%d) alloc'd at 0x%08x\n", - size, (1<<align), (uint32_t)block->start); - } - - return block; -} - -void nouveau_instmem_free(struct drm_device *dev, struct mem_block *block) -{ - if (dev && block) { - free_block(block); - } -} - -uint32_t nouveau_instmem_r32(drm_nouveau_private_t *dev_priv, - struct mem_block *mem, int index) -{ - uint32_t ofs = (uint32_t)mem->start + (index<<2); - - if (dev_priv->ramin) { -#if defined(__powerpc__) - return in_be32((void __iomem *)(dev_priv->ramin)->handle + ofs); -#else - return DRM_READ32(dev_priv->ramin, ofs); -#endif - } else { - return NV_READ(NV_RAMIN+ofs); - } -} - -void nouveau_instmem_w32(drm_nouveau_private_t *dev_priv, - struct mem_block *mem, int index, uint32_t val) -{ - uint32_t ofs = (uint32_t)mem->start + (index<<2); - - if (dev_priv->ramin) { -#if defined(__powerpc__) - out_be32((void __iomem *)(dev_priv->ramin)->handle + ofs, val); -#else - DRM_WRITE32(dev_priv->ramin, ofs, val); -#endif - } else { - NV_WRITE(NV_RAMIN+ofs, val); - } + nouveau_mem_free_block(block); } /* * Ioctls */ -int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) +int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_nouveau_private_t *dev_priv = dev->dev_private; - drm_nouveau_mem_alloc_t alloc; + struct drm_nouveau_mem_alloc *alloc = data; struct mem_block *block; - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); - } - - DRM_COPY_FROM_USER_IOCTL(alloc, (drm_nouveau_mem_alloc_t __user *) data, - sizeof(alloc)); + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; - block=nouveau_mem_alloc(dev, alloc.alignment, alloc.size, alloc.flags, filp); + block=nouveau_mem_alloc(dev, alloc->alignment, alloc->size, + alloc->flags, file_priv); if (!block) - return DRM_ERR(ENOMEM); - alloc.region_offset=block->start; - alloc.flags=block->flags; - - DRM_COPY_TO_USER_IOCTL((drm_nouveau_mem_alloc_t __user *) data, alloc, sizeof(alloc)); + return -ENOMEM; + alloc->map_handle=block->map_handle; + alloc->offset=block->start; + alloc->flags=block->flags; return 0; } -int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS) +int nouveau_ioctl_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_nouveau_private_t *dev_priv = dev->dev_private; - drm_nouveau_mem_free_t memfree; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_mem_free *memfree = data; struct mem_block *block; - DRM_COPY_FROM_USER_IOCTL(memfree, (drm_nouveau_mem_free_t __user *) data, - sizeof(memfree)); + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; block=NULL; - if (memfree.flags&NOUVEAU_MEM_FB) - block = find_block(dev_priv->fb_heap, memfree.region_offset); - else if (memfree.flags&NOUVEAU_MEM_AGP) - block = find_block(dev_priv->agp_heap, memfree.region_offset); + if (memfree->flags & NOUVEAU_MEM_FB) + block = find_block(dev_priv->fb_heap, memfree->offset); + else if (memfree->flags & NOUVEAU_MEM_AGP) + block = find_block(dev_priv->agp_heap, memfree->offset); + else if (memfree->flags & NOUVEAU_MEM_PCI) + block = find_block(dev_priv->pci_heap, memfree->offset); if (!block) - return DRM_ERR(EFAULT); - if (block->filp != filp) - return DRM_ERR(EPERM); + return -EFAULT; + if (block->file_priv != file_priv) + return -EPERM; nouveau_mem_free(dev, block); return 0; diff --git a/shared-core/nouveau_notifier.c b/shared-core/nouveau_notifier.c new file mode 100644 index 00000000..31e2b244 --- /dev/null +++ b/shared-core/nouveau_notifier.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" + +int +nouveau_notifier_init_channel(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + int flags, ret; + + flags = (NOUVEAU_MEM_PCI | NOUVEAU_MEM_MAPPED | + NOUVEAU_MEM_FB_ACCEPTABLE); + + chan->notifier_block = nouveau_mem_alloc(dev, 0, PAGE_SIZE, flags, + (struct drm_file *)-2); + if (!chan->notifier_block) + return -ENOMEM; + DRM_DEBUG("Allocated notifier block in 0x%08x\n", + chan->notifier_block->flags); + + ret = nouveau_mem_init_heap(&chan->notifier_heap, + 0, chan->notifier_block->size); + if (ret) + return ret; + + return 0; +} + +void +nouveau_notifier_takedown_channel(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + + if (chan->notifier_block) { + nouveau_mem_free(dev, chan->notifier_block); + chan->notifier_block = NULL; + } + + nouveau_mem_takedown(&chan->notifier_heap); +} + +static void +nouveau_notifier_gpuobj_dtor(struct drm_device *dev, + struct nouveau_gpuobj *gpuobj) +{ + DRM_DEBUG("\n"); + + if (gpuobj->priv) + nouveau_mem_free_block(gpuobj->priv); +} + +int +nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, + int count, uint32_t *b_offset) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *nobj = NULL; + struct mem_block *mem; + uint32_t offset; + int target, ret; + + if (!chan->notifier_heap) { + DRM_ERROR("Channel %d doesn't have a notifier heap!\n", + chan->id); + return -EINVAL; + } + + mem = nouveau_mem_alloc_block(chan->notifier_heap, count*32, 0, + (struct drm_file *)-2); + if (!mem) { + DRM_ERROR("Channel %d notifier block full\n", chan->id); + return -ENOMEM; + } + mem->flags = NOUVEAU_MEM_NOTIFIER; + + offset = chan->notifier_block->start; + if (chan->notifier_block->flags & NOUVEAU_MEM_FB) { + target = NV_DMA_TARGET_VIDMEM; + } else + if (chan->notifier_block->flags & NOUVEAU_MEM_AGP) { + if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA && + dev_priv->card_type < NV_50) { + ret = nouveau_sgdma_get_page(dev, offset, &offset); + if (ret) + return ret; + target = NV_DMA_TARGET_PCI; + } else { + target = NV_DMA_TARGET_AGP; + } + } else + if (chan->notifier_block->flags & NOUVEAU_MEM_PCI) { + target = NV_DMA_TARGET_PCI_NONLINEAR; + } else { + DRM_ERROR("Bad DMA target, flags 0x%08x!\n", + chan->notifier_block->flags); + return -EINVAL; + } + offset += mem->start; + + if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + offset, mem->size, + NV_DMA_ACCESS_RW, target, &nobj))) { + nouveau_mem_free_block(mem); + DRM_ERROR("Error creating notifier ctxdma: %d\n", ret); + return ret; + } + nobj->dtor = nouveau_notifier_gpuobj_dtor; + nobj->priv = mem; + + if ((ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL))) { + nouveau_gpuobj_del(dev, &nobj); + nouveau_mem_free_block(mem); + DRM_ERROR("Error referencing notifier ctxdma: %d\n", ret); + return ret; + } + + *b_offset = mem->start; + return 0; +} + +int +nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_nouveau_notifierobj_alloc *na = data; + struct nouveau_channel *chan; + int ret; + + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan); + + ret = nouveau_notifier_alloc(chan, na->handle, na->count, &na->offset); + if (ret) + return ret; + + return 0; +} + diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index e36568c6..fbce7702 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -35,79 +35,6 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" -/* TODO - * - Check object class, deny unsafe objects (add card-specific versioning?) - * - Get rid of DMA object creation, this should be wrapped by MM routines. - */ - -/* Translate a RAMIN offset into a value the card understands, will be useful - * in the future when we can access more instance ram which isn't mapped into - * the PRAMIN aperture - */ -uint32_t -nouveau_chip_instance_get(drm_device_t *dev, struct mem_block *mem) -{ - uint32_t inst = (uint32_t)mem->start >> 4; - DRM_DEBUG("****** on-chip instance for 0x%016llx = 0x%08x\n", - mem->start, inst); - return inst; -} - -static void -nouveau_object_link(drm_device_t *dev, struct nouveau_object *obj) -{ - drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[obj->channel]; - - if (!chan->objs) { - chan->objs = obj; - return; - } - - obj->prev = NULL; - obj->next = chan->objs; - - chan->objs->prev = obj; - chan->objs = obj; -} - -static void -nouveau_object_unlink(drm_device_t *dev, struct nouveau_object *obj) -{ - drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[obj->channel]; - - if (obj->prev == NULL) { - if (obj->next) - obj->next->prev = NULL; - chan->objs = obj->next; - } else if (obj->next == NULL) { - if (obj->prev) - obj->prev->next = NULL; - } else { - obj->prev->next = obj->next; - obj->next->prev = obj->prev; - } -} - -static struct nouveau_object * -nouveau_object_handle_find(drm_device_t *dev, int channel, uint32_t handle) -{ - drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - struct nouveau_object *obj = chan->objs; - - DRM_DEBUG("Looking for handle 0x%08x\n", handle); - while (obj) { - if (obj->handle == handle) - return obj; - obj = obj->next; - } - - DRM_DEBUG("...couldn't find handle\n"); - return NULL; -} - /* NVidia uses context objects to drive drawing operations. Context objects can be selected into 8 subchannels in the FIFO, @@ -139,130 +66,550 @@ nouveau_object_handle_find(drm_device_t *dev, int channel, uint32_t handle) is given as: */ static uint32_t -nouveau_ht_handle_hash(drm_device_t *dev, int channel, uint32_t handle) +nouveau_ramht_hash_handle(struct drm_device *dev, int channel, uint32_t handle) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_nouveau_private *dev_priv=dev->dev_private; uint32_t hash = 0; int i; + DRM_DEBUG("ch%d handle=0x%08x\n", channel, handle); + for (i=32;i>0;i-=dev_priv->ramht_bits) { hash ^= (handle & ((1 << dev_priv->ramht_bits) - 1)); handle >>= dev_priv->ramht_bits; } - hash ^= channel << (dev_priv->ramht_bits - 4); - return hash << 3; + if (dev_priv->card_type < NV_50) + hash ^= channel << (dev_priv->ramht_bits - 4); + hash <<= 3; + + DRM_DEBUG("hash=0x%08x\n", hash); + return hash; } static int -nouveau_ht_object_insert(drm_device_t* dev, int channel, uint32_t handle, - struct nouveau_object *obj) +nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht, + uint32_t offset) { - drm_nouveau_private_t *dev_priv=dev->dev_private; - int ht_base = NV_RAMIN + dev_priv->ramht_offset; - int ht_end = ht_base + dev_priv->ramht_size; - int o_ofs, ofs; - - obj->handle = handle; - o_ofs = ofs = nouveau_ht_handle_hash(dev, channel, obj->handle); - - while (NV_READ(ht_base + ofs) || NV_READ(ht_base + ofs + 4)) { - ofs += 8; - if (ofs == dev_priv->ramht_size) ofs = 0; - if (ofs == o_ofs) { - DRM_ERROR("no free hash table entries\n"); - return 1; + struct drm_nouveau_private *dev_priv=dev->dev_private; + uint32_t ctx = INSTANCE_RD(ramht, (offset + 4)/4); + + if (dev_priv->card_type < NV_40) + return ((ctx & NV_RAMHT_CONTEXT_VALID) != 0); + return (ctx != 0); +} + +static int +nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) +{ + struct drm_nouveau_private *dev_priv=dev->dev_private; + struct nouveau_channel *chan = dev_priv->fifos[ref->channel]; + struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; + struct nouveau_gpuobj *gpuobj = ref->gpuobj; + uint32_t ctx, co, ho; + + if (!ramht) { + DRM_ERROR("No hash table!\n"); + return -EINVAL; + } + + if (dev_priv->card_type < NV_40) { + ctx = NV_RAMHT_CONTEXT_VALID | (ref->instance >> 4) | + (ref->channel << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | + (gpuobj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT); + } else + if (dev_priv->card_type < NV_50) { + ctx = (ref->instance >> 4) | + (ref->channel << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) | + (gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT); + } else { + ctx = (ref->instance >> 4) | + (gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT); + } + + co = ho = nouveau_ramht_hash_handle(dev, ref->channel, ref->handle); + do { + if (!nouveau_ramht_entry_valid(dev, ramht, co)) { + DRM_DEBUG("insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n", + ref->channel, co, ref->handle, ctx); + INSTANCE_WR(ramht, (co + 0)/4, ref->handle); + INSTANCE_WR(ramht, (co + 4)/4, ctx); + + list_add_tail(&ref->list, &chan->ramht_refs); + return 0; + } + DRM_DEBUG("collision ch%d 0x%08x: h=0x%08x\n", + ref->channel, co, INSTANCE_RD(ramht, co/4)); + + co += 8; + if (co >= dev_priv->ramht_size) { + DRM_INFO("no space left after collision\n"); + co = 0; + /* exit as it seems to cause crash with nouveau_demo and + * 0xdead0001 object */ + break; + } + } while (co != ho); + + DRM_ERROR("RAMHT space exhausted. ch=%d\n", ref->channel); + return -ENOMEM; +} + +static void +nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = dev_priv->fifos[ref->channel]; + struct nouveau_gpuobj *ramht = chan->ramht ? chan->ramht->gpuobj : NULL; + uint32_t co, ho; + + if (!ramht) { + DRM_ERROR("No hash table!\n"); + return; + } + + co = ho = nouveau_ramht_hash_handle(dev, ref->channel, ref->handle); + do { + if (nouveau_ramht_entry_valid(dev, ramht, co) && + (ref->handle == INSTANCE_RD(ramht, (co/4)))) { + DRM_DEBUG("remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n", + ref->channel, co, ref->handle, + INSTANCE_RD(ramht, (co + 4))); + INSTANCE_WR(ramht, (co + 0)/4, 0x00000000); + INSTANCE_WR(ramht, (co + 4)/4, 0x00000000); + + list_del(&ref->list); + return; } + + co += 8; + if (co >= dev_priv->ramht_size) + co = 0; + } while (co != ho); + + DRM_ERROR("RAMHT entry not found. ch=%d, handle=0x%08x\n", + ref->channel, ref->handle); +} + +int +nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, + int size, int align, uint32_t flags, + struct nouveau_gpuobj **gpuobj_ret) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; + struct nouveau_gpuobj *gpuobj; + struct mem_block *pramin = NULL; + int ret; + + DRM_DEBUG("ch%d size=%d align=%d flags=0x%08x\n", + chan ? chan->id : -1, size, align, flags); + + if (!dev_priv || !gpuobj_ret || *gpuobj_ret != NULL) + return -EINVAL; + + gpuobj = drm_calloc(1, sizeof(*gpuobj), DRM_MEM_DRIVER); + if (!gpuobj) + return -ENOMEM; + DRM_DEBUG("gpuobj %p\n", gpuobj); + gpuobj->flags = flags; + gpuobj->im_channel = chan ? chan->id : -1; + + list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); + + /* Choose between global instmem heap, and per-channel private + * instmem heap. On <NV50 allow requests for private instmem + * to be satisfied from global heap if no per-channel area + * available. + */ + if (chan) { + if (chan->ramin_heap) { + DRM_DEBUG("private heap\n"); + pramin = chan->ramin_heap; + } else + if (dev_priv->card_type < NV_50) { + DRM_DEBUG("global heap fallback\n"); + pramin = dev_priv->ramin_heap; + } + } else { + DRM_DEBUG("global heap\n"); + pramin = dev_priv->ramin_heap; } - ofs += ht_base; - DRM_DEBUG("Channel %d - Handle 0x%08x at 0x%08x\n", - channel, obj->handle, ofs); + if (!pramin) { + DRM_ERROR("No PRAMIN heap!\n"); + return -EINVAL; + } + + if (!chan && (ret = engine->instmem.populate(dev, gpuobj, &size))) { + nouveau_gpuobj_del(dev, &gpuobj); + return ret; + } + + /* Allocate a chunk of the PRAMIN aperture */ + gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size, + drm_order(align), + (struct drm_file *)-2); + if (!gpuobj->im_pramin) { + nouveau_gpuobj_del(dev, &gpuobj); + return -ENOMEM; + } + gpuobj->im_pramin->flags = NOUVEAU_MEM_INSTANCE; + + if (!chan && (ret = engine->instmem.bind(dev, gpuobj))) { + nouveau_gpuobj_del(dev, &gpuobj); + return ret; + } + + if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { + int i; + + for (i = 0; i < gpuobj->im_pramin->size; i += 4) + INSTANCE_WR(gpuobj, i/4, 0); + } + + *gpuobj_ret = gpuobj; + return 0; +} + +int +nouveau_gpuobj_early_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + DRM_DEBUG("\n"); + + INIT_LIST_HEAD(&dev_priv->gpuobj_list); - NV_WRITE(NV_RAMHT_HANDLE_OFFSET + ofs, obj->handle); - if (dev_priv->card_type >= NV_40) - NV_WRITE(NV_RAMHT_CONTEXT_OFFSET + ofs, - (channel << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) | - (obj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT) | - nouveau_chip_instance_get(dev, obj->instance) - ); - else - NV_WRITE(NV_RAMHT_CONTEXT_OFFSET + ofs, - NV_RAMHT_CONTEXT_VALID | - (channel << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | - (obj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT) | - nouveau_chip_instance_get(dev, obj->instance) - ); - - obj->ht_loc = ofs; return 0; } -static void nouveau_hash_table_remove(drm_device_t* dev, - struct nouveau_object *obj) +int +nouveau_gpuobj_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + DRM_DEBUG("\n"); + + if (dev_priv->card_type < NV_50) { + if ((ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramht_offset, + ~0, dev_priv->ramht_size, + NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ALLOW_NO_REFS, + &dev_priv->ramht, NULL))) + return ret; + } + + return 0; +} + +void +nouveau_gpuobj_takedown(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + DRM_DEBUG("\n"); + + nouveau_gpuobj_del(dev, &dev_priv->ramht); +} + +void +nouveau_gpuobj_late_takedown(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *gpuobj = NULL; + struct list_head *entry, *tmp; + + DRM_DEBUG("\n"); + + list_for_each_safe(entry, tmp, &dev_priv->gpuobj_list) { + gpuobj = list_entry(entry, struct nouveau_gpuobj, list); + + DRM_ERROR("gpuobj %p still exists at takedown, refs=%d\n", + gpuobj, gpuobj->refcount); + gpuobj->refcount = 0; + nouveau_gpuobj_del(dev, &gpuobj); + } +} + +int +nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; + struct nouveau_gpuobj *gpuobj; + + DRM_DEBUG("gpuobj %p\n", pgpuobj ? *pgpuobj : NULL); - DRM_DEBUG("Remove handle 0x%08x at 0x%08x from HT\n", - obj->handle, obj->ht_loc); - if (obj->ht_loc) { - DRM_DEBUG("... HT entry was: 0x%08x/0x%08x\n", - NV_READ(obj->ht_loc), NV_READ(obj->ht_loc+4)); - NV_WRITE(obj->ht_loc , 0x00000000); - NV_WRITE(obj->ht_loc+4, 0x00000000); + if (!dev_priv || !pgpuobj || !(*pgpuobj)) + return -EINVAL; + gpuobj = *pgpuobj; + + if (gpuobj->refcount != 0) { + DRM_ERROR("gpuobj refcount is %d\n", gpuobj->refcount); + return -EINVAL; } + + if (gpuobj->dtor) + gpuobj->dtor(dev, gpuobj); + + if (gpuobj->im_backing) { + if (gpuobj->flags & NVOBJ_FLAG_FAKE) + drm_free(gpuobj->im_backing, + sizeof(*gpuobj->im_backing), DRM_MEM_DRIVER); + else + engine->instmem.clear(dev, gpuobj); + } + + if (gpuobj->im_pramin) { + if (gpuobj->flags & NVOBJ_FLAG_FAKE) + drm_free(gpuobj->im_pramin, sizeof(*gpuobj->im_pramin), + DRM_MEM_DRIVER); + else + nouveau_mem_free_block(gpuobj->im_pramin); + } + + list_del(&gpuobj->list); + + *pgpuobj = NULL; + drm_free(gpuobj, sizeof(*gpuobj), DRM_MEM_DRIVER); + return 0; } -static struct nouveau_object * -nouveau_object_instance_alloc(drm_device_t* dev, int channel) +static int +nouveau_gpuobj_instance_get(struct drm_device *dev, + struct nouveau_channel *chan, + struct nouveau_gpuobj *gpuobj, uint32_t *inst) { - drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_object *obj; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *cpramin; + + /* <NV50 use PRAMIN address everywhere */ + if (dev_priv->card_type < NV_50) { + *inst = gpuobj->im_pramin->start; + return 0; + } - /* Create object struct */ - obj = drm_calloc(1, sizeof(struct nouveau_object), DRM_MEM_DRIVER); - if (!obj) { - DRM_ERROR("couldn't alloc memory for object\n"); - return NULL; + if (chan && gpuobj->im_channel != chan->id) { + DRM_ERROR("Channel mismatch: obj %d, ref %d\n", + gpuobj->im_channel, chan->id); + return -EINVAL; } - /* Allocate instance memory */ - obj->instance = nouveau_instmem_alloc(dev, - (dev_priv->card_type >= NV_40 ? 32 : 16), 4); - if (!obj->instance) { - DRM_ERROR("couldn't alloc RAMIN for object\n"); - drm_free(obj, sizeof(struct nouveau_object), DRM_MEM_DRIVER); - return NULL; + /* NV50 channel-local instance */ + if (chan > 0) { + cpramin = chan->ramin->gpuobj; + *inst = gpuobj->im_pramin->start - cpramin->im_pramin->start; + return 0; } - /* Bind object to channel */ - obj->channel = channel; - obj->handle = ~0; - nouveau_object_link(dev, obj); + /* NV50 global (VRAM) instance */ + if (gpuobj->im_channel < 0) { + /* ...from global heap */ + if (!gpuobj->im_backing) { + DRM_ERROR("AII, no VRAM backing gpuobj\n"); + return -EINVAL; + } + *inst = gpuobj->im_backing->start; + return 0; + } else { + /* ...from local heap */ + cpramin = dev_priv->fifos[gpuobj->im_channel]->ramin->gpuobj; + *inst = cpramin->im_backing->start + + (gpuobj->im_pramin->start - cpramin->im_pramin->start); + return 0; + } - return obj; + return -EINVAL; } -static void -nouveau_object_instance_free(drm_device_t *dev, struct nouveau_object *obj) +int +nouveau_gpuobj_ref_add(struct drm_device *dev, struct nouveau_channel *chan, + uint32_t handle, struct nouveau_gpuobj *gpuobj, + struct nouveau_gpuobj_ref **ref_ret) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj_ref *ref; + uint32_t instance; + int ret; + + DRM_DEBUG("ch%d h=0x%08x gpuobj=%p\n", + chan ? chan->id : -1, handle, gpuobj); + + if (!dev_priv || !gpuobj || (ref_ret && *ref_ret != NULL)) + return -EINVAL; + + if (!chan && !ref_ret) + return -EINVAL; + + ret = nouveau_gpuobj_instance_get(dev, chan, gpuobj, &instance); + if (ret) + return ret; + + ref = drm_calloc(1, sizeof(*ref), DRM_MEM_DRIVER); + if (!ref) + return -ENOMEM; + ref->gpuobj = gpuobj; + ref->channel = chan ? chan->id : -1; + ref->instance = instance; + + if (!ref_ret) { + ref->handle = handle; + + ret = nouveau_ramht_insert(dev, ref); + if (ret) { + drm_free(ref, sizeof(*ref), DRM_MEM_DRIVER); + return ret; + } + } else { + ref->handle = ~0; + *ref_ret = ref; + } + + ref->gpuobj->refcount++; + return 0; +} + +int nouveau_gpuobj_ref_del(struct drm_device *dev, struct nouveau_gpuobj_ref **pref) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct nouveau_gpuobj_ref *ref; + + DRM_DEBUG("ref %p\n", pref ? *pref : NULL); + + if (!dev || !pref || *pref == NULL) + return -EINVAL; + ref = *pref; + + if (ref->handle != ~0) + nouveau_ramht_remove(dev, ref); + + if (ref->gpuobj) { + ref->gpuobj->refcount--; + + if (ref->gpuobj->refcount == 0) { + if (!(ref->gpuobj->flags & NVOBJ_FLAG_ALLOW_NO_REFS)) + nouveau_gpuobj_del(dev, &ref->gpuobj); + } + } + + *pref = NULL; + drm_free(ref, sizeof(ref), DRM_MEM_DRIVER); + return 0; +} + +int +nouveau_gpuobj_new_ref(struct drm_device *dev, + struct nouveau_channel *oc, struct nouveau_channel *rc, + uint32_t handle, int size, int align, uint32_t flags, + struct nouveau_gpuobj_ref **ref) +{ + struct nouveau_gpuobj *gpuobj = NULL; + int ret; + + if ((ret = nouveau_gpuobj_new(dev, oc, size, align, flags, &gpuobj))) + return ret; + + if ((ret = nouveau_gpuobj_ref_add(dev, rc, handle, gpuobj, ref))) { + nouveau_gpuobj_del(dev, &gpuobj); + return ret; + } + + return 0; +} + +int +nouveau_gpuobj_ref_find(struct nouveau_channel *chan, uint32_t handle, + struct nouveau_gpuobj_ref **ref_ret) +{ + struct nouveau_gpuobj_ref *ref; + struct list_head *entry, *tmp; + + list_for_each_safe(entry, tmp, &chan->ramht_refs) { + ref = list_entry(entry, struct nouveau_gpuobj_ref, list); + + if (ref->handle == handle) { + if (ref_ret) + *ref_ret = ref; + return 0; + } + } + + return -EINVAL; +} + +int +nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset, + uint32_t b_offset, uint32_t size, + uint32_t flags, struct nouveau_gpuobj **pgpuobj, + struct nouveau_gpuobj_ref **pref) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *gpuobj = NULL; int i; - /* Unbind object from channel */ - nouveau_object_unlink(dev, obj); + DRM_DEBUG("p_offset=0x%08x b_offset=0x%08x size=0x%08x flags=0x%08x\n", + p_offset, b_offset, size, flags); + + gpuobj = drm_calloc(1, sizeof(*gpuobj), DRM_MEM_DRIVER); + if (!gpuobj) + return -ENOMEM; + DRM_DEBUG("gpuobj %p\n", gpuobj); + gpuobj->im_channel = -1; + gpuobj->flags = flags | NVOBJ_FLAG_FAKE; + + list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); - /* Clean RAMIN entry */ - DRM_DEBUG("Instance entry for 0x%08x" - "(engine %d, class 0x%x) before destroy:\n", - obj->handle, obj->engine, obj->class); - for (i=0; i<(obj->instance->size/4); i++) { - DRM_DEBUG(" +0x%02x: 0x%08x\n", (i*4), - INSTANCE_RD(obj->instance, i)); - INSTANCE_WR(obj->instance, i, 0x00000000); + if (p_offset != ~0) { + gpuobj->im_pramin = drm_calloc(1, sizeof(struct mem_block), + DRM_MEM_DRIVER); + if (!gpuobj->im_pramin) { + nouveau_gpuobj_del(dev, &gpuobj); + return -ENOMEM; + } + gpuobj->im_pramin->start = p_offset; + gpuobj->im_pramin->size = size; + } + + if (b_offset != ~0) { + gpuobj->im_backing = drm_calloc(1, sizeof(struct mem_block), + DRM_MEM_DRIVER); + if (!gpuobj->im_backing) { + nouveau_gpuobj_del(dev, &gpuobj); + return -ENOMEM; + } + gpuobj->im_backing->start = b_offset; + gpuobj->im_backing->size = size; } - /* Free RAMIN */ - nouveau_instmem_free(dev, obj->instance); + if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { + for (i = 0; i < gpuobj->im_pramin->size; i += 4) + INSTANCE_WR(gpuobj, i/4, 0); + } + + if (pref) { + if ((i = nouveau_gpuobj_ref_add(dev, NULL, 0, gpuobj, pref))) { + nouveau_gpuobj_del(dev, &gpuobj); + return i; + } + } + + if (pgpuobj) + *pgpuobj = gpuobj; + return 0; +} + + +static int +nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + /*XXX: dodgy hack for now */ + if (dev_priv->card_type >= NV_50) + return 24; + if (dev_priv->card_type >= NV_40) + return 32; + return 16; } /* @@ -278,76 +625,191 @@ nouveau_object_instance_free(drm_device_t *dev, struct nouveau_object *obj) 17:16 target: 0 NV memory, 1 NV memory tiled, 2 PCI, 3 AGP 31:20 dma adjust (bits 0-11 of the address) entry[1] - dma limit - entry[2] + dma limit (size of transfer) + entry[X] 1 0 readonly, 1 readwrite - 31:12 dma frame address (bits 12-31 of the address) + 31:12 dma frame address of the page (bits 12-31 of the address) + entry[N] + page table terminator, same value as the first pte, as does nvidia + rivatv uses 0xffffffff - Non linear page tables seem to need a list of frame addresses afterwards, - the rivatv project has some info on this. + Non linear page tables need a list of frame addresses afterwards, + the rivatv project has some info on this. The method below creates a DMA object in instance RAM and returns a handle to it that can be used to set up context objects. */ - -struct nouveau_object * -nouveau_object_dma_create(drm_device_t* dev, int channel, int class, - uint32_t offset, uint32_t size, - int access, int target) +int +nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, + uint64_t offset, uint64_t size, int access, + int target, struct nouveau_gpuobj **gpuobj) { - drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_object *obj; - uint32_t frame, adjust; - uint32_t pte_flags = 0; + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + uint32_t is_scatter_gather = 0; + + /* Total number of pages covered by the request. + */ + const unsigned int page_count = (size + PAGE_SIZE - 1) / PAGE_SIZE; - DRM_DEBUG("offset:0x%08x, size:0x%08x, target:%d, access:%d\n", - offset, size, target, access); + + DRM_DEBUG("ch%d class=0x%04x offset=0x%llx size=0x%llx\n", + chan->id, class, offset, size); + DRM_DEBUG("access=%d target=%d\n", access, target); switch (target) { - case NV_DMA_TARGET_AGP: - offset += dev_priv->agp_phys; - break; - default: - break; + case NV_DMA_TARGET_AGP: + offset += dev_priv->gart_info.aper_base; + break; + case NV_DMA_TARGET_PCI_NONLINEAR: + /*assume the "offset" is a virtual memory address*/ + is_scatter_gather = 1; + /*put back the right value*/ + target = NV_DMA_TARGET_PCI; + break; + default: + break; + } + + ret = nouveau_gpuobj_new(dev, chan, + is_scatter_gather ? ((page_count << 2) + 12) : nouveau_gpuobj_class_instmem_size(dev, class), + 16, + NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, + gpuobj); + if (ret) { + DRM_ERROR("Error creating gpuobj: %d\n", ret); + return ret; } - switch (access) { - case NV_DMA_ACCESS_RO: - break; - case NV_DMA_ACCESS_WO: - case NV_DMA_ACCESS_RW: - pte_flags |= (1 << 1); - break; - default: - DRM_ERROR("invalid access mode=%d\n", access); - return NULL; - } + if (dev_priv->card_type < NV_50) { + uint32_t frame, adjust, pte_flags = 0; + adjust = offset & 0x00000fff; + if (access != NV_DMA_ACCESS_RO) + pte_flags |= (1<<1); + + if ( ! is_scatter_gather ) + { + frame = offset & ~0x00000fff; + + INSTANCE_WR(*gpuobj, 0, ((1<<12) | (1<<13) | + (adjust << 20) | + (access << 14) | + (target << 16) | + class)); + INSTANCE_WR(*gpuobj, 1, size - 1); + INSTANCE_WR(*gpuobj, 2, frame | pte_flags); + INSTANCE_WR(*gpuobj, 3, frame | pte_flags); + } + else + { + /* Intial page entry in the scatter-gather area that + * corresponds to the base offset + */ + unsigned int idx = offset / PAGE_SIZE; + + uint32_t instance_offset; + unsigned int i; + + if ((idx + page_count) > dev->sg->pages) { + DRM_ERROR("Requested page range exceedes " + "allocated scatter-gather range!"); + return -E2BIG; + } + + DRM_DEBUG("Creating PCI DMA object using virtual zone starting at %#llx, size %d\n", offset, (uint32_t)size); + INSTANCE_WR(*gpuobj, 0, ((1<<12) | (0<<13) | + (adjust << 20) | + (access << 14) | + (target << 16) | + class)); + INSTANCE_WR(*gpuobj, 1, (uint32_t) size-1); + + + /*write starting at the third dword*/ + instance_offset = 2; + + /*for each PAGE, get its bus address, fill in the page table entry, and advance*/ + for (i = 0; i < page_count; i++) { + if (dev->sg->busaddr[idx] == 0) { + dev->sg->busaddr[idx] = + pci_map_page(dev->pdev, + dev->sg->pagelist[idx], + 0, + PAGE_SIZE, + DMA_BIDIRECTIONAL); + + if (dma_mapping_error(dev->sg->busaddr[idx])) { + return -ENOMEM; + } + } + + frame = (uint32_t) dev->sg->busaddr[idx]; + INSTANCE_WR(*gpuobj, instance_offset, + frame | pte_flags); + + idx++; + instance_offset ++; + } + } + } else { + uint32_t flags0, flags5; - frame = offset & ~0x00000FFF; - adjust = offset & 0x00000FFF; + if (target == NV_DMA_TARGET_VIDMEM) { + flags0 = 0x00190000; + flags5 = 0x00010000; + } else { + flags0 = 0x7fc00000; + flags5 = 0x00080000; + } - obj = nouveau_object_instance_alloc(dev, channel); - if (!obj) { - DRM_ERROR("couldn't allocate DMA object\n"); - return obj; + INSTANCE_WR(*gpuobj, 0, flags0 | class); + INSTANCE_WR(*gpuobj, 1, offset + size - 1); + INSTANCE_WR(*gpuobj, 2, offset); + INSTANCE_WR(*gpuobj, 5, flags5); } - obj->engine = 0; - obj->class = class; + (*gpuobj)->engine = NVOBJ_ENGINE_SW; + (*gpuobj)->class = class; + return 0; +} - INSTANCE_WR(obj->instance, 0, ((1<<12) | (1<<13) | - (adjust << 20) | - (access << 14) | - (target << 16) | - class)); - INSTANCE_WR(obj->instance, 1, size-1); - INSTANCE_WR(obj->instance, 2, frame | pte_flags); - INSTANCE_WR(obj->instance, 3, frame | pte_flags); +int +nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan, + uint64_t offset, uint64_t size, int access, + struct nouveau_gpuobj **gpuobj, + uint32_t *o_ret) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + if (dev_priv->gart_info.type == NOUVEAU_GART_AGP || + (dev_priv->card_type >= NV_50 && + dev_priv->gart_info.type == NOUVEAU_GART_SGDMA)) { + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + offset, size, access, + NV_DMA_TARGET_AGP, gpuobj); + if (o_ret) + *o_ret = 0; + } else + if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) { + *gpuobj = dev_priv->gart_info.sg_ctxdma; + if (offset & ~0xffffffffULL) { + DRM_ERROR("obj offset exceeds 32-bits\n"); + return -EINVAL; + } + if (o_ret) + *o_ret = (uint32_t)offset; + ret = (*gpuobj != NULL) ? 0 : -EINVAL; + } else { + DRM_ERROR("Invalid GART type %d\n", dev_priv->gart_info.type); + return -EINVAL; + } - return obj; + return ret; } - /* Context objects in the instance RAM have the following structure. * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes. @@ -399,205 +861,287 @@ nouveau_object_dma_create(drm_device_t* dev, int channel, int class, entry[5]: set to 0? */ -struct nouveau_object * -nouveau_object_gr_create(drm_device_t* dev, int channel, int class) +int +nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, + struct nouveau_gpuobj **gpuobj) { - drm_nouveau_private_t *dev_priv=dev->dev_private; - struct nouveau_object *obj; - - DRM_DEBUG("class=%x\n", class); - - obj = nouveau_object_instance_alloc(dev, channel); - if (!obj) { - DRM_ERROR("couldn't allocate context object\n"); - return obj; + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + DRM_DEBUG("ch%d class=0x%04x\n", chan->id, class); + + ret = nouveau_gpuobj_new(dev, chan, + nouveau_gpuobj_class_instmem_size(dev, class), + 16, + NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, + gpuobj); + if (ret) { + DRM_ERROR("Error creating gpuobj: %d\n", ret); + return ret; } - obj->engine = 1; - obj->class = class; - + if (dev_priv->card_type >= NV_50) { + INSTANCE_WR(*gpuobj, 0, class); + INSTANCE_WR(*gpuobj, 5, 0x00010000); + } else { switch (class) { case NV_CLASS_NULL: - INSTANCE_WR(obj->instance, 0, 0x00001030); - INSTANCE_WR(obj->instance, 1, 0xFFFFFFFF); - INSTANCE_WR(obj->instance, 2, 0x00000000); - INSTANCE_WR(obj->instance, 2, 0x00000000); + INSTANCE_WR(*gpuobj, 0, 0x00001030); + INSTANCE_WR(*gpuobj, 1, 0xFFFFFFFF); break; default: if (dev_priv->card_type >= NV_40) { - INSTANCE_WR(obj->instance, 0, obj->class); - INSTANCE_WR(obj->instance, 1, 0x00000000); + INSTANCE_WR(*gpuobj, 0, class); #ifdef __BIG_ENDIAN - INSTANCE_WR(obj->instance, 2, 0x01000000); -#else - INSTANCE_WR(obj->instance, 2, 0x00000000); + INSTANCE_WR(*gpuobj, 2, 0x01000000); #endif - INSTANCE_WR(obj->instance, 3, 0x00000000); - INSTANCE_WR(obj->instance, 4, 0x00000000); - INSTANCE_WR(obj->instance, 5, 0x00000000); - INSTANCE_WR(obj->instance, 6, 0x00000000); - INSTANCE_WR(obj->instance, 7, 0x00000000); } else { #ifdef __BIG_ENDIAN - INSTANCE_WR(obj->instance, 0, obj->class | 0x00080000); + INSTANCE_WR(*gpuobj, 0, class | 0x00080000); #else - INSTANCE_WR(obj->instance, 0, obj->class); + INSTANCE_WR(*gpuobj, 0, class); #endif - INSTANCE_WR(obj->instance, 1, 0x00000000); - INSTANCE_WR(obj->instance, 2, 0x00000000); - INSTANCE_WR(obj->instance, 3, 0x00000000); } } + } - return obj; -} - -void -nouveau_object_free(drm_device_t *dev, struct nouveau_object *obj) -{ - nouveau_object_instance_free(dev, obj); - if (obj->handle != ~0) - nouveau_hash_table_remove(dev, obj); - drm_free(obj, sizeof(struct nouveau_object), DRM_MEM_DRIVER); + (*gpuobj)->engine = NVOBJ_ENGINE_GR; + (*gpuobj)->class = class; + return 0; } -void nouveau_object_cleanup(drm_device_t *dev, int channel) +static int +nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *pramin = NULL; + int size, base, ret; + + DRM_DEBUG("ch%d\n", chan->id); + + /* Base amount for object storage (4KiB enough?) */ + size = 0x1000; + base = 0; + + /* PGRAPH context */ + + if (dev_priv->card_type == NV_50) { + /* Various fixed table thingos */ + size += 0x1400; /* mostly unknown stuff */ + size += 0x4000; /* vm pd */ + base = 0x6000; + /* RAMHT, not sure about setting size yet, 32KiB to be safe */ + size += 0x8000; + /* RAMFC */ + size += 0x1000; + /* PGRAPH context */ + size += 0x60000; + } - while (dev_priv->fifos[channel].objs) { - nouveau_object_free(dev, dev_priv->fifos[channel].objs); + DRM_DEBUG("ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n", + chan->id, size, base); + ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0, + &chan->ramin); + if (ret) { + DRM_ERROR("Error allocating channel PRAMIN: %d\n", ret); + return ret; + } + pramin = chan->ramin->gpuobj; + + ret = nouveau_mem_init_heap(&chan->ramin_heap, + pramin->im_pramin->start + base, size); + if (ret) { + DRM_ERROR("Error creating PRAMIN heap: %d\n", ret); + nouveau_gpuobj_ref_del(dev, &chan->ramin); + return ret; } + + return 0; } -int nouveau_ioctl_object_init(DRM_IOCTL_ARGS) +int +nouveau_gpuobj_channel_init(struct nouveau_channel *chan, + uint32_t vram_h, uint32_t tt_h) { - DRM_DEVICE; - drm_nouveau_object_init_t init; - struct nouveau_object *obj; + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *vram = NULL, *tt = NULL; + int ret, i; + + INIT_LIST_HEAD(&chan->ramht_refs); + + DRM_DEBUG("ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); + + /* Reserve a block of PRAMIN for the channel + *XXX: maybe on <NV50 too at some point + */ + if (0 || dev_priv->card_type == NV_50) { + ret = nouveau_gpuobj_channel_init_pramin(chan); + if (ret) + return ret; + } - DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_object_init_t __user *) - data, sizeof(init)); + /* NV50 VM, point offset 0-512MiB at shared PCIEGART table */ + if (dev_priv->card_type >= NV_50) { + uint32_t vm_offset; + + vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200; + vm_offset += chan->ramin->gpuobj->im_pramin->start; + if ((ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000, + 0, &chan->vm_pd, NULL))) + return ret; + for (i=0; i<0x4000; i+=8) { + INSTANCE_WR(chan->vm_pd, (i+0)/4, 0x00000000); + INSTANCE_WR(chan->vm_pd, (i+4)/4, 0xdeadcafe); + } - if (!nouveau_fifo_owner(dev, filp, init.channel)) { - DRM_ERROR("pid %d doesn't own channel %d\n", - DRM_CURRENTPID, init.channel); - return DRM_ERR(EINVAL); + if ((ret = nouveau_gpuobj_ref_add(dev, NULL, 0, + dev_priv->gart_info.sg_ctxdma, + &chan->vm_gart_pt))) + return ret; + INSTANCE_WR(chan->vm_pd, (0+0)/4, + chan->vm_gart_pt->instance | 0x03); + INSTANCE_WR(chan->vm_pd, (0+4)/4, 0x00000000); } - //FIXME: check args, only allow trusted objects to be created + /* RAMHT */ + if (dev_priv->card_type < NV_50) { + ret = nouveau_gpuobj_ref_add(dev, NULL, 0, dev_priv->ramht, + &chan->ramht); + if (ret) + return ret; + } else { + ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, + 0x8000, 16, + NVOBJ_FLAG_ZERO_ALLOC, + &chan->ramht); + if (ret) + return ret; + } + + /* VRAM ctxdma */ + if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + 0, dev_priv->fb_available_size, + NV_DMA_ACCESS_RW, + NV_DMA_TARGET_VIDMEM, &vram))) { + DRM_ERROR("Error creating VRAM ctxdma: %d\n", ret); + return ret; + } - if (nouveau_object_handle_find(dev, init.channel, init.handle)) { - DRM_ERROR("Channel %d: handle 0x%08x already exists\n", - init.channel, init.handle); - return DRM_ERR(EINVAL); + if ((ret = nouveau_gpuobj_ref_add(dev, chan, vram_h, vram, NULL))) { + DRM_ERROR("Error referencing VRAM ctxdma: %d\n", ret); + return ret; } - obj = nouveau_object_gr_create(dev, init.channel, init.class); - if (!obj) - return DRM_ERR(ENOMEM); + /* TT memory ctxdma */ + if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) { + ret = nouveau_gpuobj_gart_dma_new(chan, 0, + dev_priv->gart_info.aper_size, + NV_DMA_ACCESS_RW, &tt, NULL); + } else + if (dev_priv->pci_heap) { + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + 0, dev->sg->pages * PAGE_SIZE, + NV_DMA_ACCESS_RW, + NV_DMA_TARGET_PCI_NONLINEAR, &tt); + } else { + DRM_ERROR("Invalid GART type %d\n", dev_priv->gart_info.type); + ret = -EINVAL; + } + + if (ret) { + DRM_ERROR("Error creating TT ctxdma: %d\n", ret); + return ret; + } - if (nouveau_ht_object_insert(dev, init.channel, init.handle, obj)) { - nouveau_object_free(dev, obj); - return DRM_ERR(ENOMEM); + ret = nouveau_gpuobj_ref_add(dev, chan, tt_h, tt, NULL); + if (ret) { + DRM_ERROR("Error referencing TT ctxdma: %d\n", ret); + return ret; } return 0; } -static int -nouveau_dma_object_check_access(drm_device_t *dev, - drm_nouveau_dma_object_init_t *init) +void +nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - uint64_t limit; - - /* Check for known DMA object classes */ - switch (init->class) { - case NV_CLASS_DMA_IN_MEMORY: - case NV_CLASS_DMA_FROM_MEMORY: - case NV_CLASS_DMA_TO_MEMORY: - break; - default: - DRM_ERROR("invalid class = 0x%x\n", init->class); - return DRM_ERR(EPERM); - } + struct drm_device *dev = chan->dev; + struct list_head *entry, *tmp; + struct nouveau_gpuobj_ref *ref; - /* Check access mode, and translate to NV_DMA_ACCESS_* */ - switch (init->access) { - case NOUVEAU_MEM_ACCESS_RO: - init->access = NV_DMA_ACCESS_RO; - break; - case NOUVEAU_MEM_ACCESS_WO: - init->access = NV_DMA_ACCESS_WO; - break; - case NOUVEAU_MEM_ACCESS_RW: - init->access = NV_DMA_ACCESS_RW; - break; - default: - DRM_ERROR("invalid access mode = %d\n", init->access); - return DRM_ERR(EPERM); - } + DRM_DEBUG("ch%d\n", chan->id); - /* Check that request is within the allowed limits of "target" */ - switch (init->target) { - case NOUVEAU_MEM_FB: - limit = dev_priv->fb_available_size; - init->target = NV_DMA_TARGET_VIDMEM; - break; - case NOUVEAU_MEM_AGP: - limit = dev_priv->agp_available_size; - init->target = NV_DMA_TARGET_AGP; - break; - default: - DRM_ERROR("invalid target = 0x%x\n", init->target); - return DRM_ERR(EPERM); - } + list_for_each_safe(entry, tmp, &chan->ramht_refs) { + ref = list_entry(entry, struct nouveau_gpuobj_ref, list); - if ((init->offset > limit) || (init->offset + init->size) > limit) { - DRM_ERROR("access out of allowed range (%d,0x%08x,0x%08x)\n", - init->target, init->offset, init->size); - return DRM_ERR(EPERM); + nouveau_gpuobj_ref_del(dev, &ref); } - return 0; + nouveau_gpuobj_ref_del(dev, &chan->ramht); + + nouveau_gpuobj_del(dev, &chan->vm_pd); + nouveau_gpuobj_ref_del(dev, &chan->vm_gart_pt); + + if (chan->ramin_heap) + nouveau_mem_takedown(&chan->ramin_heap); + if (chan->ramin) + nouveau_gpuobj_ref_del(dev, &chan->ramin); + } -int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS) +int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; - drm_nouveau_dma_object_init_t init; - struct nouveau_object *obj; + struct nouveau_channel *chan; + struct drm_nouveau_grobj_alloc *init = data; + struct nouveau_gpuobj *gr = NULL; + int ret; - DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_dma_object_init_t __user *) - data, sizeof(init)); + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan); - if (!nouveau_fifo_owner(dev, filp, init.channel)) { - DRM_ERROR("pid %d doesn't own channel %d\n", - DRM_CURRENTPID, init.channel); - return DRM_ERR(EINVAL); + //FIXME: check args, only allow trusted objects to be created + + if (init->handle == ~0) + return -EINVAL; + + if (nouveau_gpuobj_ref_find(chan, init->handle, NULL) == 0) + return -EEXIST; + + ret = nouveau_gpuobj_gr_new(chan, init->class, &gr); + if (ret) { + DRM_ERROR("Error creating gr object: %d (%d/0x%08x)\n", + ret, init->channel, init->handle); + return ret; } - if (nouveau_dma_object_check_access(dev, &init)) - return DRM_ERR(EPERM); - - if (nouveau_object_handle_find(dev, init.channel, init.handle)) { - DRM_ERROR("Channel %d: handle 0x%08x already exists\n", - init.channel, init.handle); - return DRM_ERR(EINVAL); + if ((ret = nouveau_gpuobj_ref_add(dev, chan, init->handle, gr, NULL))) { + DRM_ERROR("Error referencing gr object: %d (%d/0x%08x\n)", + ret, init->channel, init->handle); + nouveau_gpuobj_del(dev, &gr); + return ret; } - obj = nouveau_object_dma_create(dev, init.channel, init.class, - init.offset, init.size, - init.access, init.target); - if (!obj) - return DRM_ERR(ENOMEM); + return 0; +} - obj->handle = init.handle; - if (nouveau_ht_object_insert(dev, init.channel, init.handle, obj)) { - nouveau_object_free(dev, obj); - return DRM_ERR(ENOMEM); - } +int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_nouveau_gpuobj_free *objfree = data; + struct nouveau_gpuobj_ref *ref; + struct nouveau_channel *chan; + int ret; + + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan); + + if ((ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref))) + return ret; + nouveau_gpuobj_ref_del(dev, &ref); return 0; } diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h index ea4a2f6b..4dc3b7fa 100644 --- a/shared-core/nouveau_reg.h +++ b/shared-core/nouveau_reg.h @@ -15,9 +15,6 @@ # define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 # define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 -#define NV03_PGRAPH_STATUS 0x004006b0 -#define NV04_PGRAPH_STATUS 0x00400700 - #define NV_RAMIN 0x00700000 #define NV_RAMHT_HANDLE_OFFSET 0 @@ -39,6 +36,8 @@ #define NV_DMA_TARGET_VIDMEM 0 #define NV_DMA_TARGET_PCI 2 #define NV_DMA_TARGET_AGP 3 +/*The following is not a real value used by nvidia cards, it's changed by nouveau_object_dma_create*/ +#define NV_DMA_TARGET_PCI_NONLINEAR 8 /* Some object classes we care about in the drm */ #define NV_CLASS_DMA_FROM_MEMORY 0x00000002 @@ -47,13 +46,18 @@ #define NV_CLASS_DMA_IN_MEMORY 0x0000003D #define NV03_FIFO_SIZE 0x8000UL -#define NV_MAX_FIFO_NUMBER 32 +#define NV_MAX_FIFO_NUMBER 128 #define NV03_FIFO_REGS_SIZE 0x10000 #define NV03_FIFO_REGS(i) (0x00800000+i*NV03_FIFO_REGS_SIZE) # define NV03_FIFO_REGS_DMAPUT(i) (NV03_FIFO_REGS(i)+0x40) # define NV03_FIFO_REGS_DMAGET(i) (NV03_FIFO_REGS(i)+0x44) +#define NV50_FIFO_REGS_SIZE 0x2000 +#define NV50_FIFO_REGS(i) (0x00c00000+i*NV50_FIFO_REGS_SIZE) +# define NV50_FIFO_REGS_DMAPUT(i) (NV50_FIFO_REGS(i)+0x40) +# define NV50_FIFO_REGS_DMAGET(i) (NV50_FIFO_REGS(i)+0x44) #define NV03_PMC_BOOT_0 0x00000000 +#define NV03_PMC_BOOT_1 0x00000004 #define NV03_PMC_INTR_0 0x00000100 # define NV_PMC_INTR_0_PFIFO_PENDING (1<< 8) # define NV_PMC_INTR_0_PGRAPH_PENDING (1<<12) @@ -74,6 +78,16 @@ #define NV40_PMC_1708 0x00001708 #define NV40_PMC_170C 0x0000170C +/* probably PMC ? */ +#define NV50_PUNK_BAR0_PRAMIN 0x00001700 +#define NV50_PUNK_BAR_CFG_BASE 0x00001704 +#define NV50_PUNK_BAR_CFG_BASE_VALID (1<<30) +#define NV50_PUNK_BAR1_CTXDMA 0x00001708 +#define NV50_PUNK_BAR1_CTXDMA_VALID (1<<31) +#define NV50_PUNK_BAR3_CTXDMA 0x0000170C +#define NV50_PUNK_BAR3_CTXDMA_VALID (1<<31) +#define NV50_PUNK_UNK1710 0x00001710 + #define NV04_PTIMER_INTR_0 0x00009100 #define NV04_PTIMER_INTR_EN_0 0x00009140 #define NV04_PTIMER_NUMERATOR 0x00009200 @@ -104,6 +118,35 @@ #define NV04_PGRAPH_DEBUG_3 0x0040008c #define NV10_PGRAPH_DEBUG_4 0x00400090 #define NV03_PGRAPH_INTR 0x00400100 +#define NV03_PGRAPH_NSTATUS 0x00400104 +# define NV04_PGRAPH_NSTATUS_STATE_IN_USE (1<<11) +# define NV04_PGRAPH_NSTATUS_INVALID_STATE (1<<12) +# define NV04_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<13) +# define NV04_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<14) +# define NV10_PGRAPH_NSTATUS_STATE_IN_USE (1<<23) +# define NV10_PGRAPH_NSTATUS_INVALID_STATE (1<<24) +# define NV10_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<25) +# define NV10_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<26) +#define NV03_PGRAPH_NSOURCE 0x00400108 +# define NV03_PGRAPH_NSOURCE_NOTIFICATION (1<< 0) +# define NV03_PGRAPH_NSOURCE_DATA_ERROR (1<< 1) +# define NV03_PGRAPH_NSOURCE_PROTECTION_ERROR (1<< 2) +# define NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION (1<< 3) +# define NV03_PGRAPH_NSOURCE_LIMIT_COLOR (1<< 4) +# define NV03_PGRAPH_NSOURCE_LIMIT_ZETA (1<< 5) +# define NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD (1<< 6) +# define NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION (1<< 7) +# define NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION (1<< 8) +# define NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION (1<< 9) +# define NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION (1<<10) +# define NV03_PGRAPH_NSOURCE_STATE_INVALID (1<<11) +# define NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY (1<<12) +# define NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE (1<<13) +# define NV03_PGRAPH_NSOURCE_METHOD_CNT (1<<14) +# define NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION (1<<15) +# define NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION (1<<16) +# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_A (1<<17) +# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_B (1<<18) #define NV03_PGRAPH_INTR_EN 0x00400140 #define NV40_PGRAPH_INTR_EN 0x0040013C # define NV_PGRAPH_INTR_NOTIFY (1<< 0) @@ -135,6 +178,21 @@ #define NV10_PGRAPH_CTX_CACHE4 0x004001C0 #define NV04_PGRAPH_CTX_CACHE4 0x004001E0 #define NV10_PGRAPH_CTX_CACHE5 0x004001E0 +#define NV40_PGRAPH_CTXCTL_0304 0x00400304 +#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001 +#define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308 +#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_MASK 0xff000000 +#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT 24 +#define NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK 0x00ffffff +#define NV40_PGRAPH_CTXCTL_0310 0x00400310 +#define NV40_PGRAPH_CTXCTL_0310_XFER_SAVE 0x00000020 +#define NV40_PGRAPH_CTXCTL_0310_XFER_LOAD 0x00000040 +#define NV40_PGRAPH_CTXCTL_030C 0x0040030c +#define NV40_PGRAPH_CTXCTL_UCODE_INDEX 0x00400324 +#define NV40_PGRAPH_CTXCTL_UCODE_DATA 0x00400328 +#define NV40_PGRAPH_CTXCTL_CUR 0x0040032c +#define NV40_PGRAPH_CTXCTL_CUR_LOADED 0x01000000 +#define NV40_PGRAPH_CTXCTL_CUR_INST_MASK 0x000FFFFF #define NV03_PGRAPH_ABS_X_RAM 0x00400400 #define NV03_PGRAPH_ABS_Y_RAM 0x00400480 #define NV03_PGRAPH_X_MISC 0x00400500 @@ -208,7 +266,12 @@ #define NV04_PGRAPH_BLIMIT5 0x00400698 #define NV04_PGRAPH_BSWIZZLE2 0x0040069C #define NV04_PGRAPH_BSWIZZLE5 0x004006A0 +#define NV03_PGRAPH_STATUS 0x004006B0 +#define NV04_PGRAPH_STATUS 0x00400700 +#define NV04_PGRAPH_TRAPPED_ADDR 0x00400704 +#define NV04_PGRAPH_TRAPPED_DATA 0x00400708 #define NV04_PGRAPH_SURFACE 0x0040070C +#define NV10_PGRAPH_TRAPPED_DATA_HIGH 0x0040070C #define NV04_PGRAPH_STATE 0x00400710 #define NV10_PGRAPH_SURFACE 0x00400710 #define NV04_PGRAPH_NOTIFY 0x00400714 @@ -228,9 +291,11 @@ #define NV10_PGRAPH_DMA_PITCH 0x00400770 #define NV10_PGRAPH_DVD_COLORFMT 0x00400774 #define NV10_PGRAPH_SCALED_FORMAT 0x00400778 -#define NV10_PGRAPH_CHANNEL_CTX_TABLE 0x00400780 -#define NV10_PGRAPH_CHANNEL_CTX_SIZE 0x00400784 -#define NV10_PGRAPH_CHANNEL_CTX_POINTER 0x00400788 +#define NV20_PGRAPH_CHANNEL_CTX_TABLE 0x00400780 +#define NV20_PGRAPH_CHANNEL_CTX_POINTER 0x00400784 +#define NV20_PGRAPH_CHANNEL_CTX_XFER 0x00400788 +#define NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD 0x00000001 +#define NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE 0x00000002 #define NV04_PGRAPH_PATT_COLOR0 0x00400800 #define NV04_PGRAPH_PATT_COLOR1 0x00400804 #define NV04_PGRAPH_PATTERN 0x00400808 @@ -257,6 +322,18 @@ #define NV47_PGRAPH_TSTATUS0(i) 0x00400D0C #define NV04_PGRAPH_V_RAM 0x00400D40 #define NV04_PGRAPH_W_RAM 0x00400D80 +#define NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40 +#define NV10_PGRAPH_COMBINER1_IN_ALPHA 0x00400E44 +#define NV10_PGRAPH_COMBINER0_IN_RGB 0x00400E48 +#define NV10_PGRAPH_COMBINER1_IN_RGB 0x00400E4C +#define NV10_PGRAPH_COMBINER_COLOR0 0x00400E50 +#define NV10_PGRAPH_COMBINER_COLOR1 0x00400E54 +#define NV10_PGRAPH_COMBINER0_OUT_ALPHA 0x00400E58 +#define NV10_PGRAPH_COMBINER1_OUT_ALPHA 0x00400E5C +#define NV10_PGRAPH_COMBINER0_OUT_RGB 0x00400E60 +#define NV10_PGRAPH_COMBINER1_OUT_RGB 0x00400E64 +#define NV10_PGRAPH_COMBINER_FINAL0 0x00400E68 +#define NV10_PGRAPH_COMBINER_FINAL1 0x00400E6C #define NV10_PGRAPH_WINDOWCLIP_HORIZONTAL 0x00400F00 #define NV10_PGRAPH_WINDOWCLIP_VERTICAL 0x00400F20 #define NV10_PGRAPH_XFMODE0 0x00400F40 @@ -317,6 +394,12 @@ #define NV04_PFIFO_MODE 0x00002504 #define NV04_PFIFO_DMA 0x00002508 #define NV04_PFIFO_SIZE 0x0000250c +#define NV50_PFIFO_CTX_TABLE(c) (0x2600+(c)*4) +#define NV50_PFIFO_CTX_TABLE__SIZE 128 +#define NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED (1<<31) +#define NV50_PFIFO_CTX_TABLE_UNK30_BAD (1<<30) +#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80 0x0FFFFFFF +#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84 0x00FFFFFF #define NV03_PFIFO_CACHE0_PUSH0 0x00003000 #define NV03_PFIFO_CACHE0_PULL0 0x00003040 #define NV04_PFIFO_CACHE0_PULL0 0x00003050 @@ -404,7 +487,7 @@ #define NV10_PFIFO_CACHE1_SEMAPHORE 0x0000326C #define NV03_PFIFO_CACHE1_GET 0x00003270 #define NV04_PFIFO_CACHE1_ENGINE 0x00003280 -#define NV10_PFIFO_CACHE1_DMA_DCOUNT 0x000032A0 +#define NV04_PFIFO_CACHE1_DMA_DCOUNT 0x000032A0 #define NV40_PFIFO_GRCTX_INSTANCE 0x000032E0 #define NV40_PFIFO_UNK32E4 0x000032E4 #define NV04_PFIFO_CACHE1_METHOD(i) (0x00003800+(i*8)) @@ -427,7 +510,10 @@ #define NV04_RAMFC_DMA_PUT 0x00 #define NV04_RAMFC_DMA_GET 0x04 #define NV04_RAMFC_DMA_INSTANCE 0x08 +#define NV04_RAMFC_DMA_STATE 0x0C #define NV04_RAMFC_DMA_FETCH 0x10 +#define NV04_RAMFC_ENGINE 0x14 +#define NV04_RAMFC_PULL1_ENGINE 0x18 #define NV10_RAMFC_DMA_PUT 0x00 #define NV10_RAMFC_DMA_GET 0x04 @@ -462,6 +548,6 @@ #define NV40_RAMFC_UNK_40 0x40 #define NV40_RAMFC_UNK_44 0x44 #define NV40_RAMFC_UNK_48 0x48 -#define NV40_RAMFC_2088 0x4C -#define NV40_RAMFC_3300 0x50 +#define NV40_RAMFC_UNK_4C 0x4C +#define NV40_RAMFC_UNK_50 0x50 diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index e7930b9e..c617bfd3 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -28,9 +28,9 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" -static int nouveau_init_card_mappings(drm_device_t *dev) +static int nouveau_init_card_mappings(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; int ret; /* resource 0 is mmio regs */ @@ -51,6 +51,7 @@ static int nouveau_init_card_mappings(drm_device_t *dev) DRM_DEBUG("regs mapped ok at 0x%lx\n", dev_priv->mmio->offset); /* map larger RAMIN aperture on NV40 cards */ + dev_priv->ramin = NULL; if (dev_priv->card_type >= NV_40) { int ramin_resource = 2; if (drm_get_resource_len(dev, ramin_resource) == 0) @@ -66,80 +67,198 @@ static int nouveau_init_card_mappings(drm_device_t *dev) "limited instance memory available\n"); dev_priv->ramin = NULL; } - } else - dev_priv->ramin = NULL; + } + + /* On older cards (or if the above failed), create a map covering + * the BAR0 PRAMIN aperture */ + if (!dev_priv->ramin) { + ret = drm_addmap(dev, + drm_get_resource_start(dev, 0) + NV_RAMIN, + (1*1024*1024), + _DRM_REGISTERS, _DRM_READ_ONLY, + &dev_priv->ramin); + if (ret) { + DRM_ERROR("Failed to map BAR0 PRAMIN: %d\n", ret); + return ret; + } + } return 0; } -static void nouveau_stub_takedown(drm_device_t *dev) {} -static int nouveau_init_engine_ptrs(drm_device_t *dev) +static int nouveau_stub_init(struct drm_device *dev) { return 0; } +static void nouveau_stub_takedown(struct drm_device *dev) {} +static uint64_t nouveau_stub_timer_read(struct drm_device *dev) { return 0; } + +static int nouveau_init_engine_ptrs(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_engine_func *engine = &dev_priv->Engine; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; switch (dev_priv->chipset & 0xf0) { case 0x00: - engine->Mc.Init = nv04_mc_init; - engine->Mc.Takedown = nv04_mc_takedown; - engine->Timer.Init = nv04_timer_init; - engine->Timer.Takedown = nv04_timer_takedown; - engine->Fb.Init = nv04_fb_init; - engine->Fb.Takedown = nv04_fb_takedown; - engine->Graph.Init = nv04_graph_init; - engine->Graph.Takedown = nv04_graph_takedown; - engine->Fifo.Init = nouveau_fifo_init; - engine->Fifo.Takedown = nouveau_stub_takedown; + engine->instmem.init = nv04_instmem_init; + engine->instmem.takedown= nv04_instmem_takedown; + engine->instmem.populate = nv04_instmem_populate; + engine->instmem.clear = nv04_instmem_clear; + engine->instmem.bind = nv04_instmem_bind; + engine->instmem.unbind = nv04_instmem_unbind; + engine->mc.init = nv04_mc_init; + engine->mc.takedown = nv04_mc_takedown; + engine->timer.init = nv04_timer_init; + engine->timer.read = nv04_timer_read; + engine->timer.takedown = nv04_timer_takedown; + engine->fb.init = nv04_fb_init; + engine->fb.takedown = nv04_fb_takedown; + engine->graph.init = nv04_graph_init; + engine->graph.takedown = nv04_graph_takedown; + engine->graph.create_context = nv04_graph_create_context; + engine->graph.destroy_context = nv04_graph_destroy_context; + engine->graph.load_context = nv04_graph_load_context; + engine->graph.save_context = nv04_graph_save_context; + engine->fifo.init = nouveau_fifo_init; + engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.create_context = nv04_fifo_create_context; + engine->fifo.destroy_context = nv04_fifo_destroy_context; + engine->fifo.load_context = nv04_fifo_load_context; + engine->fifo.save_context = nv04_fifo_save_context; break; case 0x10: - engine->Mc.Init = nv04_mc_init; - engine->Mc.Takedown = nv04_mc_takedown; - engine->Timer.Init = nv04_timer_init; - engine->Timer.Takedown = nv04_timer_takedown; - engine->Fb.Init = nv10_fb_init; - engine->Fb.Takedown = nv10_fb_takedown; - engine->Graph.Init = nv10_graph_init; - engine->Graph.Takedown = nv10_graph_takedown; - engine->Fifo.Init = nouveau_fifo_init; - engine->Fifo.Takedown = nouveau_stub_takedown; + engine->instmem.init = nv04_instmem_init; + engine->instmem.takedown= nv04_instmem_takedown; + engine->instmem.populate = nv04_instmem_populate; + engine->instmem.clear = nv04_instmem_clear; + engine->instmem.bind = nv04_instmem_bind; + engine->instmem.unbind = nv04_instmem_unbind; + engine->mc.init = nv04_mc_init; + engine->mc.takedown = nv04_mc_takedown; + engine->timer.init = nv04_timer_init; + engine->timer.read = nv04_timer_read; + engine->timer.takedown = nv04_timer_takedown; + engine->fb.init = nv10_fb_init; + engine->fb.takedown = nv10_fb_takedown; + engine->graph.init = nv10_graph_init; + engine->graph.takedown = nv10_graph_takedown; + engine->graph.create_context = nv10_graph_create_context; + engine->graph.destroy_context = nv10_graph_destroy_context; + engine->graph.load_context = nv10_graph_load_context; + engine->graph.save_context = nv10_graph_save_context; + engine->fifo.init = nouveau_fifo_init; + engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.create_context = nv10_fifo_create_context; + engine->fifo.destroy_context = nv10_fifo_destroy_context; + engine->fifo.load_context = nv10_fifo_load_context; + engine->fifo.save_context = nv10_fifo_save_context; break; case 0x20: - engine->Mc.Init = nv04_mc_init; - engine->Mc.Takedown = nv04_mc_takedown; - engine->Timer.Init = nv04_timer_init; - engine->Timer.Takedown = nv04_timer_takedown; - engine->Fb.Init = nv10_fb_init; - engine->Fb.Takedown = nv10_fb_takedown; - engine->Graph.Init = nv20_graph_init; - engine->Graph.Takedown = nv20_graph_takedown; - engine->Fifo.Init = nouveau_fifo_init; - engine->Fifo.Takedown = nouveau_stub_takedown; + engine->instmem.init = nv04_instmem_init; + engine->instmem.takedown= nv04_instmem_takedown; + engine->instmem.populate = nv04_instmem_populate; + engine->instmem.clear = nv04_instmem_clear; + engine->instmem.bind = nv04_instmem_bind; + engine->instmem.unbind = nv04_instmem_unbind; + engine->mc.init = nv04_mc_init; + engine->mc.takedown = nv04_mc_takedown; + engine->timer.init = nv04_timer_init; + engine->timer.read = nv04_timer_read; + engine->timer.takedown = nv04_timer_takedown; + engine->fb.init = nv10_fb_init; + engine->fb.takedown = nv10_fb_takedown; + engine->graph.init = nv20_graph_init; + engine->graph.takedown = nv20_graph_takedown; + engine->graph.create_context = nv20_graph_create_context; + engine->graph.destroy_context = nv20_graph_destroy_context; + engine->graph.load_context = nv20_graph_load_context; + engine->graph.save_context = nv20_graph_save_context; + engine->fifo.init = nouveau_fifo_init; + engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.create_context = nv10_fifo_create_context; + engine->fifo.destroy_context = nv10_fifo_destroy_context; + engine->fifo.load_context = nv10_fifo_load_context; + engine->fifo.save_context = nv10_fifo_save_context; break; case 0x30: - engine->Mc.Init = nv04_mc_init; - engine->Mc.Takedown = nv04_mc_takedown; - engine->Timer.Init = nv04_timer_init; - engine->Timer.Takedown = nv04_timer_takedown; - engine->Fb.Init = nv10_fb_init; - engine->Fb.Takedown = nv10_fb_takedown; - engine->Graph.Init = nv30_graph_init; - engine->Graph.Takedown = nv30_graph_takedown; - engine->Fifo.Init = nouveau_fifo_init; - engine->Fifo.Takedown = nouveau_stub_takedown; + engine->instmem.init = nv04_instmem_init; + engine->instmem.takedown= nv04_instmem_takedown; + engine->instmem.populate = nv04_instmem_populate; + engine->instmem.clear = nv04_instmem_clear; + engine->instmem.bind = nv04_instmem_bind; + engine->instmem.unbind = nv04_instmem_unbind; + engine->mc.init = nv04_mc_init; + engine->mc.takedown = nv04_mc_takedown; + engine->timer.init = nv04_timer_init; + engine->timer.read = nv04_timer_read; + engine->timer.takedown = nv04_timer_takedown; + engine->fb.init = nv10_fb_init; + engine->fb.takedown = nv10_fb_takedown; + engine->graph.init = nv30_graph_init; + engine->graph.takedown = nv20_graph_takedown; + engine->graph.create_context = nv20_graph_create_context; + engine->graph.destroy_context = nv20_graph_destroy_context; + engine->graph.load_context = nv20_graph_load_context; + engine->graph.save_context = nv20_graph_save_context; + engine->fifo.init = nouveau_fifo_init; + engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.create_context = nv10_fifo_create_context; + engine->fifo.destroy_context = nv10_fifo_destroy_context; + engine->fifo.load_context = nv10_fifo_load_context; + engine->fifo.save_context = nv10_fifo_save_context; break; case 0x40: - engine->Mc.Init = nv40_mc_init; - engine->Mc.Takedown = nv40_mc_takedown; - engine->Timer.Init = nv04_timer_init; - engine->Timer.Takedown = nv04_timer_takedown; - engine->Fb.Init = nv40_fb_init; - engine->Fb.Takedown = nv40_fb_takedown; - engine->Graph.Init = nv40_graph_init; - engine->Graph.Takedown = nv40_graph_takedown; - engine->Fifo.Init = nouveau_fifo_init; - engine->Fifo.Takedown = nouveau_stub_takedown; + engine->instmem.init = nv04_instmem_init; + engine->instmem.takedown= nv04_instmem_takedown; + engine->instmem.populate = nv04_instmem_populate; + engine->instmem.clear = nv04_instmem_clear; + engine->instmem.bind = nv04_instmem_bind; + engine->instmem.unbind = nv04_instmem_unbind; + engine->mc.init = nv40_mc_init; + engine->mc.takedown = nv40_mc_takedown; + engine->timer.init = nv04_timer_init; + engine->timer.read = nv04_timer_read; + engine->timer.takedown = nv04_timer_takedown; + engine->fb.init = nv40_fb_init; + engine->fb.takedown = nv40_fb_takedown; + engine->graph.init = nv40_graph_init; + engine->graph.takedown = nv40_graph_takedown; + engine->graph.create_context = nv40_graph_create_context; + engine->graph.destroy_context = nv40_graph_destroy_context; + engine->graph.load_context = nv40_graph_load_context; + engine->graph.save_context = nv40_graph_save_context; + engine->fifo.init = nv40_fifo_init; + engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.create_context = nv40_fifo_create_context; + engine->fifo.destroy_context = nv40_fifo_destroy_context; + engine->fifo.load_context = nv40_fifo_load_context; + engine->fifo.save_context = nv40_fifo_save_context; break; case 0x50: + case 0x80: /* gotta love NVIDIA's consistency.. */ + engine->instmem.init = nv50_instmem_init; + engine->instmem.takedown= nv50_instmem_takedown; + engine->instmem.populate = nv50_instmem_populate; + engine->instmem.clear = nv50_instmem_clear; + engine->instmem.bind = nv50_instmem_bind; + engine->instmem.unbind = nv50_instmem_unbind; + engine->mc.init = nv50_mc_init; + engine->mc.takedown = nv50_mc_takedown; + engine->timer.init = nouveau_stub_init; + engine->timer.read = nouveau_stub_timer_read; + engine->timer.takedown = nouveau_stub_takedown; + engine->fb.init = nouveau_stub_init; + engine->fb.takedown = nouveau_stub_takedown; + engine->graph.init = nv50_graph_init; + engine->graph.takedown = nv50_graph_takedown; + engine->graph.create_context = nv50_graph_create_context; + engine->graph.destroy_context = nv50_graph_destroy_context; + engine->graph.load_context = nv50_graph_load_context; + engine->graph.save_context = nv50_graph_save_context; + engine->fifo.init = nv50_fifo_init; + engine->fifo.takedown = nv50_fifo_takedown; + engine->fifo.create_context = nv50_fifo_create_context; + engine->fifo.destroy_context = nv50_fifo_destroy_context; + engine->fifo.load_context = nv50_fifo_load_context; + engine->fifo.save_context = nv50_fifo_save_context; + break; default: DRM_ERROR("NV%02x unsupported\n", dev_priv->chipset); return 1; @@ -148,16 +267,30 @@ static int nouveau_init_engine_ptrs(drm_device_t *dev) return 0; } -static int nouveau_card_init(drm_device_t *dev) +int +nouveau_card_init(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_engine_func *engine; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine; int ret; + DRM_DEBUG("prev state = %d\n", dev_priv->init_state); + + if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE) + return 0; + /* Map any PCI resources we need on the card */ ret = nouveau_init_card_mappings(dev); if (ret) return ret; +#if defined(__powerpc__) + /* Put the card in BE mode if it's not */ + if (NV_READ(NV03_PMC_BOOT_1)) + NV_WRITE(NV03_PMC_BOOT_1,0x00000001); + + DRM_MEMORYBARRIER(); +#endif + /* Determine exact chipset we're running on */ if (dev_priv->card_type < NV_10) dev_priv->chipset = dev_priv->card_type; @@ -169,105 +302,206 @@ static int nouveau_card_init(drm_device_t *dev) ret = nouveau_init_engine_ptrs(dev); if (ret) return ret; engine = &dev_priv->Engine; + dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; + + ret = nouveau_gpuobj_early_init(dev); + if (ret) return ret; /* Initialise instance memory, must happen before mem_init so we * know exactly how much VRAM we're able to use for "normal" * purposes. */ - ret = nouveau_instmem_init(dev); + ret = engine->instmem.init(dev); if (ret) return ret; /* Setup the memory manager */ ret = nouveau_mem_init(dev); if (ret) return ret; + ret = nouveau_gpuobj_init(dev); + if (ret) return ret; + /* Parse BIOS tables / Run init tables? */ /* PMC */ - ret = engine->Mc.Init(dev); + ret = engine->mc.init(dev); if (ret) return ret; /* PTIMER */ - ret = engine->Timer.Init(dev); + ret = engine->timer.init(dev); if (ret) return ret; /* PFB */ - ret = engine->Fb.Init(dev); + ret = engine->fb.init(dev); if (ret) return ret; /* PGRAPH */ - ret = engine->Graph.Init(dev); + ret = engine->graph.init(dev); if (ret) return ret; /* PFIFO */ - ret = engine->Fifo.Init(dev); + ret = engine->fifo.init(dev); + if (ret) return ret; + + /* this call irq_preinstall, register irq handler and + * call irq_postinstall + */ + ret = drm_irq_install(dev); if (ret) return ret; /* what about PVIDEO/PCRTC/PRAMDAC etc? */ + ret = nouveau_dma_channel_init(dev); + if (ret) return ret; + + dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; return 0; } -/* here a client dies, release the stuff that was allocated for its filp */ -void nouveau_preclose(drm_device_t * dev, DRMFILE filp) +static void nouveau_card_takedown(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; + + DRM_DEBUG("prev state = %d\n", dev_priv->init_state); + + if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) { + nouveau_dma_channel_takedown(dev); + + engine->fifo.takedown(dev); + engine->graph.takedown(dev); + engine->fb.takedown(dev); + engine->timer.takedown(dev); + engine->mc.takedown(dev); - nouveau_mem_release(filp,dev_priv->fb_heap); - nouveau_mem_release(filp,dev_priv->agp_heap); - nouveau_fifo_cleanup(dev, filp); + nouveau_sgdma_nottm_hack_takedown(dev); + nouveau_sgdma_takedown(dev); + + nouveau_gpuobj_takedown(dev); + + nouveau_mem_close(dev); + engine->instmem.takedown(dev); + + drm_irq_uninstall(dev); + + nouveau_gpuobj_late_takedown(dev); + + dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; + } } -/* first module load, setup the mmio/fb mapping */ -int nouveau_firstopen(struct drm_device *dev) +/* here a client dies, release the stuff that was allocated for its + * file_priv */ +void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv) { - int ret; + struct drm_nouveau_private *dev_priv = dev->dev_private; - ret = nouveau_card_init(dev); - if (ret) { - DRM_ERROR("nouveau_card_init() failed! (%d)\n", ret); - return ret; - } + nouveau_fifo_cleanup(dev, file_priv); + nouveau_mem_release(file_priv,dev_priv->fb_heap); + nouveau_mem_release(file_priv,dev_priv->agp_heap); + nouveau_mem_release(file_priv,dev_priv->pci_heap); +} +/* first module load, setup the mmio/fb mapping */ +int nouveau_firstopen(struct drm_device *dev) +{ return 0; } int nouveau_load(struct drm_device *dev, unsigned long flags) { - drm_nouveau_private_t *dev_priv; - int ret; + struct drm_nouveau_private *dev_priv; + void __iomem *regs; + uint32_t reg0,reg1; + uint8_t architecture = 0; - if (flags==NV_UNKNOWN) - return DRM_ERR(EINVAL); + dev_priv = drm_calloc(1, sizeof(*dev_priv), DRM_MEM_DRIVER); + if (!dev_priv) + return -ENOMEM; - dev_priv = drm_alloc(sizeof(drm_nouveau_private_t), DRM_MEM_DRIVER); - if (!dev_priv) - return DRM_ERR(ENOMEM); + dev_priv->flags = flags & NOUVEAU_FLAGS; + dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN; - memset(dev_priv, 0, sizeof(drm_nouveau_private_t)); - dev_priv->card_type=flags&NOUVEAU_FAMILY; - dev_priv->flags=flags&NOUVEAU_FLAGS; - - dev->dev_private = (void *)dev_priv; + DRM_DEBUG("vendor: 0x%X device: 0x%X class: 0x%X\n", dev->pci_vendor, dev->pci_device, dev->pdev->class); -#if 0 - ret = nouveau_card_init(dev); - if (ret) { - DRM_ERROR("nouveau_card_init() failed! (%d)\n", ret); - return ret; + /* Time to determine the card architecture */ + regs = ioremap_nocache(pci_resource_start(dev->pdev, 0), 0x8); + if (!regs) { + DRM_ERROR("Could not ioremap to determine register\n"); + return -ENOMEM; } + + reg0 = readl(regs+NV03_PMC_BOOT_0); + reg1 = readl(regs+NV03_PMC_BOOT_1); +#if defined(__powerpc__) + if (reg1) + reg0=___swab32(reg0); #endif + /* We're dealing with >=NV10 */ + if ((reg0 & 0x0f000000) > 0 ) { + /* Bit 27-20 contain the architecture in hex */ + architecture = (reg0 & 0xff00000) >> 20; + /* NV04 or NV05 */ + } else if ((reg0 & 0xff00fff0) == 0x20004000) { + architecture = 0x04; + } + + iounmap(regs); + + if (architecture >= 0x50) { + dev_priv->card_type = NV_50; + } else if (architecture >= 0x44) { + dev_priv->card_type = NV_44; + } else if (architecture >= 0x40) { + dev_priv->card_type = NV_40; + } else if (architecture >= 0x30) { + dev_priv->card_type = NV_30; + } else if (architecture >= 0x20) { + dev_priv->card_type = NV_20; + } else if (architecture >= 0x17) { + dev_priv->card_type = NV_17; + } else if (architecture >= 0x11) { + dev_priv->card_type = NV_11; + } else if (architecture >= 0x10) { + dev_priv->card_type = NV_10; + } else if (architecture >= 0x04) { + dev_priv->card_type = NV_04; + } else { + dev_priv->card_type = NV_UNKNOWN; + } + + DRM_INFO("Detected an NV%d generation card (0x%08x)\n", dev_priv->card_type,reg0); + + if (dev_priv->card_type == NV_UNKNOWN) { + return -EINVAL; + } + + /* Special flags */ + if (dev->pci_device == 0x01a0) { + dev_priv->flags |= NV_NFORCE; + } else if (dev->pci_device == 0x01f0) { + dev_priv->flags |= NV_NFORCE2; + } + + dev->dev_private = (void *)dev_priv; + return 0; } void nouveau_lastclose(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - if(dev_priv->fb_mtrr>0) - { - drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC); - dev_priv->fb_mtrr=0; + struct drm_nouveau_private *dev_priv = dev->dev_private; + + /* In the case of an error dev_priv may not be be allocated yet */ + if (dev_priv && dev_priv->card_type) { + nouveau_card_takedown(dev); + + if(dev_priv->fb_mtrr>0) + { + drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC); + dev_priv->fb_mtrr=0; + } } } @@ -278,80 +512,95 @@ int nouveau_unload(struct drm_device *dev) return 0; } -int nouveau_ioctl_getparam(DRM_IOCTL_ARGS) +int +nouveau_ioctl_card_init(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; - drm_nouveau_private_t *dev_priv = dev->dev_private; - drm_nouveau_getparam_t getparam; + return nouveau_card_init(dev); +} - DRM_COPY_FROM_USER_IOCTL(getparam, (drm_nouveau_getparam_t __user *)data, - sizeof(getparam)); +int nouveau_ioctl_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_getparam *getparam = data; - switch (getparam.param) { + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + + switch (getparam->param) { + case NOUVEAU_GETPARAM_CHIPSET_ID: + getparam->value = dev_priv->chipset; + break; case NOUVEAU_GETPARAM_PCI_VENDOR: - getparam.value=dev->pci_vendor; + getparam->value=dev->pci_vendor; break; case NOUVEAU_GETPARAM_PCI_DEVICE: - getparam.value=dev->pci_device; + getparam->value=dev->pci_device; break; case NOUVEAU_GETPARAM_BUS_TYPE: if (drm_device_is_agp(dev)) - getparam.value=NV_AGP; + getparam->value=NV_AGP; else if (drm_device_is_pcie(dev)) - getparam.value=NV_PCIE; + getparam->value=NV_PCIE; else - getparam.value=NV_PCI; + getparam->value=NV_PCI; break; case NOUVEAU_GETPARAM_FB_PHYSICAL: - getparam.value=dev_priv->fb_phys; + getparam->value=dev_priv->fb_phys; break; case NOUVEAU_GETPARAM_AGP_PHYSICAL: - getparam.value=dev_priv->agp_phys; + getparam->value=dev_priv->gart_info.aper_base; + break; + case NOUVEAU_GETPARAM_PCI_PHYSICAL: + if ( dev -> sg ) + getparam->value=(uint64_t) dev->sg->virtual; + else + { + DRM_ERROR("Requested PCIGART address, while no PCIGART was created\n"); + return -EINVAL; + } break; case NOUVEAU_GETPARAM_FB_SIZE: - getparam.value=dev_priv->fb_available_size; + getparam->value=dev_priv->fb_available_size; break; case NOUVEAU_GETPARAM_AGP_SIZE: - getparam.value=dev_priv->agp_available_size; + getparam->value=dev_priv->gart_info.aper_size; break; default: - DRM_ERROR("unknown parameter %lld\n", getparam.param); - return DRM_ERR(EINVAL); + DRM_ERROR("unknown parameter %lld\n", getparam->param); + return -EINVAL; } - DRM_COPY_TO_USER_IOCTL((drm_nouveau_getparam_t __user *)data, getparam, - sizeof(getparam)); return 0; } -int nouveau_ioctl_setparam(DRM_IOCTL_ARGS) +int nouveau_ioctl_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_nouveau_private_t *dev_priv = dev->dev_private; - drm_nouveau_setparam_t setparam; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_setparam *setparam = data; - DRM_COPY_FROM_USER_IOCTL(setparam, (drm_nouveau_setparam_t __user *)data, - sizeof(setparam)); + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; - switch (setparam.param) { + switch (setparam->param) { case NOUVEAU_SETPARAM_CMDBUF_LOCATION: - switch (setparam.value) { + switch (setparam->value) { case NOUVEAU_MEM_AGP: case NOUVEAU_MEM_FB: + case NOUVEAU_MEM_PCI: + case NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI_ACCEPTABLE: break; default: DRM_ERROR("invalid CMDBUF_LOCATION value=%lld\n", - setparam.value); - return DRM_ERR(EINVAL); + setparam->value); + return -EINVAL; } - dev_priv->config.cmdbuf.location = setparam.value; + dev_priv->config.cmdbuf.location = setparam->value; break; case NOUVEAU_SETPARAM_CMDBUF_SIZE: - dev_priv->config.cmdbuf.size = setparam.value; + dev_priv->config.cmdbuf.size = setparam->value; break; default: - DRM_ERROR("unknown parameter %lld\n", setparam.param); - return DRM_ERR(EINVAL); + DRM_ERROR("unknown parameter %lld\n", setparam->param); + return -EINVAL; } return 0; @@ -360,15 +609,30 @@ int nouveau_ioctl_setparam(DRM_IOCTL_ARGS) /* waits for idle */ void nouveau_wait_for_idle(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv=dev->dev_private; - switch(dev_priv->card_type) - { - case NV_03: - while(NV_READ(NV03_PGRAPH_STATUS)); - break; - default: - while(NV_READ(NV04_PGRAPH_STATUS)); - break; + struct drm_nouveau_private *dev_priv=dev->dev_private; + switch(dev_priv->card_type) { + case NV_50: + break; + default: { + /* This stuff is more or less a copy of what is seen + * in nv28 kmmio dump. + */ + uint64_t started = dev_priv->Engine.timer.read(dev); + uint64_t stopped = started; + uint32_t status; + do { + uint32_t pmc_e = NV_READ(NV03_PMC_ENABLE); + (void)pmc_e; + status = NV_READ(NV04_PGRAPH_STATUS); + if (!status) + break; + stopped = dev_priv->Engine.timer.read(dev); + /* It'll never wrap anyway... */ + } while (stopped - started < 1000000000ULL); + if (status) + DRM_ERROR("timed out with status 0x%08x\n", + status); + } } } diff --git a/shared-core/nouveau_swmthd.c b/shared-core/nouveau_swmthd.c new file mode 100644 index 00000000..66ef6233 --- /dev/null +++ b/shared-core/nouveau_swmthd.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2007 Arthur Huillet. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/* + * Authors: + * Arthur Huillet <arthur.huillet AT free DOT fr> + */ + +#include "drmP.h" +#include "drm.h" +#include "nouveau_drm.h" +#include "nouveau_drv.h" +#include "nouveau_reg.h" + +/*TODO: add a "card_type" attribute*/ +typedef struct{ + uint32_t oclass; /* object class for this software method */ + uint32_t mthd; /* method number */ + void (*method_code)(struct drm_device *dev, uint32_t oclass, uint32_t mthd); /* pointer to the function that does the work */ + } nouveau_software_method_t; + + + /* This function handles the NV04 setcontext software methods. +One function for all because they are very similar.*/ +static void nouveau_NV04_setcontext_sw_method(struct drm_device *dev, uint32_t oclass, uint32_t mthd) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t inst_loc = NV_READ(NV04_PGRAPH_CTX_SWITCH4) & 0xFFFF; + uint32_t value_to_set = 0, bit_to_set = 0; + + switch ( oclass ) { + case 0x4a: + switch ( mthd ) { + case 0x188 : + case 0x18c : + bit_to_set = 0; + break; + case 0x198 : + bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ + break; + case 0x2fc : + bit_to_set = NV_READ(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ + break; + default : ; + }; + break; + case 0x5c: + switch ( mthd ) { + case 0x184: + bit_to_set = 1 << 13; /*USER_CLIP_ENABLE*/ + break; + case 0x188: + case 0x18c: + bit_to_set = 0; + break; + case 0x198: + bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ + break; + case 0x2fc : + bit_to_set = NV_READ(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ + break; + }; + break; + case 0x5f: + switch ( mthd ) { + case 0x184 : + bit_to_set = 1 << 12; /*CHROMA_KEY_ENABLE*/ + break; + case 0x188 : + bit_to_set = 1 << 13; /*USER_CLIP_ENABLE*/ + break; + case 0x18c : + case 0x190 : + bit_to_set = 0; + break; + case 0x19c : + bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ + break; + case 0x2fc : + bit_to_set = NV_READ(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ + break; + }; + break; + case 0x61: + switch ( mthd ) { + case 0x188 : + bit_to_set = 1 << 13; /*USER_CLIP_ENABLE*/ + break; + case 0x18c : + case 0x190 : + bit_to_set = 0; + break; + case 0x19c : + bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ + break; + case 0x2fc : + bit_to_set = NV_READ(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ + break; + }; + break; + case 0x77: + switch ( mthd ) { + case 0x198 : + bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ + break; + case 0x304 : + bit_to_set = NV_READ(NV04_PGRAPH_TRAPPED_DATA) << 15; //PATCH_CONFIG + break; + }; + break; + default :; + }; + + value_to_set = (NV_READ(0x00700000 | inst_loc << 4))| bit_to_set; + + /*RAMIN*/ + nouveau_wait_for_idle(dev); + NV_WRITE(0x00700000 | inst_loc << 4, value_to_set); + + /*DRM_DEBUG("CTX_SWITCH1 value is %#x\n", NV_READ(NV04_PGRAPH_CTX_SWITCH1));*/ + NV_WRITE(NV04_PGRAPH_CTX_SWITCH1, value_to_set); + + /*DRM_DEBUG("CTX_CACHE1 + xxx value is %#x\n", NV_READ(NV04_PGRAPH_CTX_CACHE1 + (((NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7) << 2)));*/ + NV_WRITE(NV04_PGRAPH_CTX_CACHE1 + (((NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7) << 2), value_to_set); +} + + nouveau_software_method_t nouveau_sw_methods[] = { + /*NV04 context software methods*/ + { 0x4a, 0x188, nouveau_NV04_setcontext_sw_method }, + { 0x4a, 0x18c, nouveau_NV04_setcontext_sw_method }, + { 0x4a, 0x198, nouveau_NV04_setcontext_sw_method }, + { 0x4a, 0x2fc, nouveau_NV04_setcontext_sw_method }, + { 0x5c, 0x184, nouveau_NV04_setcontext_sw_method }, + { 0x5c, 0x188, nouveau_NV04_setcontext_sw_method }, + { 0x5c, 0x18c, nouveau_NV04_setcontext_sw_method }, + { 0x5c, 0x198, nouveau_NV04_setcontext_sw_method }, + { 0x5c, 0x2fc, nouveau_NV04_setcontext_sw_method }, + { 0x5f, 0x184, nouveau_NV04_setcontext_sw_method }, + { 0x5f, 0x188, nouveau_NV04_setcontext_sw_method }, + { 0x5f, 0x18c, nouveau_NV04_setcontext_sw_method }, + { 0x5f, 0x190, nouveau_NV04_setcontext_sw_method }, + { 0x5f, 0x19c, nouveau_NV04_setcontext_sw_method }, + { 0x5f, 0x2fc, nouveau_NV04_setcontext_sw_method }, + { 0x61, 0x188, nouveau_NV04_setcontext_sw_method }, + { 0x61, 0x18c, nouveau_NV04_setcontext_sw_method }, + { 0x61, 0x190, nouveau_NV04_setcontext_sw_method }, + { 0x61, 0x19c, nouveau_NV04_setcontext_sw_method }, + { 0x61, 0x2fc, nouveau_NV04_setcontext_sw_method }, + { 0x77, 0x198, nouveau_NV04_setcontext_sw_method }, + { 0x77, 0x304, nouveau_NV04_setcontext_sw_method }, + /*terminator*/ + { 0x0, 0x0, NULL, }, + }; + + int nouveau_sw_method_execute(struct drm_device *dev, uint32_t oclass, uint32_t method) { + int i = 0; + while ( nouveau_sw_methods[ i ] . method_code != NULL ) + { + if ( nouveau_sw_methods[ i ] . oclass == oclass && nouveau_sw_methods[ i ] . mthd == method ) + { + nouveau_sw_methods[ i ] . method_code(dev, oclass, method); + return 0; + } + i ++; + } + + return 1; + } + + diff --git a/shared-core/nouveau_swmthd.h b/shared-core/nouveau_swmthd.h new file mode 100644 index 00000000..df8c7400 --- /dev/null +++ b/shared-core/nouveau_swmthd.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2007 Arthur Huillet. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/* + * Authors: + * Arthur Huillet <arthur.huillet AT free DOT fr> + */ + +int nouveau_sw_method_execute(struct drm_device *dev, uint32_t oclass, uint32_t method); /* execute the given software method, returns 0 on success */ + diff --git a/shared-core/nv04_fb.c b/shared-core/nv04_fb.c index 06b1c994..534fb50b 100644 --- a/shared-core/nv04_fb.c +++ b/shared-core/nv04_fb.c @@ -4,9 +4,9 @@ #include "nouveau_drm.h" int -nv04_fb_init(drm_device_t *dev) +nv04_fb_init(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; /* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows * nvidia reading PFB_CFG_0, then writing back its original value. @@ -18,7 +18,7 @@ nv04_fb_init(drm_device_t *dev) } void -nv04_fb_takedown(drm_device_t *dev) +nv04_fb_takedown(struct drm_device *dev) { } diff --git a/shared-core/nv04_fifo.c b/shared-core/nv04_fifo.c new file mode 100644 index 00000000..d750ced8 --- /dev/null +++ b/shared-core/nv04_fifo.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" + +#define RAMFC_WR(offset,val) INSTANCE_WR(chan->ramfc->gpuobj, \ + NV04_RAMFC_##offset/4, (val)) +#define RAMFC_RD(offset) INSTANCE_RD(chan->ramfc->gpuobj, \ + NV04_RAMFC_##offset/4) +#define NV04_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV04_RAMFC__SIZE)) +#define NV04_RAMFC__SIZE 32 + +int +nv04_fifo_create_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + if ((ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0, + NV04_RAMFC__SIZE, + NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ZERO_FREE, + NULL, &chan->ramfc))) + return ret; + + /* Setup initial state */ + RAMFC_WR(DMA_PUT, chan->pushbuf_base); + RAMFC_WR(DMA_GET, chan->pushbuf_base); + RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4); + RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | +#ifdef __BIG_ENDIAN + NV_PFIFO_CACHE1_BIG_ENDIAN | +#endif + 0)); + + /* enable the fifo dma operation */ + NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE) | (1<<chan->id)); + return 0; +} + +void +nv04_fifo_destroy_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + + NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<chan->id)); + + nouveau_gpuobj_ref_del(dev, &chan->ramfc); +} + +int +nv04_fifo_load_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t tmp; + + NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, (1<<8) | chan->id); + + NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET, RAMFC_RD(DMA_GET)); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT, RAMFC_RD(DMA_PUT)); + + tmp = RAMFC_RD(DMA_INSTANCE); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16); + + NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE, RAMFC_RD(DMA_STATE)); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_FETCH, RAMFC_RD(DMA_FETCH)); + NV_WRITE(NV04_PFIFO_CACHE1_ENGINE, RAMFC_RD(ENGINE)); + NV_WRITE(NV04_PFIFO_CACHE1_PULL1, RAMFC_RD(PULL1_ENGINE)); + + /* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */ + tmp = NV_READ(NV04_PFIFO_CACHE1_DMA_CTL) & ~(1<<31); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_CTL, tmp); + + return 0; +} + +int +nv04_fifo_save_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t tmp; + + RAMFC_WR(DMA_PUT, NV04_PFIFO_CACHE1_DMA_PUT); + RAMFC_WR(DMA_GET, NV04_PFIFO_CACHE1_DMA_GET); + + tmp = NV_READ(NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16; + tmp |= NV_READ(NV04_PFIFO_CACHE1_DMA_INSTANCE); + RAMFC_WR(DMA_INSTANCE, tmp); + + RAMFC_WR(DMA_STATE, NV_READ(NV04_PFIFO_CACHE1_DMA_STATE)); + RAMFC_WR(DMA_FETCH, NV_READ(NV04_PFIFO_CACHE1_DMA_FETCH)); + RAMFC_WR(ENGINE, NV_READ(NV04_PFIFO_CACHE1_ENGINE)); + RAMFC_WR(PULL1_ENGINE, NV_READ(NV04_PFIFO_CACHE1_PULL1)); + + return 0; +} + diff --git a/shared-core/nv04_graph.c b/shared-core/nv04_graph.c index 0cd4d3b8..cffa3e4a 100644 --- a/shared-core/nv04_graph.c +++ b/shared-core/nv04_graph.c @@ -27,323 +27,408 @@ #include "nouveau_drm.h" #include "nouveau_drv.h" -struct reg_interval -{ - uint32_t reg; - int number; -} nv04_graph_ctx_regs [] = { - {NV04_PGRAPH_CTX_SWITCH1,1}, - {NV04_PGRAPH_CTX_SWITCH2,1}, - {NV04_PGRAPH_CTX_SWITCH3,1}, - {NV04_PGRAPH_CTX_SWITCH4,1}, - {NV04_PGRAPH_CTX_CACHE1,1}, - {NV04_PGRAPH_CTX_CACHE2,1}, - {NV04_PGRAPH_CTX_CACHE3,1}, - {NV04_PGRAPH_CTX_CACHE4,1}, - {0x00400184,1}, - {0x004001a4,1}, - {0x004001c4,1}, - {0x004001e4,1}, - {0x00400188,1}, - {0x004001a8,1}, - {0x004001c8,1}, - {0x004001e8,1}, - {0x0040018c,1}, - {0x004001ac,1}, - {0x004001cc,1}, - {0x004001ec,1}, - {0x00400190,1}, - {0x004001b0,1}, - {0x004001d0,1}, - {0x004001f0,1}, - {0x00400194,1}, - {0x004001b4,1}, - {0x004001d4,1}, - {0x004001f4,1}, - {0x00400198,1}, - {0x004001b8,1}, - {0x004001d8,1}, - {0x004001f8,1}, - {0x0040019c,1}, - {0x004001bc,1}, - {0x004001dc,1}, - {0x004001fc,1}, - {0x00400174,1}, - {NV04_PGRAPH_DMA_START_0,1}, - {NV04_PGRAPH_DMA_START_1,1}, - {NV04_PGRAPH_DMA_LENGTH,1}, - {NV04_PGRAPH_DMA_MISC,1}, - {NV04_PGRAPH_DMA_PITCH,1}, - {NV04_PGRAPH_BOFFSET0,1}, - {NV04_PGRAPH_BBASE0,1}, - {NV04_PGRAPH_BLIMIT0,1}, - {NV04_PGRAPH_BOFFSET1,1}, - {NV04_PGRAPH_BBASE1,1}, - {NV04_PGRAPH_BLIMIT1,1}, - {NV04_PGRAPH_BOFFSET2,1}, - {NV04_PGRAPH_BBASE2,1}, - {NV04_PGRAPH_BLIMIT2,1}, - {NV04_PGRAPH_BOFFSET3,1}, - {NV04_PGRAPH_BBASE3,1}, - {NV04_PGRAPH_BLIMIT3,1}, - {NV04_PGRAPH_BOFFSET4,1}, - {NV04_PGRAPH_BBASE4,1}, - {NV04_PGRAPH_BLIMIT4,1}, - {NV04_PGRAPH_BOFFSET5,1}, - {NV04_PGRAPH_BBASE5,1}, - {NV04_PGRAPH_BLIMIT5,1}, - {NV04_PGRAPH_BPITCH0,1}, - {NV04_PGRAPH_BPITCH1,1}, - {NV04_PGRAPH_BPITCH2,1}, - {NV04_PGRAPH_BPITCH3,1}, - {NV04_PGRAPH_BPITCH4,1}, - {NV04_PGRAPH_SURFACE,1}, - {NV04_PGRAPH_STATE,1}, - {NV04_PGRAPH_BSWIZZLE2,1}, - {NV04_PGRAPH_BSWIZZLE5,1}, - {NV04_PGRAPH_BPIXEL,1}, - {NV04_PGRAPH_NOTIFY,1}, - {NV04_PGRAPH_PATT_COLOR0,1}, - {NV04_PGRAPH_PATT_COLOR1,1}, - {NV04_PGRAPH_PATT_COLORRAM,64}, - {NV04_PGRAPH_PATTERN,1}, - {0x0040080c,1}, - {NV04_PGRAPH_PATTERN_SHAPE,1}, - {0x00400600,1}, - {NV04_PGRAPH_ROP3,1}, - {NV04_PGRAPH_CHROMA,1}, - {NV04_PGRAPH_BETA_AND,1}, - {NV04_PGRAPH_BETA_PREMULT,1}, - {NV04_PGRAPH_CONTROL0,1}, - {NV04_PGRAPH_CONTROL1,1}, - {NV04_PGRAPH_CONTROL2,1}, - {NV04_PGRAPH_BLEND,1}, - {NV04_PGRAPH_STORED_FMT,1}, - {NV04_PGRAPH_SOURCE_COLOR,1}, - {0x00400560,1}, - {0x00400568,1}, - {0x00400564,1}, - {0x0040056c,1}, - {0x00400400,1}, - {0x00400480,1}, - {0x00400404,1}, - {0x00400484,1}, - {0x00400408,1}, - {0x00400488,1}, - {0x0040040c,1}, - {0x0040048c,1}, - {0x00400410,1}, - {0x00400490,1}, - {0x00400414,1}, - {0x00400494,1}, - {0x00400418,1}, - {0x00400498,1}, - {0x0040041c,1}, - {0x0040049c,1}, - {0x00400420,1}, - {0x004004a0,1}, - {0x00400424,1}, - {0x004004a4,1}, - {0x00400428,1}, - {0x004004a8,1}, - {0x0040042c,1}, - {0x004004ac,1}, - {0x00400430,1}, - {0x004004b0,1}, - {0x00400434,1}, - {0x004004b4,1}, - {0x00400438,1}, - {0x004004b8,1}, - {0x0040043c,1}, - {0x004004bc,1}, - {0x00400440,1}, - {0x004004c0,1}, - {0x00400444,1}, - {0x004004c4,1}, - {0x00400448,1}, - {0x004004c8,1}, - {0x0040044c,1}, - {0x004004cc,1}, - {0x00400450,1}, - {0x004004d0,1}, - {0x00400454,1}, - {0x004004d4,1}, - {0x00400458,1}, - {0x004004d8,1}, - {0x0040045c,1}, - {0x004004dc,1}, - {0x00400460,1}, - {0x004004e0,1}, - {0x00400464,1}, - {0x004004e4,1}, - {0x00400468,1}, - {0x004004e8,1}, - {0x0040046c,1}, - {0x004004ec,1}, - {0x00400470,1}, - {0x004004f0,1}, - {0x00400474,1}, - {0x004004f4,1}, - {0x00400478,1}, - {0x004004f8,1}, - {0x0040047c,1}, - {0x004004fc,1}, - {0x0040053c,1}, - {0x00400544,1}, - {0x00400540,1}, - {0x00400548,1}, - {0x00400560,1}, - {0x00400568,1}, - {0x00400564,1}, - {0x0040056c,1}, - {0x00400534,1}, - {0x00400538,1}, - {0x00400514,1}, - {0x00400518,1}, - {0x0040051c,1}, - {0x00400520,1}, - {0x00400524,1}, - {0x00400528,1}, - {0x0040052c,1}, - {0x00400530,1}, - {0x00400d00,1}, - {0x00400d40,1}, - {0x00400d80,1}, - {0x00400d04,1}, - {0x00400d44,1}, - {0x00400d84,1}, - {0x00400d08,1}, - {0x00400d48,1}, - {0x00400d88,1}, - {0x00400d0c,1}, - {0x00400d4c,1}, - {0x00400d8c,1}, - {0x00400d10,1}, - {0x00400d50,1}, - {0x00400d90,1}, - {0x00400d14,1}, - {0x00400d54,1}, - {0x00400d94,1}, - {0x00400d18,1}, - {0x00400d58,1}, - {0x00400d98,1}, - {0x00400d1c,1}, - {0x00400d5c,1}, - {0x00400d9c,1}, - {0x00400d20,1}, - {0x00400d60,1}, - {0x00400da0,1}, - {0x00400d24,1}, - {0x00400d64,1}, - {0x00400da4,1}, - {0x00400d28,1}, - {0x00400d68,1}, - {0x00400da8,1}, - {0x00400d2c,1}, - {0x00400d6c,1}, - {0x00400dac,1}, - {0x00400d30,1}, - {0x00400d70,1}, - {0x00400db0,1}, - {0x00400d34,1}, - {0x00400d74,1}, - {0x00400db4,1}, - {0x00400d38,1}, - {0x00400d78,1}, - {0x00400db8,1}, - {0x00400d3c,1}, - {0x00400d7c,1}, - {0x00400dbc,1}, - {0x00400590,1}, - {0x00400594,1}, - {0x00400598,1}, - {0x0040059c,1}, - {0x004005a8,1}, - {0x004005ac,1}, - {0x004005b0,1}, - {0x004005b4,1}, - {0x004005c0,1}, - {0x004005c4,1}, - {0x004005c8,1}, - {0x004005cc,1}, - {0x004005d0,1}, - {0x004005d4,1}, - {0x004005d8,1}, - {0x004005dc,1}, - {0x004005e0,1}, - {NV04_PGRAPH_PASSTHRU_0,1}, - {NV04_PGRAPH_PASSTHRU_1,1}, - {NV04_PGRAPH_PASSTHRU_2,1}, - {NV04_PGRAPH_DVD_COLORFMT,1}, - {NV04_PGRAPH_SCALED_FORMAT,1}, - {NV04_PGRAPH_MISC24_0,1}, - {NV04_PGRAPH_MISC24_1,1}, - {NV04_PGRAPH_MISC24_2,1}, - {0x00400500,1}, - {0x00400504,1}, - {NV04_PGRAPH_VALID1,1}, - {NV04_PGRAPH_VALID2,1} +static uint32_t nv04_graph_ctx_regs [] = { + NV04_PGRAPH_CTX_SWITCH1, + NV04_PGRAPH_CTX_SWITCH2, + NV04_PGRAPH_CTX_SWITCH3, + NV04_PGRAPH_CTX_SWITCH4, + NV04_PGRAPH_CTX_CACHE1, + NV04_PGRAPH_CTX_CACHE2, + NV04_PGRAPH_CTX_CACHE3, + NV04_PGRAPH_CTX_CACHE4, + 0x00400184, + 0x004001a4, + 0x004001c4, + 0x004001e4, + 0x00400188, + 0x004001a8, + 0x004001c8, + 0x004001e8, + 0x0040018c, + 0x004001ac, + 0x004001cc, + 0x004001ec, + 0x00400190, + 0x004001b0, + 0x004001d0, + 0x004001f0, + 0x00400194, + 0x004001b4, + 0x004001d4, + 0x004001f4, + 0x00400198, + 0x004001b8, + 0x004001d8, + 0x004001f8, + 0x0040019c, + 0x004001bc, + 0x004001dc, + 0x004001fc, + 0x00400174, + NV04_PGRAPH_DMA_START_0, + NV04_PGRAPH_DMA_START_1, + NV04_PGRAPH_DMA_LENGTH, + NV04_PGRAPH_DMA_MISC, + NV04_PGRAPH_DMA_PITCH, + NV04_PGRAPH_BOFFSET0, + NV04_PGRAPH_BBASE0, + NV04_PGRAPH_BLIMIT0, + NV04_PGRAPH_BOFFSET1, + NV04_PGRAPH_BBASE1, + NV04_PGRAPH_BLIMIT1, + NV04_PGRAPH_BOFFSET2, + NV04_PGRAPH_BBASE2, + NV04_PGRAPH_BLIMIT2, + NV04_PGRAPH_BOFFSET3, + NV04_PGRAPH_BBASE3, + NV04_PGRAPH_BLIMIT3, + NV04_PGRAPH_BOFFSET4, + NV04_PGRAPH_BBASE4, + NV04_PGRAPH_BLIMIT4, + NV04_PGRAPH_BOFFSET5, + NV04_PGRAPH_BBASE5, + NV04_PGRAPH_BLIMIT5, + NV04_PGRAPH_BPITCH0, + NV04_PGRAPH_BPITCH1, + NV04_PGRAPH_BPITCH2, + NV04_PGRAPH_BPITCH3, + NV04_PGRAPH_BPITCH4, + NV04_PGRAPH_SURFACE, + NV04_PGRAPH_STATE, + NV04_PGRAPH_BSWIZZLE2, + NV04_PGRAPH_BSWIZZLE5, + NV04_PGRAPH_BPIXEL, + NV04_PGRAPH_NOTIFY, + NV04_PGRAPH_PATT_COLOR0, + NV04_PGRAPH_PATT_COLOR1, + NV04_PGRAPH_PATT_COLORRAM+0x00, + NV04_PGRAPH_PATT_COLORRAM+0x01, + NV04_PGRAPH_PATT_COLORRAM+0x02, + NV04_PGRAPH_PATT_COLORRAM+0x03, + NV04_PGRAPH_PATT_COLORRAM+0x04, + NV04_PGRAPH_PATT_COLORRAM+0x05, + NV04_PGRAPH_PATT_COLORRAM+0x06, + NV04_PGRAPH_PATT_COLORRAM+0x07, + NV04_PGRAPH_PATT_COLORRAM+0x08, + NV04_PGRAPH_PATT_COLORRAM+0x09, + NV04_PGRAPH_PATT_COLORRAM+0x0A, + NV04_PGRAPH_PATT_COLORRAM+0x0B, + NV04_PGRAPH_PATT_COLORRAM+0x0C, + NV04_PGRAPH_PATT_COLORRAM+0x0D, + NV04_PGRAPH_PATT_COLORRAM+0x0E, + NV04_PGRAPH_PATT_COLORRAM+0x0F, + NV04_PGRAPH_PATT_COLORRAM+0x10, + NV04_PGRAPH_PATT_COLORRAM+0x11, + NV04_PGRAPH_PATT_COLORRAM+0x12, + NV04_PGRAPH_PATT_COLORRAM+0x13, + NV04_PGRAPH_PATT_COLORRAM+0x14, + NV04_PGRAPH_PATT_COLORRAM+0x15, + NV04_PGRAPH_PATT_COLORRAM+0x16, + NV04_PGRAPH_PATT_COLORRAM+0x17, + NV04_PGRAPH_PATT_COLORRAM+0x18, + NV04_PGRAPH_PATT_COLORRAM+0x19, + NV04_PGRAPH_PATT_COLORRAM+0x1A, + NV04_PGRAPH_PATT_COLORRAM+0x1B, + NV04_PGRAPH_PATT_COLORRAM+0x1C, + NV04_PGRAPH_PATT_COLORRAM+0x1D, + NV04_PGRAPH_PATT_COLORRAM+0x1E, + NV04_PGRAPH_PATT_COLORRAM+0x1F, + NV04_PGRAPH_PATT_COLORRAM+0x20, + NV04_PGRAPH_PATT_COLORRAM+0x21, + NV04_PGRAPH_PATT_COLORRAM+0x22, + NV04_PGRAPH_PATT_COLORRAM+0x23, + NV04_PGRAPH_PATT_COLORRAM+0x24, + NV04_PGRAPH_PATT_COLORRAM+0x25, + NV04_PGRAPH_PATT_COLORRAM+0x26, + NV04_PGRAPH_PATT_COLORRAM+0x27, + NV04_PGRAPH_PATT_COLORRAM+0x28, + NV04_PGRAPH_PATT_COLORRAM+0x29, + NV04_PGRAPH_PATT_COLORRAM+0x2A, + NV04_PGRAPH_PATT_COLORRAM+0x2B, + NV04_PGRAPH_PATT_COLORRAM+0x2C, + NV04_PGRAPH_PATT_COLORRAM+0x2D, + NV04_PGRAPH_PATT_COLORRAM+0x2E, + NV04_PGRAPH_PATT_COLORRAM+0x2F, + NV04_PGRAPH_PATT_COLORRAM+0x30, + NV04_PGRAPH_PATT_COLORRAM+0x31, + NV04_PGRAPH_PATT_COLORRAM+0x32, + NV04_PGRAPH_PATT_COLORRAM+0x33, + NV04_PGRAPH_PATT_COLORRAM+0x34, + NV04_PGRAPH_PATT_COLORRAM+0x35, + NV04_PGRAPH_PATT_COLORRAM+0x36, + NV04_PGRAPH_PATT_COLORRAM+0x37, + NV04_PGRAPH_PATT_COLORRAM+0x38, + NV04_PGRAPH_PATT_COLORRAM+0x39, + NV04_PGRAPH_PATT_COLORRAM+0x3A, + NV04_PGRAPH_PATT_COLORRAM+0x3B, + NV04_PGRAPH_PATT_COLORRAM+0x3C, + NV04_PGRAPH_PATT_COLORRAM+0x3D, + NV04_PGRAPH_PATT_COLORRAM+0x3E, + NV04_PGRAPH_PATT_COLORRAM+0x3F, + NV04_PGRAPH_PATTERN, + 0x0040080c, + NV04_PGRAPH_PATTERN_SHAPE, + 0x00400600, + NV04_PGRAPH_ROP3, + NV04_PGRAPH_CHROMA, + NV04_PGRAPH_BETA_AND, + NV04_PGRAPH_BETA_PREMULT, + NV04_PGRAPH_CONTROL0, + NV04_PGRAPH_CONTROL1, + NV04_PGRAPH_CONTROL2, + NV04_PGRAPH_BLEND, + NV04_PGRAPH_STORED_FMT, + NV04_PGRAPH_SOURCE_COLOR, + 0x00400560, + 0x00400568, + 0x00400564, + 0x0040056c, + 0x00400400, + 0x00400480, + 0x00400404, + 0x00400484, + 0x00400408, + 0x00400488, + 0x0040040c, + 0x0040048c, + 0x00400410, + 0x00400490, + 0x00400414, + 0x00400494, + 0x00400418, + 0x00400498, + 0x0040041c, + 0x0040049c, + 0x00400420, + 0x004004a0, + 0x00400424, + 0x004004a4, + 0x00400428, + 0x004004a8, + 0x0040042c, + 0x004004ac, + 0x00400430, + 0x004004b0, + 0x00400434, + 0x004004b4, + 0x00400438, + 0x004004b8, + 0x0040043c, + 0x004004bc, + 0x00400440, + 0x004004c0, + 0x00400444, + 0x004004c4, + 0x00400448, + 0x004004c8, + 0x0040044c, + 0x004004cc, + 0x00400450, + 0x004004d0, + 0x00400454, + 0x004004d4, + 0x00400458, + 0x004004d8, + 0x0040045c, + 0x004004dc, + 0x00400460, + 0x004004e0, + 0x00400464, + 0x004004e4, + 0x00400468, + 0x004004e8, + 0x0040046c, + 0x004004ec, + 0x00400470, + 0x004004f0, + 0x00400474, + 0x004004f4, + 0x00400478, + 0x004004f8, + 0x0040047c, + 0x004004fc, + 0x0040053c, + 0x00400544, + 0x00400540, + 0x00400548, + 0x00400560, + 0x00400568, + 0x00400564, + 0x0040056c, + 0x00400534, + 0x00400538, + 0x00400514, + 0x00400518, + 0x0040051c, + 0x00400520, + 0x00400524, + 0x00400528, + 0x0040052c, + 0x00400530, + 0x00400d00, + 0x00400d40, + 0x00400d80, + 0x00400d04, + 0x00400d44, + 0x00400d84, + 0x00400d08, + 0x00400d48, + 0x00400d88, + 0x00400d0c, + 0x00400d4c, + 0x00400d8c, + 0x00400d10, + 0x00400d50, + 0x00400d90, + 0x00400d14, + 0x00400d54, + 0x00400d94, + 0x00400d18, + 0x00400d58, + 0x00400d98, + 0x00400d1c, + 0x00400d5c, + 0x00400d9c, + 0x00400d20, + 0x00400d60, + 0x00400da0, + 0x00400d24, + 0x00400d64, + 0x00400da4, + 0x00400d28, + 0x00400d68, + 0x00400da8, + 0x00400d2c, + 0x00400d6c, + 0x00400dac, + 0x00400d30, + 0x00400d70, + 0x00400db0, + 0x00400d34, + 0x00400d74, + 0x00400db4, + 0x00400d38, + 0x00400d78, + 0x00400db8, + 0x00400d3c, + 0x00400d7c, + 0x00400dbc, + 0x00400590, + 0x00400594, + 0x00400598, + 0x0040059c, + 0x004005a8, + 0x004005ac, + 0x004005b0, + 0x004005b4, + 0x004005c0, + 0x004005c4, + 0x004005c8, + 0x004005cc, + 0x004005d0, + 0x004005d4, + 0x004005d8, + 0x004005dc, + 0x004005e0, + NV04_PGRAPH_PASSTHRU_0, + NV04_PGRAPH_PASSTHRU_1, + NV04_PGRAPH_PASSTHRU_2, + NV04_PGRAPH_DVD_COLORFMT, + NV04_PGRAPH_SCALED_FORMAT, + NV04_PGRAPH_MISC24_0, + NV04_PGRAPH_MISC24_1, + NV04_PGRAPH_MISC24_2, + 0x00400500, + 0x00400504, + NV04_PGRAPH_VALID1, + NV04_PGRAPH_VALID2 + +}; +struct graph_state { + int nv04[sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0])]; }; -void nouveau_nv04_context_switch(drm_device_t *dev) +void nouveau_nv04_context_switch(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - int channel, channel_old, i, j, index; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *next, *last; + int chid; + + if (!dev) { + DRM_DEBUG("Invalid drm_device\n"); + return; + } + dev_priv = dev->dev_private; + if (!dev_priv) { + DRM_DEBUG("Invalid drm_nouveau_private\n"); + return; + } + if (!dev_priv->fifos) { + DRM_DEBUG("Invalid drm_nouveau_private->fifos\n"); + return; + } - channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1); - channel_old = (NV_READ(NV04_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1); + chid = NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1); + next = dev_priv->fifos[chid]; - DRM_DEBUG("NV: PGRAPH context switch interrupt channel %x -> %x\n",channel_old, channel); + if (!next) { + DRM_DEBUG("Invalid next channel\n"); + return; + } - NV_WRITE(NV03_PFIFO_CACHES, 0x0); + chid = (NV_READ(NV04_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1); + last = dev_priv->fifos[chid]; + + if (!last) { + DRM_DEBUG("WARNING: Invalid last channel, switch to %x\n", + next->id); + } else { + DRM_INFO("NV: PGRAPH context switch interrupt channel %x -> %x\n", + last->id, next->id); + } + +/* NV_WRITE(NV03_PFIFO_CACHES, 0x0); NV_WRITE(NV04_PFIFO_CACHE0_PULL0, 0x0); - NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x0); + NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x0);*/ NV_WRITE(NV04_PGRAPH_FIFO,0x0); - nouveau_wait_for_idle(dev); + if (last) + nv04_graph_save_context(last); - // save PGRAPH context - index=0; - for (i = 0; i<sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++) - for (j = 0; j<nv04_graph_ctx_regs[i].number; j++) - { - dev_priv->fifos[channel_old].pgraph_ctx[index] = NV_READ(nv04_graph_ctx_regs[i].reg+j*4); - index++; - } + nouveau_wait_for_idle(dev); NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10000000); NV_WRITE(NV04_PGRAPH_CTX_USER, (NV_READ(NV04_PGRAPH_CTX_USER) & 0xffffff) | (0x0f << 24)); - // restore PGRAPH context - index=0; - for (i = 0; i<sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++) - for (j = 0; j<nv04_graph_ctx_regs[i].number; j++) - { - NV_WRITE(nv04_graph_ctx_regs[i].reg+j*4, dev_priv->fifos[channel].pgraph_ctx[index]); - index++; - } + nouveau_wait_for_idle(dev); + + nv04_graph_load_context(next); NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100); - NV_WRITE(NV04_PGRAPH_CTX_USER, channel << 24); + NV_WRITE(NV04_PGRAPH_CTX_USER, next->id << 24); NV_WRITE(NV04_PGRAPH_FFINTFC_ST2, NV_READ(NV04_PGRAPH_FFINTFC_ST2)&0x000FFFFF); - NV_WRITE(NV04_PGRAPH_FIFO,0x0); +/* NV_WRITE(NV04_PGRAPH_FIFO,0x0); NV_WRITE(NV04_PFIFO_CACHE0_PULL0, 0x0); NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x1); - NV_WRITE(NV03_PFIFO_CACHES, 0x1); + NV_WRITE(NV03_PFIFO_CACHES, 0x1);*/ NV_WRITE(NV04_PGRAPH_FIFO,0x1); } -int nv04_graph_context_create(drm_device_t *dev, int channel) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("nv04_graph_context_create %d\n", channel); +int nv04_graph_create_context(struct nouveau_channel *chan) { + struct graph_state* pgraph_ctx; + DRM_DEBUG("nv04_graph_context_create %d\n", chan->id); + + chan->pgraph_ctx = pgraph_ctx = drm_calloc(1, sizeof(*pgraph_ctx), + DRM_MEM_DRIVER); - memset(dev_priv->fifos[channel].pgraph_ctx, 0, sizeof(dev_priv->fifos[channel].pgraph_ctx)); + if (pgraph_ctx == NULL) + return -ENOMEM; //dev_priv->fifos[channel].pgraph_ctx_user = channel << 24; - dev_priv->fifos[channel].pgraph_ctx[0] = 0x0001ffff; + pgraph_ctx->nv04[0] = 0x0001ffff; /* is it really needed ??? */ //dev_priv->fifos[channel].pgraph_ctx[1] = NV_READ(NV_PGRAPH_DEBUG_4); //dev_priv->fifos[channel].pgraph_ctx[2] = NV_READ(0x004006b0); @@ -351,34 +436,68 @@ int nv04_graph_context_create(drm_device_t *dev, int channel) { return 0; } +void nv04_graph_destroy_context(struct nouveau_channel *chan) +{ + struct graph_state* pgraph_ctx = chan->pgraph_ctx; + + drm_free(pgraph_ctx, sizeof(*pgraph_ctx), DRM_MEM_DRIVER); + chan->pgraph_ctx = NULL; +} + +int nv04_graph_load_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct graph_state* pgraph_ctx = chan->pgraph_ctx; + int i; + + for (i = 0; i < sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++) + NV_WRITE(nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]); + + return 0; +} + +int nv04_graph_save_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct graph_state* pgraph_ctx = chan->pgraph_ctx; + int i; -int nv04_graph_init(drm_device_t *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - int i,sum=0; + for (i = 0; i < sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++) + pgraph_ctx->nv04[i] = NV_READ(nv04_graph_ctx_regs[i]); + + return 0; +} + +int nv04_graph_init(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); - // check the context is big enough - for ( i = 0 ; i<sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++) - sum+=nv04_graph_ctx_regs[i].number; - if ( sum*4>sizeof(dev_priv->fifos[0].pgraph_ctx) ) - DRM_ERROR("pgraph_ctx too small\n"); - - NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000); - NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF); - - NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x000001FF); - NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x1230C000); - NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x72111101); - NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x11D5F071); - NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x0004FF31); - NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x4004FF31 | - (0x00D00000) | - (1<<29) | - (1<<31)); + /* Enable PGRAPH interrupts */ + NV_WRITE(NV03_PGRAPH_INTR, 0xFFFFFFFF); + NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); + + NV_WRITE(NV04_PGRAPH_VALID1, 0); + NV_WRITE(NV04_PGRAPH_VALID2, 0); + /*NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x000001FF); + NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/ + NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x1231c000); + /*1231C000 blob, 001 haiku*/ + //*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/ + NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x72111100); + /*0x72111100 blob , 01 haiku*/ + /*NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/ + NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x11d5f071); + /*haiku same*/ + + /*NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/ + NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x10d4ff31); + /*haiku and blob 10d4*/ NV_WRITE(NV04_PGRAPH_STATE , 0xFFFFFFFF); NV_WRITE(NV04_PGRAPH_CTX_CONTROL , 0x10010100); @@ -391,7 +510,6 @@ int nv04_graph_init(drm_device_t *dev) { return 0; } -void nv04_graph_takedown(drm_device_t *dev) +void nv04_graph_takedown(struct drm_device *dev) { } - diff --git a/shared-core/nv04_instmem.c b/shared-core/nv04_instmem.c new file mode 100644 index 00000000..5a446450 --- /dev/null +++ b/shared-core/nv04_instmem.c @@ -0,0 +1,159 @@ +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" + +static void +nv04_instmem_determine_amount(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; + + /* Figure out how much instance memory we need */ + if (dev_priv->card_type >= NV_40) { + /* We'll want more instance memory than this on some NV4x cards. + * There's a 16MB aperture to play with that maps onto the end + * of vram. For now, only reserve a small piece until we know + * more about what each chipset requires. + */ + dev_priv->ramin_rsvd_vram = (1*1024* 1024); + } else { + /*XXX: what *are* the limits on <NV40 cards?, and does RAMIN + * exist in vram on those cards as well? + */ + dev_priv->ramin_rsvd_vram = (512*1024); + } + DRM_DEBUG("RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram>>10); + + /* Clear all of it, except the BIOS image that's in the first 64KiB */ + for (i=(64*1024); i<dev_priv->ramin_rsvd_vram; i+=4) + NV_WI32(i, 0x00000000); +} + +static void +nv04_instmem_configure_fixed_tables(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + /* FIFO hash table (RAMHT) + * use 4k hash table at RAMIN+0x10000 + * TODO: extend the hash table + */ + dev_priv->ramht_offset = 0x10000; + dev_priv->ramht_bits = 9; + dev_priv->ramht_size = (1 << dev_priv->ramht_bits); + DRM_DEBUG("RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset, + dev_priv->ramht_size); + + /* FIFO runout table (RAMRO) - 512k at 0x11200 */ + dev_priv->ramro_offset = 0x11200; + dev_priv->ramro_size = 512; + DRM_DEBUG("RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset, + dev_priv->ramro_size); + + /* FIFO context table (RAMFC) + * NV40 : Not sure exactly how to position RAMFC on some cards, + * 0x30002 seems to position it at RAMIN+0x20000 on these + * cards. RAMFC is 4kb (32 fifos, 128byte entries). + * Others: Position RAMFC at RAMIN+0x11400 + */ + switch(dev_priv->card_type) + { + case NV_40: + case NV_44: + dev_priv->ramfc_offset = 0x20000; + dev_priv->ramfc_size = nouveau_fifo_number(dev) * + nouveau_fifo_ctx_size(dev); + break; + case NV_30: + case NV_20: + case NV_17: + case NV_11: + case NV_10: + case NV_04: + default: + dev_priv->ramfc_offset = 0x11400; + dev_priv->ramfc_size = nouveau_fifo_number(dev) * + nouveau_fifo_ctx_size(dev); + break; + } + DRM_DEBUG("RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset, + dev_priv->ramfc_size); +} + +int nv04_instmem_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t offset; + int ret = 0; + + nv04_instmem_determine_amount(dev); + nv04_instmem_configure_fixed_tables(dev); + + /* Create a heap to manage RAMIN allocations, we don't allocate + * the space that was reserved for RAMHT/FC/RO. + */ + offset = dev_priv->ramfc_offset + dev_priv->ramfc_size; + + /* On my NV4E, there's *something* clobbering the 16KiB just after + * where we setup these fixed tables. No idea what it is just yet, + * so reserve this space on all NV4X cards for now. + */ + if (dev_priv->card_type >= NV_40) + offset += 16*1024; + + ret = nouveau_mem_init_heap(&dev_priv->ramin_heap, + offset, dev_priv->ramin_rsvd_vram - offset); + if (ret) { + dev_priv->ramin_heap = NULL; + DRM_ERROR("Failed to init RAMIN heap\n"); + } + + return ret; +} + +void +nv04_instmem_takedown(struct drm_device *dev) +{ +} + +int +nv04_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, uint32_t *sz) +{ + if (gpuobj->im_backing) + return -EINVAL; + + return 0; +} + +void +nv04_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (gpuobj && gpuobj->im_backing) { + if (gpuobj->im_bound) + dev_priv->Engine.instmem.unbind(dev, gpuobj); + gpuobj->im_backing = NULL; + } +} + +int +nv04_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +{ + if (!gpuobj->im_pramin || gpuobj->im_bound) + return -EINVAL; + + gpuobj->im_bound = 1; + return 0; +} + +int +nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +{ + if (gpuobj->im_bound == 0) + return -EINVAL; + + gpuobj->im_bound = 0; + return 0; +} + diff --git a/shared-core/nv04_mc.c b/shared-core/nv04_mc.c index 0e23efb2..eee0c50c 100644 --- a/shared-core/nv04_mc.c +++ b/shared-core/nv04_mc.c @@ -4,22 +4,20 @@ #include "nouveau_drm.h" int -nv04_mc_init(drm_device_t *dev) +nv04_mc_init(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; /* Power up everything, resetting each individual unit will * be done later if needed. */ NV_WRITE(NV03_PMC_ENABLE, 0xFFFFFFFF); - NV_WRITE(NV03_PMC_INTR_EN_0, 0); - return 0; } void -nv04_mc_takedown(drm_device_t *dev) +nv04_mc_takedown(struct drm_device *dev) { } diff --git a/shared-core/nv04_timer.c b/shared-core/nv04_timer.c index a4b4e826..08a27f4f 100644 --- a/shared-core/nv04_timer.c +++ b/shared-core/nv04_timer.c @@ -4,9 +4,9 @@ #include "nouveau_drm.h" int -nv04_timer_init(drm_device_t *dev) +nv04_timer_init(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; NV_WRITE(NV04_PTIMER_INTR_EN_0, 0x00000000); NV_WRITE(NV04_PTIMER_INTR_0, 0xFFFFFFFF); @@ -17,8 +17,29 @@ nv04_timer_init(drm_device_t *dev) return 0; } +uint64_t +nv04_timer_read(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t low; + /* From kmmio dumps on nv28 this looks like how the blob does this. + * It reads the high dword twice, before and after. + * The only explanation seems to be that the 64-bit timer counter + * advances between high and low dword reads and may corrupt the + * result. Not confirmed. + */ + uint32_t high2 = NV_READ(NV04_PTIMER_TIME_1); + uint32_t high1; + do { + high1 = high2; + low = NV_READ(NV04_PTIMER_TIME_0); + high2 = NV_READ(NV04_PTIMER_TIME_1); + } while(high1 != high2); + return (((uint64_t)high2) << 32) | (uint64_t)low; +} + void -nv04_timer_takedown(drm_device_t *dev) +nv04_timer_takedown(struct drm_device *dev) { } diff --git a/shared-core/nv10_fb.c b/shared-core/nv10_fb.c index e8336a2d..7fff5b3f 100644 --- a/shared-core/nv10_fb.c +++ b/shared-core/nv10_fb.c @@ -4,9 +4,9 @@ #include "nouveau_drm.h" int -nv10_fb_init(drm_device_t *dev) +nv10_fb_init(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t fb_bar_size; int i; @@ -20,7 +20,7 @@ nv10_fb_init(drm_device_t *dev) } void -nv10_fb_takedown(drm_device_t *dev) +nv10_fb_takedown(struct drm_device *dev) { } diff --git a/shared-core/nv10_fifo.c b/shared-core/nv10_fifo.c new file mode 100644 index 00000000..c86725d2 --- /dev/null +++ b/shared-core/nv10_fifo.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" + + +#define RAMFC_WR(offset,val) INSTANCE_WR(chan->ramfc->gpuobj, \ + NV10_RAMFC_##offset/4, (val)) +#define RAMFC_RD(offset) INSTANCE_RD(chan->ramfc->gpuobj, \ + NV10_RAMFC_##offset/4) +#define NV10_RAMFC(c) (dev_priv->ramfc_offset + ((c) * NV10_RAMFC__SIZE)) +#define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32) + +int +nv10_fifo_create_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + if ((ret = nouveau_gpuobj_new_fake(dev, NV10_RAMFC(chan->id), ~0, + NV10_RAMFC__SIZE, + NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ZERO_FREE, + NULL, &chan->ramfc))) + return ret; + + /* Fill entries that are seen filled in dumps of nvidia driver just + * after channel's is put into DMA mode + */ + RAMFC_WR(DMA_PUT , chan->pushbuf_base); + RAMFC_WR(DMA_GET , chan->pushbuf_base); + RAMFC_WR(DMA_INSTANCE , chan->pushbuf->instance >> 4); + RAMFC_WR(DMA_FETCH , NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | +#ifdef __BIG_ENDIAN + NV_PFIFO_CACHE1_BIG_ENDIAN | +#endif + 0); + + /* enable the fifo dma operation */ + NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)|(1<<chan->id)); + return 0; +} + +void +nv10_fifo_destroy_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + + NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<chan->id)); + + nouveau_gpuobj_ref_del(dev, &chan->ramfc); +} + +int +nv10_fifo_load_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t tmp; + + NV_WRITE(NV03_PFIFO_CACHE1_PUSH1 , 0x00000100 | chan->id); + + NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET , RAMFC_RD(DMA_GET)); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT , RAMFC_RD(DMA_PUT)); + NV_WRITE(NV10_PFIFO_CACHE1_REF_CNT , RAMFC_RD(REF_CNT)); + + tmp = RAMFC_RD(DMA_INSTANCE); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_INSTANCE , tmp & 0xFFFF); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_DCOUNT , tmp >> 16); + + NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE , RAMFC_RD(DMA_STATE)); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_FETCH , RAMFC_RD(DMA_FETCH)); + NV_WRITE(NV04_PFIFO_CACHE1_ENGINE , RAMFC_RD(ENGINE)); + NV_WRITE(NV04_PFIFO_CACHE1_PULL1 , RAMFC_RD(PULL1_ENGINE)); + + if (dev_priv->chipset >= 0x17) { + NV_WRITE(NV10_PFIFO_CACHE1_ACQUIRE_VALUE, + RAMFC_RD(ACQUIRE_VALUE)); + NV_WRITE(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, + RAMFC_RD(ACQUIRE_TIMESTAMP)); + NV_WRITE(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT, + RAMFC_RD(ACQUIRE_TIMEOUT)); + NV_WRITE(NV10_PFIFO_CACHE1_SEMAPHORE, + RAMFC_RD(SEMAPHORE)); + NV_WRITE(NV10_PFIFO_CACHE1_DMA_SUBROUTINE, + RAMFC_RD(DMA_SUBROUTINE)); + } + + /* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */ + tmp = NV_READ(NV04_PFIFO_CACHE1_DMA_CTL) & ~(1<<31); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_CTL, tmp); + + return 0; +} + +int +nv10_fifo_save_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t tmp; + + RAMFC_WR(DMA_PUT , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT)); + RAMFC_WR(DMA_GET , NV_READ(NV04_PFIFO_CACHE1_DMA_GET)); + RAMFC_WR(REF_CNT , NV_READ(NV10_PFIFO_CACHE1_REF_CNT)); + + tmp = NV_READ(NV04_PFIFO_CACHE1_DMA_INSTANCE) & 0xFFFF; + tmp |= (NV_READ(NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16); + RAMFC_WR(DMA_INSTANCE , tmp); + + RAMFC_WR(DMA_STATE , NV_READ(NV04_PFIFO_CACHE1_DMA_STATE)); + RAMFC_WR(DMA_FETCH , NV_READ(NV04_PFIFO_CACHE1_DMA_FETCH)); + RAMFC_WR(ENGINE , NV_READ(NV04_PFIFO_CACHE1_ENGINE)); + RAMFC_WR(PULL1_ENGINE , NV_READ(NV04_PFIFO_CACHE1_PULL1)); + + if (dev_priv->chipset >= 0x17) { + RAMFC_WR(ACQUIRE_VALUE, + NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); + RAMFC_WR(ACQUIRE_TIMESTAMP, + NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP)); + RAMFC_WR(ACQUIRE_TIMEOUT, + NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); + RAMFC_WR(SEMAPHORE, + NV_READ(NV10_PFIFO_CACHE1_SEMAPHORE)); + RAMFC_WR(DMA_SUBROUTINE, + NV_READ(NV04_PFIFO_CACHE1_DMA_GET)); + } + + return 0; +} + diff --git a/shared-core/nv10_graph.c b/shared-core/nv10_graph.c index fb189709..c6319b8f 100644 --- a/shared-core/nv10_graph.c +++ b/shared-core/nv10_graph.c @@ -27,165 +27,22 @@ #include "nouveau_drm.h" #include "nouveau_drv.h" +#define NV10_FIFO_NUMBER 32 + +struct pipe_state { + uint32_t pipe_0x0000[0x040/4]; + uint32_t pipe_0x0040[0x010/4]; + uint32_t pipe_0x0200[0x0c0/4]; + uint32_t pipe_0x4400[0x080/4]; + uint32_t pipe_0x6400[0x3b0/4]; + uint32_t pipe_0x6800[0x2f0/4]; + uint32_t pipe_0x6c00[0x030/4]; + uint32_t pipe_0x7000[0x130/4]; + uint32_t pipe_0x7400[0x0c0/4]; + uint32_t pipe_0x7800[0x0c0/4]; +}; -static void nv10_praph_pipe(drm_device_t *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - int i; - - nouveau_wait_for_idle(dev); - /* XXX check haiku comments */ - NV_WRITE(NV10_PGRAPH_XFMODE0, 0x10000000); - NV_WRITE(NV10_PGRAPH_XFMODE1, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); - for (i = 0; i < 4; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); - for (i = 0; i < 4; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); - - for (i = 0; i < 3; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); - - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); - for (i = 0; i < 3; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000008); - - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000200); - for (i = 0; i < 48; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - - nouveau_wait_for_idle(dev); - - NV_WRITE(NV10_PGRAPH_XFMODE0, 0x00000000); - NV_WRITE(NV10_PGRAPH_XFMODE1, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006400); - for (i = 0; i < 211; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x40000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); - - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006800); - for (i = 0; i < 162; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); - for (i = 0; i < 25; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006c00); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0xbf800000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00007000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x7149f2ca); - for (i = 0; i < 35; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - - - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00007400); - for (i = 0; i < 48; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00007800); - for (i = 0; i < 48; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00004400); - for (i = 0; i < 32; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000000); - for (i = 0; i < 16; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - - NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); - for (i = 0; i < 4; i++) - NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); - - nouveau_wait_for_idle(dev); -} - -/* TODO replace address with name - use loops */ static int nv10_graph_ctx_regs [] = { -NV03_PGRAPH_XY_LOGIC_MISC0, - NV10_PGRAPH_CTX_SWITCH1, NV10_PGRAPH_CTX_SWITCH2, NV10_PGRAPH_CTX_SWITCH3, @@ -455,6 +312,7 @@ NV03_PGRAPH_ABS_UCLIPA_YMIN, NV03_PGRAPH_ABS_UCLIPA_YMAX, NV03_PGRAPH_ABS_ICLIP_XMAX, NV03_PGRAPH_ABS_ICLIP_YMAX, +NV03_PGRAPH_XY_LOGIC_MISC0, NV03_PGRAPH_XY_LOGIC_MISC1, NV03_PGRAPH_XY_LOGIC_MISC2, NV03_PGRAPH_XY_LOGIC_MISC3, @@ -462,18 +320,18 @@ NV03_PGRAPH_CLIPX_0, NV03_PGRAPH_CLIPX_1, NV03_PGRAPH_CLIPY_0, NV03_PGRAPH_CLIPY_1, -0x00400e40, -0x00400e44, -0x00400e48, -0x00400e4c, -0x00400e50, -0x00400e54, -0x00400e58, -0x00400e5c, -0x00400e60, -0x00400e64, -0x00400e68, -0x00400e6c, +NV10_PGRAPH_COMBINER0_IN_ALPHA, +NV10_PGRAPH_COMBINER1_IN_ALPHA, +NV10_PGRAPH_COMBINER0_IN_RGB, +NV10_PGRAPH_COMBINER1_IN_RGB, +NV10_PGRAPH_COMBINER_COLOR0, +NV10_PGRAPH_COMBINER_COLOR1, +NV10_PGRAPH_COMBINER0_OUT_ALPHA, +NV10_PGRAPH_COMBINER1_OUT_ALPHA, +NV10_PGRAPH_COMBINER0_OUT_RGB, +NV10_PGRAPH_COMBINER1_OUT_RGB, +NV10_PGRAPH_COMBINER_FINAL0, +NV10_PGRAPH_COMBINER_FINAL1, 0x00400e00, 0x00400e04, 0x00400e08, @@ -527,99 +385,396 @@ NV10_PGRAPH_DEBUG_4, 0x00400a04, }; -static int nv10_graph_ctx_regs_find_offset(drm_device_t *dev, int reg) +struct graph_state { + int nv10[sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0])]; + int nv17[sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0])]; + struct pipe_state pipe_state; +}; + +static void nv10_graph_save_pipe(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct graph_state* pgraph_ctx = chan->pgraph_ctx; + struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; + int i; +#define PIPE_SAVE(addr) \ + do { \ + NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, addr); \ + for (i=0; i < sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]); i++) \ + fifo_pipe_state->pipe_##addr[i] = NV_READ(NV10_PGRAPH_PIPE_DATA); \ + } while (0) + + PIPE_SAVE(0x4400); + PIPE_SAVE(0x0200); + PIPE_SAVE(0x6400); + PIPE_SAVE(0x6800); + PIPE_SAVE(0x6c00); + PIPE_SAVE(0x7000); + PIPE_SAVE(0x7400); + PIPE_SAVE(0x7800); + PIPE_SAVE(0x0040); + PIPE_SAVE(0x0000); + +#undef PIPE_SAVE +} + +static void nv10_graph_load_pipe(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct graph_state* pgraph_ctx = chan->pgraph_ctx; + struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; + int i; + uint32_t xfmode0, xfmode1; +#define PIPE_RESTORE(addr) \ + do { \ + NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, addr); \ + for (i=0; i < sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]); i++) \ + NV_WRITE(NV10_PGRAPH_PIPE_DATA, fifo_pipe_state->pipe_##addr[i]); \ + } while (0) + + + nouveau_wait_for_idle(dev); + /* XXX check haiku comments */ + xfmode0 = NV_READ(NV10_PGRAPH_XFMODE0); + xfmode1 = NV_READ(NV10_PGRAPH_XFMODE1); + NV_WRITE(NV10_PGRAPH_XFMODE0, 0x10000000); + NV_WRITE(NV10_PGRAPH_XFMODE1, 0x00000000); + NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); + for (i = 0; i < 4; i++) + NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); + for (i = 0; i < 4; i++) + NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); + + NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); + for (i = 0; i < 3; i++) + NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x3f800000); + + NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); + for (i = 0; i < 3; i++) + NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000000); + + NV_WRITE(NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); + NV_WRITE(NV10_PGRAPH_PIPE_DATA, 0x00000008); + + + PIPE_RESTORE(0x0200); + nouveau_wait_for_idle(dev); + + /* restore XFMODE */ + NV_WRITE(NV10_PGRAPH_XFMODE0, xfmode0); + NV_WRITE(NV10_PGRAPH_XFMODE1, xfmode1); + PIPE_RESTORE(0x6400); + PIPE_RESTORE(0x6800); + PIPE_RESTORE(0x6c00); + PIPE_RESTORE(0x7000); + PIPE_RESTORE(0x7400); + PIPE_RESTORE(0x7800); + PIPE_RESTORE(0x4400); + PIPE_RESTORE(0x0000); + PIPE_RESTORE(0x0040); + nouveau_wait_for_idle(dev); + +#undef PIPE_RESTORE +} + +static void nv10_graph_create_pipe(struct nouveau_channel *chan) { + struct graph_state* pgraph_ctx = chan->pgraph_ctx; + struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; + uint32_t *fifo_pipe_state_addr; + int i; +#define PIPE_INIT(addr) \ + do { \ + fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \ + } while (0) +#define PIPE_INIT_END(addr) \ + do { \ + if (fifo_pipe_state_addr != \ + sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]) + fifo_pipe_state->pipe_##addr) \ + DRM_ERROR("incomplete pipe init for 0x%x : %p/%p\n", addr, fifo_pipe_state_addr, \ + sizeof(fifo_pipe_state->pipe_##addr)/sizeof(fifo_pipe_state->pipe_##addr[0]) + fifo_pipe_state->pipe_##addr); \ + } while (0) +#define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value + + PIPE_INIT(0x0200); + for (i = 0; i < 48; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x0200); + + PIPE_INIT(0x6400); + for (i = 0; i < 211; i++) + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x40000000); + NV_WRITE_PIPE_INIT(0x40000000); + NV_WRITE_PIPE_INIT(0x40000000); + NV_WRITE_PIPE_INIT(0x40000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f000000); + NV_WRITE_PIPE_INIT(0x3f000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x3f800000); + PIPE_INIT_END(0x6400); + + PIPE_INIT(0x6800); + for (i = 0; i < 162; i++) + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f800000); + for (i = 0; i < 25; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x6800); + + PIPE_INIT(0x6c00); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0xbf800000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x6c00); + + PIPE_INIT(0x7000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + for (i = 0; i < 35; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x7000); + + PIPE_INIT(0x7400); + for (i = 0; i < 48; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x7400); + + PIPE_INIT(0x7800); + for (i = 0; i < 48; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x7800); + + PIPE_INIT(0x4400); + for (i = 0; i < 32; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x4400); + + PIPE_INIT(0x0000); + for (i = 0; i < 16; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x0000); + + PIPE_INIT(0x0040); + for (i = 0; i < 4; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x0040); + +#undef PIPE_INIT +#undef PIPE_INIT_END +#undef NV_WRITE_PIPE_INIT +} + +static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - int i, j; + int i; for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) { if (nv10_graph_ctx_regs[i] == reg) return i; } - if (dev_priv->chipset>=0x17) { - for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++) { - if (nv17_graph_ctx_regs[j] == reg) - return i; - } + DRM_ERROR("unknow offset nv10_ctx_regs %d\n", reg); + return -1; +} + +static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) +{ + int i; + for (i = 0; i < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++) { + if (nv17_graph_ctx_regs[i] == reg) + return i; } + DRM_ERROR("unknow offset nv17_ctx_regs %d\n", reg); return -1; } -static void restore_ctx_regs(drm_device_t *dev, int channel) +int nv10_graph_load_context(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *fifo = &dev_priv->fifos[channel]; - int i, j; + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct graph_state* pgraph_ctx = chan->pgraph_ctx; + int i; + for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) - NV_WRITE(nv10_graph_ctx_regs[i], fifo->pgraph_ctx[i]); + NV_WRITE(nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]); if (dev_priv->chipset>=0x17) { - for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++) - NV_WRITE(nv17_graph_ctx_regs[j], fifo->pgraph_ctx[i]); + for (i = 0; i < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++) + NV_WRITE(nv17_graph_ctx_regs[i], pgraph_ctx->nv17[i]); } - nouveau_wait_for_idle(dev); + + nv10_graph_load_pipe(chan); + + return 0; } -void nouveau_nv10_context_switch(drm_device_t *dev) +int nv10_graph_save_context(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - int channel, channel_old, i, j; + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct graph_state* pgraph_ctx = chan->pgraph_ctx; + int i; - channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1); - channel_old = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1); + for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) + pgraph_ctx->nv10[i] = NV_READ(nv10_graph_ctx_regs[i]); + if (dev_priv->chipset>=0x17) { + for (i = 0; i < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++) + pgraph_ctx->nv17[i] = NV_READ(nv17_graph_ctx_regs[i]); + } - DRM_INFO("NV: PGRAPH context switch interrupt channel %x -> %x\n",channel_old, channel); + nv10_graph_save_pipe(chan); - NV_WRITE(NV04_PGRAPH_FIFO,0x0); -#if 0 - NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000000); - NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000000); - NV_WRITE(NV_PFIFO_CACHES, 0x00000000); -#endif + return 0; +} - // save PGRAPH context - for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) - dev_priv->fifos[channel_old].pgraph_ctx[i] = NV_READ(nv10_graph_ctx_regs[i]); - if (dev_priv->chipset>=0x17) { - for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++) - dev_priv->fifos[channel_old].pgraph_ctx[i] = NV_READ(nv17_graph_ctx_regs[j]); +void nouveau_nv10_context_switch(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv; + struct nouveau_channel *next, *last; + int chid; + + if (!dev) { + DRM_DEBUG("Invalid drm_device\n"); + return; + } + dev_priv = dev->dev_private; + if (!dev_priv) { + DRM_DEBUG("Invalid drm_nouveau_private\n"); + return; + } + if (!dev_priv->fifos) { + DRM_DEBUG("Invalid drm_nouveau_private->fifos\n"); + return; + } + + chid = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 20)&(nouveau_fifo_number(dev)-1); + next = dev_priv->fifos[chid]; + + if (!next) { + DRM_ERROR("Invalid next channel\n"); + return; + } + + chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1); + last = dev_priv->fifos[chid]; + + if (!last) { + DRM_INFO("WARNING: Invalid last channel, switch to %x\n", + next->id); + } else { + DRM_DEBUG("NV: PGRAPH context switch interrupt channel %x -> %x\n", + last->id, next->id); } - + + NV_WRITE(NV04_PGRAPH_FIFO,0x0); + if (last) { + nouveau_wait_for_idle(dev); + nv10_graph_save_context(last); + } + nouveau_wait_for_idle(dev); NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10000000); - NV_WRITE(NV10_PGRAPH_CTX_USER, (NV_READ(NV10_PGRAPH_CTX_USER) & 0xffffff) | (0x1f << 24)); nouveau_wait_for_idle(dev); - // restore PGRAPH context -#if 1 - restore_ctx_regs(dev, channel); -#endif - + + nv10_graph_load_context(next); + NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100); - NV_WRITE(NV10_PGRAPH_CTX_USER, channel << 24); NV_WRITE(NV10_PGRAPH_FFINTFC_ST2, NV_READ(NV10_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF); - -#if 0 - NV_WRITE(NV_PFIFO_CACH1_PUL0, 0x00000001); - NV_WRITE(NV_PFIFO_CACH1_PUL1, 0x00000001); - NV_WRITE(NV_PFIFO_CACHES, 0x00000001); -#endif NV_WRITE(NV04_PGRAPH_FIFO,0x1); } #define NV_WRITE_CTX(reg, val) do { \ int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \ if (offset > 0) \ - fifo->pgraph_ctx[offset] = val; \ + pgraph_ctx->nv10[offset] = val; \ } while (0) -int nv10_graph_context_create(drm_device_t *dev, int channel) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *fifo = &dev_priv->fifos[channel]; - uint32_t tmp, vramsz; - DRM_DEBUG("nv10_graph_context_create %d\n", channel); +#define NV17_WRITE_CTX(reg, val) do { \ + int offset = nv17_graph_ctx_regs_find_offset(dev, reg); \ + if (offset > 0) \ + pgraph_ctx->nv17[offset] = val; \ + } while (0) + +int nv10_graph_create_context(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct graph_state* pgraph_ctx; - memset(fifo->pgraph_ctx, 0, sizeof(fifo->pgraph_ctx)); + DRM_DEBUG("nv10_graph_context_create %d\n", chan->id); + chan->pgraph_ctx = pgraph_ctx = drm_calloc(1, sizeof(*pgraph_ctx), + DRM_MEM_DRIVER); + + if (pgraph_ctx == NULL) + return -ENOMEM; + + /* mmio trace suggest that should be done in ddx with methods/objects */ +#if 0 + uint32_t tmp, vramsz; /* per channel init from ddx */ tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00; /*XXX the original ddx code, does this in 2 steps : @@ -644,28 +799,67 @@ int nv10_graph_context_create(drm_device_t *dev, int channel) { NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_YMIN, 0); NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff); NV_WRITE_CTX(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff); +#endif + NV_WRITE_CTX(0x00400e88, 0x08000000); + NV_WRITE_CTX(0x00400e9c, 0x4b7fffff); NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff); - /* is it really needed ??? */ + NV_WRITE_CTX(0x00400e10, 0x00001000); + NV_WRITE_CTX(0x00400e14, 0x00001000); + NV_WRITE_CTX(0x00400e30, 0x00080008); + NV_WRITE_CTX(0x00400e34, 0x00080008); if (dev_priv->chipset>=0x17) { - NV_WRITE_CTX(NV10_PGRAPH_DEBUG_4, NV_READ(NV10_PGRAPH_DEBUG_4)); - NV_WRITE_CTX(0x004006b0, NV_READ(0x004006b0)); + /* is it really needed ??? */ + NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4, NV_READ(NV10_PGRAPH_DEBUG_4)); + NV17_WRITE_CTX(0x004006b0, NV_READ(0x004006b0)); + NV17_WRITE_CTX(0x00400eac, 0x0fff0000); + NV17_WRITE_CTX(0x00400eb0, 0x0fff0000); + NV17_WRITE_CTX(0x00400ec0, 0x00000080); + NV17_WRITE_CTX(0x00400ed0, 0x00000080); } + NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->id << 24); - /* for the first channel init the regs */ - if (dev_priv->fifo_alloc_count == 0) - restore_ctx_regs(dev, channel); - - - //XXX should be saved/restored for each fifo - //we supposed here we have X fifo and only one 3D fifo. - nv10_praph_pipe(dev); + nv10_graph_create_pipe(chan); return 0; } +void nv10_graph_destroy_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct graph_state* pgraph_ctx = chan->pgraph_ctx; + int chid; + + drm_free(pgraph_ctx, sizeof(*pgraph_ctx), DRM_MEM_DRIVER); + chan->pgraph_ctx = NULL; -int nv10_graph_init(drm_device_t *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + chid = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1); + + /* This code seems to corrupt the 3D pipe, but blob seems to do similar things ???? + */ +#if 0 + /* does this avoid a potential context switch while we are written graph + * reg, or we should mask graph interrupt ??? + */ + NV_WRITE(NV04_PGRAPH_FIFO,0x0); + if (chid == chan->id) { + DRM_INFO("cleanning a channel with graph in current context\n"); + nouveau_wait_for_idle(dev); + DRM_INFO("reseting current graph context\n"); + /* can't be call here because of dynamic mem alloc */ + //nv10_graph_create_context(chan); + nv10_graph_load_context(chan); + } + NV_WRITE(NV04_PGRAPH_FIFO, 0x1); +#else + if (chid == chan->id) { + DRM_INFO("cleanning a channel with graph in current context\n"); + } +#endif +} + +int nv10_graph_init(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; int i; NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & @@ -673,16 +867,23 @@ int nv10_graph_init(drm_device_t *dev) { NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); - NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000); NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF); + NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000); NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x00118700); - NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x24E00810); - NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x55DE0030 | + //NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x24E00810); /* 0x25f92ad9 */ + NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x25f92ad9); + NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x55DE0830 | (1<<29) | (1<<31)); + if (dev_priv->chipset>=0x17) { + NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x1f000000); + NV_WRITE(0x004006b0, 0x40000020); + } + else + NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x00000000); /* copy tile info from PFB */ for (i=0; i<NV10_PFB_TILE__SIZE; i++) { @@ -692,6 +893,10 @@ int nv10_graph_init(drm_device_t *dev) { NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i))); } + NV_WRITE(NV10_PGRAPH_CTX_SWITCH1, 0x00000000); + NV_WRITE(NV10_PGRAPH_CTX_SWITCH2, 0x00000000); + NV_WRITE(NV10_PGRAPH_CTX_SWITCH3, 0x00000000); + NV_WRITE(NV10_PGRAPH_CTX_SWITCH4, 0x00000000); NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100); NV_WRITE(NV10_PGRAPH_STATE , 0xFFFFFFFF); NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001); @@ -699,7 +904,7 @@ int nv10_graph_init(drm_device_t *dev) { return 0; } -void nv10_graph_takedown(drm_device_t *dev) +void nv10_graph_takedown(struct drm_device *dev) { } diff --git a/shared-core/nv20_graph.c b/shared-core/nv20_graph.c index 7190fc84..e6ccf672 100644 --- a/shared-core/nv20_graph.c +++ b/shared-core/nv20_graph.c @@ -1,142 +1,686 @@ -/* - * Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr> - * All Rights Reserved. +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + +/* + * NV20 + * ----- + * There are 3 families : + * NV20 is 0x10de:0x020* + * NV25/28 is 0x10de:0x025* / 0x10de:0x028* + * NV2A is 0x10de:0x02A0 * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * NV30 + * ----- + * There are 3 families : + * NV30/31 is 0x10de:0x030* / 0x10de:0x031* + * NV34 is 0x10de:0x032* + * NV35/36 is 0x10de:0x033* / 0x10de:0x034* * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. + * Not seen in the wild, no dumps (probably NV35) : + * NV37 is 0x10de:0x00fc, 0x10de:0x00fd + * NV38 is 0x10de:0x0333, 0x10de:0x00fe * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. */ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" +#define NV20_GRCTX_SIZE (3580*4) +#define NV25_GRCTX_SIZE (3529*4) +#define NV2A_GRCTX_SIZE (3500*4) -#define NV20_GRCTX_SIZE (3529*4) +#define NV30_31_GRCTX_SIZE (24392) +#define NV34_GRCTX_SIZE (18140) +#define NV35_36_GRCTX_SIZE (22396) -int nv20_graph_context_create(drm_device_t *dev, int channel) { - drm_nouveau_private_t *dev_priv = - (drm_nouveau_private_t *)dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - unsigned int ctx_size = NV20_GRCTX_SIZE; +static void nv20_graph_context_init(struct drm_device *dev, + struct nouveau_gpuobj *ctx) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; int i; +/* +write32 #1 block at +0x00740adc NV_PRAMIN+0x40adc of 3369 (0xd29) elements: ++0x00740adc: ffff0000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740afc: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740b1c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740b3c: 00000000 0fff0000 0fff0000 00000000 00000000 00000000 00000000 00000000 ++0x00740b5c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740b7c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740b9c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740bbc: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740bdc: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740bfc: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 + ++0x00740c1c: 00000101 00000000 00000000 00000000 00000000 00000111 00000000 00000000 ++0x00740c3c: 00000000 00000000 00000000 44400000 00000000 00000000 00000000 00000000 ++0x00740c5c: 00000000 00000000 00000000 00000000 00000000 00000000 00030303 00030303 ++0x00740c7c: 00030303 00030303 00000000 00000000 00000000 00000000 00080000 00080000 ++0x00740c9c: 00080000 00080000 00000000 00000000 01012000 01012000 01012000 01012000 ++0x00740cbc: 000105b8 000105b8 000105b8 000105b8 00080008 00080008 00080008 00080008 ++0x00740cdc: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740cfc: 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 ++0x00740d1c: 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 ++0x00740d3c: 00000000 00000000 4b7fffff 00000000 00000000 00000000 00000000 00000000 + ++0x00740d5c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740d7c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740d9c: 00000001 00000000 00004000 00000000 00000000 00000001 00000000 00040000 ++0x00740dbc: 00010000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740ddc: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +... +*/ + INSTANCE_WR(ctx, (0x33c/4)+0, 0xffff0000); + INSTANCE_WR(ctx, (0x33c/4)+25, 0x0fff0000); + INSTANCE_WR(ctx, (0x33c/4)+26, 0x0fff0000); + INSTANCE_WR(ctx, (0x33c/4)+80, 0x00000101); + INSTANCE_WR(ctx, (0x33c/4)+85, 0x00000111); + INSTANCE_WR(ctx, (0x33c/4)+91, 0x44400000); + for (i = 0; i < 4; ++i) + INSTANCE_WR(ctx, (0x33c/4)+102+i, 0x00030303); + for (i = 0; i < 4; ++i) + INSTANCE_WR(ctx, (0x33c/4)+110+i, 0x00080000); + for (i = 0; i < 4; ++i) + INSTANCE_WR(ctx, (0x33c/4)+116+i, 0x01012000); + for (i = 0; i < 4; ++i) + INSTANCE_WR(ctx, (0x33c/4)+120+i, 0x000105b8); + for (i = 0; i < 4; ++i) + INSTANCE_WR(ctx, (0x33c/4)+124+i, 0x00080008); + for (i = 0; i < 16; ++i) + INSTANCE_WR(ctx, (0x33c/4)+136+i, 0x07ff0000); + INSTANCE_WR(ctx, (0x33c/4)+154, 0x4b7fffff); + INSTANCE_WR(ctx, (0x33c/4)+176, 0x00000001); + INSTANCE_WR(ctx, (0x33c/4)+178, 0x00004000); + INSTANCE_WR(ctx, (0x33c/4)+181, 0x00000001); + INSTANCE_WR(ctx, (0x33c/4)+183, 0x00040000); + INSTANCE_WR(ctx, (0x33c/4)+184, 0x00010000); + +/* +... ++0x0074239c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x007423bc: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 ++0x007423dc: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 ++0x007423fc: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 +... ++0x00742bdc: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 ++0x00742bfc: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 ++0x00742c1c: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 ++0x00742c3c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +... +*/ + for (i = 0; i < 0x880; i += 0x10) { + INSTANCE_WR(ctx, ((0x1c1c + i)/4)+0, 0x10700ff9); + INSTANCE_WR(ctx, ((0x1c1c + i)/4)+1, 0x0436086c); + INSTANCE_WR(ctx, ((0x1c1c + i)/4)+2, 0x000c001b); + } - /* Alloc and clear RAMIN to store the context */ - chan->ramin_grctx = nouveau_instmem_alloc(dev, ctx_size, 4); - if (!chan->ramin_grctx) - return DRM_ERR(ENOMEM); - for (i=0; i<ctx_size; i+=4) - INSTANCE_WR(chan->ramin_grctx, i/4, 0x00000000); +/* +write32 #1 block at +0x00742fbc NV_PRAMIN+0x42fbc of 4 (0x4) elements: ++0x00742fbc: 3f800000 00000000 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x281c/4), 0x3f800000); + +/* +write32 #1 block at +0x00742ffc NV_PRAMIN+0x42ffc of 12 (0xc) elements: ++0x00742ffc: 40000000 3f800000 3f000000 00000000 40000000 3f800000 00000000 bf800000 ++0x0074301c: 00000000 bf800000 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x285c/4)+0, 0x40000000); + INSTANCE_WR(ctx, (0x285c/4)+1, 0x3f800000); + INSTANCE_WR(ctx, (0x285c/4)+2, 0x3f000000); + INSTANCE_WR(ctx, (0x285c/4)+4, 0x40000000); + INSTANCE_WR(ctx, (0x285c/4)+5, 0x3f800000); + INSTANCE_WR(ctx, (0x285c/4)+7, 0xbf800000); + INSTANCE_WR(ctx, (0x285c/4)+9, 0xbf800000); + +/* +write32 #1 block at +0x00742fcc NV_PRAMIN+0x42fcc of 4 (0x4) elements: ++0x00742fcc: 00000000 3f800000 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x282c/4)+1, 0x3f800000); + +/* +write32 #1 block at +0x0074302c NV_PRAMIN+0x4302c of 4 (0x4) elements: ++0x0074302c: 00000000 00000000 00000000 00000000 +write32 #1 block at +0x00743c9c NV_PRAMIN+0x43c9c of 4 (0x4) elements: ++0x00743c9c: 00000000 00000000 00000000 00000000 +write32 #1 block at +0x00743c3c NV_PRAMIN+0x43c3c of 8 (0x8) elements: ++0x00743c3c: 00000000 00000000 000fe000 00000000 00000000 00000000 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x349c/4)+2, 0x000fe000); + +/* +write32 #1 block at +0x00743c6c NV_PRAMIN+0x43c6c of 4 (0x4) elements: ++0x00743c6c: 00000000 00000000 00000000 00000000 +write32 #1 block at +0x00743ccc NV_PRAMIN+0x43ccc of 4 (0x4) elements: ++0x00743ccc: 00000000 000003f8 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x352c/4)+1, 0x000003f8); + +/* write32 #1 NV_PRAMIN+0x43ce0 <- 0x002fe000 */ + INSTANCE_WR(ctx, 0x3540/4, 0x002fe000); + +/* +write32 #1 block at +0x00743cfc NV_PRAMIN+0x43cfc of 8 (0x8) elements: ++0x00743cfc: 001c527c 001c527c 001c527c 001c527c 001c527c 001c527c 001c527c 001c527c +*/ + for (i = 0; i < 8; ++i) + INSTANCE_WR(ctx, (0x355c/4)+i, 0x001c527c); +} - /* Initialise default context values */ - INSTANCE_WR(chan->ramin_grctx, 10, channel << 24); /* CTX_USER */ +static void nv2a_graph_context_init(struct drm_device *dev, + struct nouveau_gpuobj *ctx) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; - INSTANCE_WR(dev_priv->ctx_table, channel, nouveau_chip_instance_get(dev, chan->ramin_grctx)); + INSTANCE_WR(ctx, 0x33c/4, 0xffff0000); + for(i = 0x3a0; i< 0x3a8; i += 4) + INSTANCE_WR(ctx, i/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x47c/4, 0x00000101); + INSTANCE_WR(ctx, 0x490/4, 0x00000111); + INSTANCE_WR(ctx, 0x4a8/4, 0x44400000); + for(i = 0x4d4; i< 0x4e4; i += 4) + INSTANCE_WR(ctx, i/4, 0x00030303); + for(i = 0x4f4; i< 0x504; i += 4) + INSTANCE_WR(ctx, i/4, 0x00080000); + for(i = 0x50c; i< 0x51c; i += 4) + INSTANCE_WR(ctx, i/4, 0x01012000); + for(i = 0x51c; i< 0x52c; i += 4) + INSTANCE_WR(ctx, i/4, 0x000105b8); + for(i = 0x52c; i< 0x53c; i += 4) + INSTANCE_WR(ctx, i/4, 0x00080008); + for(i = 0x55c; i< 0x59c; i += 4) + INSTANCE_WR(ctx, i/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x5a4/4, 0x4b7fffff); + INSTANCE_WR(ctx, 0x5fc/4, 0x00000001); + INSTANCE_WR(ctx, 0x604/4, 0x00004000); + INSTANCE_WR(ctx, 0x610/4, 0x00000001); + INSTANCE_WR(ctx, 0x618/4, 0x00040000); + INSTANCE_WR(ctx, 0x61c/4, 0x00010000); + + for (i=0x1a9c; i <= 0x22fc/4; i += 32) { + INSTANCE_WR(ctx, i/4 , 0x10700ff9); + INSTANCE_WR(ctx, i/4 + 1, 0x0436086c); + INSTANCE_WR(ctx, i/4 + 2, 0x000c001b); + } - return 0; + INSTANCE_WR(ctx, 0x269c/4, 0x3f800000); + INSTANCE_WR(ctx, 0x26b0/4, 0x3f800000); + INSTANCE_WR(ctx, 0x26dc/4, 0x40000000); + INSTANCE_WR(ctx, 0x26e0/4, 0x3f800000); + INSTANCE_WR(ctx, 0x26e4/4, 0x3f000000); + INSTANCE_WR(ctx, 0x26ec/4, 0x40000000); + INSTANCE_WR(ctx, 0x26f0/4, 0x3f800000); + INSTANCE_WR(ctx, 0x26f8/4, 0xbf800000); + INSTANCE_WR(ctx, 0x2700/4, 0xbf800000); + INSTANCE_WR(ctx, 0x3024/4, 0x000fe000); + INSTANCE_WR(ctx, 0x30a0/4, 0x000003f8); + INSTANCE_WR(ctx, 0x33fc/4, 0x002fe000); + for(i = 0x341c; i< 0x343c; i += 4) + INSTANCE_WR(ctx, i/4, 0x001c527c); } -static void nv20_graph_rdi(drm_device_t *dev) { - drm_nouveau_private_t *dev_priv = - (drm_nouveau_private_t *)dev->dev_private; +static void nv25_graph_context_init(struct drm_device *dev, + struct nouveau_gpuobj *ctx) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; int i; +/* +write32 #1 block at +0x00740a7c NV_PRAMIN.GRCTX0+0x35c of 173 (0xad) elements: ++0x00740a7c: ffff0000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740a9c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740abc: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740adc: 00000000 0fff0000 0fff0000 00000000 00000000 00000000 00000000 00000000 ++0x00740afc: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740b1c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740b3c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740b5c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 + ++0x00740b7c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740b9c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740bbc: 00000101 00000000 00000000 00000000 00000000 00000111 00000000 00000000 ++0x00740bdc: 00000000 00000000 00000000 00000080 ffff0000 00000001 00000000 00000000 ++0x00740bfc: 00000000 00000000 44400000 00000000 00000000 00000000 00000000 00000000 ++0x00740c1c: 4b800000 00000000 00000000 00000000 00000000 00030303 00030303 00030303 ++0x00740c3c: 00030303 00000000 00000000 00000000 00000000 00080000 00080000 00080000 ++0x00740c5c: 00080000 00000000 00000000 01012000 01012000 01012000 01012000 000105b8 + ++0x00740c7c: 000105b8 000105b8 000105b8 00080008 00080008 00080008 00080008 00000000 ++0x00740c9c: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 07ff0000 ++0x00740cbc: 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 ++0x00740cdc: 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 07ff0000 00000000 ++0x00740cfc: 00000000 4b7fffff 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740d1c: 00000000 00000000 00000000 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x35c/4)+0, 0xffff0000); + INSTANCE_WR(ctx, (0x35c/4)+25, 0x0fff0000); + INSTANCE_WR(ctx, (0x35c/4)+26, 0x0fff0000); + INSTANCE_WR(ctx, (0x35c/4)+80, 0x00000101); + INSTANCE_WR(ctx, (0x35c/4)+85, 0x00000111); + INSTANCE_WR(ctx, (0x35c/4)+91, 0x00000080); + INSTANCE_WR(ctx, (0x35c/4)+92, 0xffff0000); + INSTANCE_WR(ctx, (0x35c/4)+93, 0x00000001); + INSTANCE_WR(ctx, (0x35c/4)+98, 0x44400000); + INSTANCE_WR(ctx, (0x35c/4)+104, 0x4b800000); + INSTANCE_WR(ctx, (0x35c/4)+109, 0x00030303); + INSTANCE_WR(ctx, (0x35c/4)+110, 0x00030303); + INSTANCE_WR(ctx, (0x35c/4)+111, 0x00030303); + INSTANCE_WR(ctx, (0x35c/4)+112, 0x00030303); + INSTANCE_WR(ctx, (0x35c/4)+117, 0x00080000); + INSTANCE_WR(ctx, (0x35c/4)+118, 0x00080000); + INSTANCE_WR(ctx, (0x35c/4)+119, 0x00080000); + INSTANCE_WR(ctx, (0x35c/4)+120, 0x00080000); + INSTANCE_WR(ctx, (0x35c/4)+123, 0x01012000); + INSTANCE_WR(ctx, (0x35c/4)+124, 0x01012000); + INSTANCE_WR(ctx, (0x35c/4)+125, 0x01012000); + INSTANCE_WR(ctx, (0x35c/4)+126, 0x01012000); + INSTANCE_WR(ctx, (0x35c/4)+127, 0x000105b8); + INSTANCE_WR(ctx, (0x35c/4)+128, 0x000105b8); + INSTANCE_WR(ctx, (0x35c/4)+129, 0x000105b8); + INSTANCE_WR(ctx, (0x35c/4)+130, 0x000105b8); + INSTANCE_WR(ctx, (0x35c/4)+131, 0x00080008); + INSTANCE_WR(ctx, (0x35c/4)+132, 0x00080008); + INSTANCE_WR(ctx, (0x35c/4)+133, 0x00080008); + INSTANCE_WR(ctx, (0x35c/4)+134, 0x00080008); + for (i=0; i<16; ++i) + INSTANCE_WR(ctx, (0x35c/4)+143+i, 0x07ff0000); + INSTANCE_WR(ctx, (0x35c/4)+161, 0x4b7fffff); + +/* +write32 #1 block at +0x00740d34 NV_PRAMIN.GRCTX0+0x614 of 3136 (0xc40) elements: ++0x00740d34: 00000000 00000000 00000000 00000080 30201000 70605040 b0a09080 f0e0d0c0 ++0x00740d54: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00740d74: 00000000 00000000 00000000 00000000 00000001 00000000 00004000 00000000 ++0x00740d94: 00000000 00000001 00000000 00040000 00010000 00000000 00000000 00000000 ++0x00740db4: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +... ++0x00742214: 00000000 00000000 00000000 00000000 10700ff9 0436086c 000c001b 00000000 ++0x00742234: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 ++0x00742254: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 ++0x00742274: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 +... ++0x00742a34: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 ++0x00742a54: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 ++0x00742a74: 10700ff9 0436086c 000c001b 00000000 10700ff9 0436086c 000c001b 00000000 ++0x00742a94: 10700ff9 0436086c 000c001b 00000000 00000000 00000000 00000000 00000000 ++0x00742ab4: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ++0x00742ad4: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x614/4)+3, 0x00000080); + INSTANCE_WR(ctx, (0x614/4)+4, 0x30201000); + INSTANCE_WR(ctx, (0x614/4)+5, 0x70605040); + INSTANCE_WR(ctx, (0x614/4)+6, 0xb0a09080); + INSTANCE_WR(ctx, (0x614/4)+7, 0xf0e0d0c0); + INSTANCE_WR(ctx, (0x614/4)+20, 0x00000001); + INSTANCE_WR(ctx, (0x614/4)+22, 0x00004000); + INSTANCE_WR(ctx, (0x614/4)+25, 0x00000001); + INSTANCE_WR(ctx, (0x614/4)+27, 0x00040000); + INSTANCE_WR(ctx, (0x614/4)+28, 0x00010000); + for (i=0; i < 0x880/4; i+=4) { + INSTANCE_WR(ctx, (0x1b04/4)+i+0, 0x10700ff9); + INSTANCE_WR(ctx, (0x1b04/4)+i+1, 0x0436086c); + INSTANCE_WR(ctx, (0x1b04/4)+i+2, 0x000c001b); + } - NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x2c80000); - for (i = 0; i < 32; i++) - NV_WRITE(NV10_PGRAPH_RDI_DATA, 0); - - nouveau_wait_for_idle(dev); +/* +write32 #1 block at +0x00742e24 NV_PRAMIN.GRCTX0+0x2704 of 4 (0x4) elements: ++0x00742e24: 3f800000 00000000 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x2704/4), 0x3f800000); + +/* +write32 #1 block at +0x00742e64 NV_PRAMIN.GRCTX0+0x2744 of 12 (0xc) elements: ++0x00742e64: 40000000 3f800000 3f000000 00000000 40000000 3f800000 00000000 bf800000 ++0x00742e84: 00000000 bf800000 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x2744/4)+0, 0x40000000); + INSTANCE_WR(ctx, (0x2744/4)+1, 0x3f800000); + INSTANCE_WR(ctx, (0x2744/4)+2, 0x3f000000); + INSTANCE_WR(ctx, (0x2744/4)+4, 0x40000000); + INSTANCE_WR(ctx, (0x2744/4)+5, 0x3f800000); + INSTANCE_WR(ctx, (0x2744/4)+7, 0xbf800000); + INSTANCE_WR(ctx, (0x2744/4)+9, 0xbf800000); + +/* +write32 #1 block at +0x00742e34 NV_PRAMIN.GRCTX0+0x2714 of 4 (0x4) elements: ++0x00742e34: 00000000 3f800000 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x2714/4)+1, 0x3f800000); + +/* +write32 #1 block at +0x00742e94 NV_PRAMIN.GRCTX0+0x2774 of 4 (0x4) elements: ++0x00742e94: 00000000 00000000 00000000 00000000 +write32 #1 block at +0x00743804 NV_PRAMIN.GRCTX0+0x30e4 of 4 (0x4) elements: ++0x00743804: 00000000 00000000 00000000 00000000 +write32 #1 block at +0x007437a4 NV_PRAMIN.GRCTX0+0x3084 of 8 (0x8) elements: ++0x007437a4: 00000000 00000000 000fe000 00000000 00000000 00000000 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x3084/4)+2, 0x000fe000); + +/* +write32 #1 block at +0x007437d4 NV_PRAMIN.GRCTX0+0x30b4 of 4 (0x4) elements: ++0x007437d4: 00000000 00000000 00000000 00000000 +write32 #1 block at +0x00743824 NV_PRAMIN.GRCTX0+0x3104 of 4 (0x4) elements: ++0x00743824: 00000000 000003f8 00000000 00000000 +*/ + INSTANCE_WR(ctx, (0x3104/4)+1, 0x000003f8); + +/* write32 #1 NV_PRAMIN.GRCTX0+0x3468 <- 0x002fe000 */ + INSTANCE_WR(ctx, 0x3468/4, 0x002fe000); + +/* +write32 #1 block at +0x00743ba4 NV_PRAMIN.GRCTX0+0x3484 of 8 (0x8) elements: ++0x00743ba4: 001c527c 001c527c 001c527c 001c527c 001c527c 001c527c 001c527c 001c527c +*/ + for (i=0; i<8; ++i) + INSTANCE_WR(ctx, (0x3484/4)+i, 0x001c527c); } -/* Save current context (from PGRAPH) into the channel's context - */ -static void nv20_graph_context_save_current(drm_device_t *dev, int channel) { - drm_nouveau_private_t *dev_priv = - (drm_nouveau_private_t *)dev->dev_private; - uint32_t instance; - - instance = INSTANCE_RD(dev_priv->ctx_table, channel); - if (!instance) { - return; +static void nv30_31_graph_context_init(struct drm_device *dev, + struct nouveau_gpuobj *ctx) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; + + INSTANCE_WR(ctx, 0x410/4, 0x00000101); + INSTANCE_WR(ctx, 0x424/4, 0x00000111); + INSTANCE_WR(ctx, 0x428/4, 0x00000060); + INSTANCE_WR(ctx, 0x444/4, 0x00000080); + INSTANCE_WR(ctx, 0x448/4, 0xffff0000); + INSTANCE_WR(ctx, 0x44c/4, 0x00000001); + INSTANCE_WR(ctx, 0x460/4, 0x44400000); + INSTANCE_WR(ctx, 0x48c/4, 0xffff0000); + for(i = 0x4e0; i< 0x4e8; i += 4) + INSTANCE_WR(ctx, i/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x4ec/4, 0x00011100); + for(i = 0x508; i< 0x548; i += 4) + INSTANCE_WR(ctx, i/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x550/4, 0x4b7fffff); + INSTANCE_WR(ctx, 0x58c/4, 0x00000080); + INSTANCE_WR(ctx, 0x590/4, 0x30201000); + INSTANCE_WR(ctx, 0x594/4, 0x70605040); + INSTANCE_WR(ctx, 0x598/4, 0xb8a89888); + INSTANCE_WR(ctx, 0x59c/4, 0xf8e8d8c8); + INSTANCE_WR(ctx, 0x5b0/4, 0xb0000000); + for(i = 0x600; i< 0x640; i += 4) + INSTANCE_WR(ctx, i/4, 0x00010588); + for(i = 0x640; i< 0x680; i += 4) + INSTANCE_WR(ctx, i/4, 0x00030303); + for(i = 0x6c0; i< 0x700; i += 4) + INSTANCE_WR(ctx, i/4, 0x0008aae4); + for(i = 0x700; i< 0x740; i += 4) + INSTANCE_WR(ctx, i/4, 0x01012000); + for(i = 0x740; i< 0x780; i += 4) + INSTANCE_WR(ctx, i/4, 0x00080008); + INSTANCE_WR(ctx, 0x85c/4, 0x00040000); + INSTANCE_WR(ctx, 0x860/4, 0x00010000); + for(i = 0x864; i< 0x874; i += 4) + INSTANCE_WR(ctx, i/4, 0x00040004); + for(i = 0x1f18; i<= 0x3088 ; i+= 16) { + INSTANCE_WR(ctx, i/4 + 0, 0x10700ff9); + INSTANCE_WR(ctx, i/4 + 1, 0x0436086c); + INSTANCE_WR(ctx, i/4 + 2, 0x000c001b); } - if (instance != nouveau_chip_instance_get(dev, dev_priv->fifos[channel].ramin_grctx)) - DRM_ERROR("nv20_graph_context_save_current : bad instance\n"); + for(i = 0x30b8; i< 0x30c8; i += 4) + INSTANCE_WR(ctx, i/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x344c/4, 0x3f800000); + INSTANCE_WR(ctx, 0x3808/4, 0x3f800000); + INSTANCE_WR(ctx, 0x381c/4, 0x3f800000); + INSTANCE_WR(ctx, 0x3848/4, 0x40000000); + INSTANCE_WR(ctx, 0x384c/4, 0x3f800000); + INSTANCE_WR(ctx, 0x3850/4, 0x3f000000); + INSTANCE_WR(ctx, 0x3858/4, 0x40000000); + INSTANCE_WR(ctx, 0x385c/4, 0x3f800000); + INSTANCE_WR(ctx, 0x3864/4, 0xbf800000); + INSTANCE_WR(ctx, 0x386c/4, 0xbf800000); +} - NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_SIZE, instance); - NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_POINTER, 2 /* save ctx */); +static void nv34_graph_context_init(struct drm_device *dev, + struct nouveau_gpuobj *ctx) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; + + INSTANCE_WR(ctx, 0x40c/4, 0x01000101); + INSTANCE_WR(ctx, 0x420/4, 0x00000111); + INSTANCE_WR(ctx, 0x424/4, 0x00000060); + INSTANCE_WR(ctx, 0x440/4, 0x00000080); + INSTANCE_WR(ctx, 0x444/4, 0xffff0000); + INSTANCE_WR(ctx, 0x448/4, 0x00000001); + INSTANCE_WR(ctx, 0x45c/4, 0x44400000); + INSTANCE_WR(ctx, 0x480/4, 0xffff0000); + for(i = 0x4d4; i< 0x4dc; i += 4) + INSTANCE_WR(ctx, i/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x4e0/4, 0x00011100); + for(i = 0x4fc; i< 0x53c; i += 4) + INSTANCE_WR(ctx, i/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x544/4, 0x4b7fffff); + INSTANCE_WR(ctx, 0x57c/4, 0x00000080); + INSTANCE_WR(ctx, 0x580/4, 0x30201000); + INSTANCE_WR(ctx, 0x584/4, 0x70605040); + INSTANCE_WR(ctx, 0x588/4, 0xb8a89888); + INSTANCE_WR(ctx, 0x58c/4, 0xf8e8d8c8); + INSTANCE_WR(ctx, 0x5a0/4, 0xb0000000); + for(i = 0x5f0; i< 0x630; i += 4) + INSTANCE_WR(ctx, i/4, 0x00010588); + for(i = 0x630; i< 0x670; i += 4) + INSTANCE_WR(ctx, i/4, 0x00030303); + for(i = 0x6b0; i< 0x6f0; i += 4) + INSTANCE_WR(ctx, i/4, 0x0008aae4); + for(i = 0x6f0; i< 0x730; i += 4) + INSTANCE_WR(ctx, i/4, 0x01012000); + for(i = 0x730; i< 0x770; i += 4) + INSTANCE_WR(ctx, i/4, 0x00080008); + INSTANCE_WR(ctx, 0x850/4, 0x00040000); + INSTANCE_WR(ctx, 0x854/4, 0x00010000); + for(i = 0x858; i< 0x868; i += 4) + INSTANCE_WR(ctx, i/4, 0x00040004); + for(i = 0x15ac; i<= 0x271c ; i+= 16) { + INSTANCE_WR(ctx, i/4 + 0, 0x10700ff9); + INSTANCE_WR(ctx, i/4 + 1, 0x0436086c); + INSTANCE_WR(ctx, i/4 + 2, 0x000c001b); + } + for(i = 0x274c; i< 0x275c; i += 4) + INSTANCE_WR(ctx, i/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x2ae0/4, 0x3f800000); + INSTANCE_WR(ctx, 0x2e9c/4, 0x3f800000); + INSTANCE_WR(ctx, 0x2eb0/4, 0x3f800000); + INSTANCE_WR(ctx, 0x2edc/4, 0x40000000); + INSTANCE_WR(ctx, 0x2ee0/4, 0x3f800000); + INSTANCE_WR(ctx, 0x2ee4/4, 0x3f000000); + INSTANCE_WR(ctx, 0x2eec/4, 0x40000000); + INSTANCE_WR(ctx, 0x2ef0/4, 0x3f800000); + INSTANCE_WR(ctx, 0x2ef8/4, 0xbf800000); + INSTANCE_WR(ctx, 0x2f00/4, 0xbf800000); } +static void nv35_36_graph_context_init(struct drm_device *dev, + struct nouveau_gpuobj *ctx) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; -/* Restore the context for a specific channel into PGRAPH - */ -static void nv20_graph_context_restore(drm_device_t *dev, int channel) { - drm_nouveau_private_t *dev_priv = - (drm_nouveau_private_t *)dev->dev_private; - uint32_t instance; - - instance = INSTANCE_RD(dev_priv->ctx_table, channel); - if (!instance) { - return; + INSTANCE_WR(ctx, 0x40c/4, 0x00000101); + INSTANCE_WR(ctx, 0x420/4, 0x00000111); + INSTANCE_WR(ctx, 0x424/4, 0x00000060); + INSTANCE_WR(ctx, 0x440/4, 0x00000080); + INSTANCE_WR(ctx, 0x444/4, 0xffff0000); + INSTANCE_WR(ctx, 0x448/4, 0x00000001); + INSTANCE_WR(ctx, 0x45c/4, 0x44400000); + INSTANCE_WR(ctx, 0x488/4, 0xffff0000); + for(i = 0x4dc; i< 0x4e4; i += 4) + INSTANCE_WR(ctx, i/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x4e8/4, 0x00011100); + for(i = 0x504; i< 0x544; i += 4) + INSTANCE_WR(ctx, i/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x54c/4, 0x4b7fffff); + INSTANCE_WR(ctx, 0x588/4, 0x00000080); + INSTANCE_WR(ctx, 0x58c/4, 0x30201000); + INSTANCE_WR(ctx, 0x590/4, 0x70605040); + INSTANCE_WR(ctx, 0x594/4, 0xb8a89888); + INSTANCE_WR(ctx, 0x598/4, 0xf8e8d8c8); + INSTANCE_WR(ctx, 0x5ac/4, 0xb0000000); + for(i = 0x604; i< 0x644; i += 4) + INSTANCE_WR(ctx, i/4, 0x00010588); + for(i = 0x644; i< 0x684; i += 4) + INSTANCE_WR(ctx, i/4, 0x00030303); + for(i = 0x6c4; i< 0x704; i += 4) + INSTANCE_WR(ctx, i/4, 0x0008aae4); + for(i = 0x704; i< 0x744; i += 4) + INSTANCE_WR(ctx, i/4, 0x01012000); + for(i = 0x744; i< 0x784; i += 4) + INSTANCE_WR(ctx, i/4, 0x00080008); + INSTANCE_WR(ctx, 0x860/4, 0x00040000); + INSTANCE_WR(ctx, 0x864/4, 0x00010000); + for(i = 0x868; i< 0x878; i += 4) + INSTANCE_WR(ctx, i/4, 0x00040004); + for(i = 0x1f1c; i<= 0x308c ; i+= 16) { + INSTANCE_WR(ctx, i/4 + 0, 0x10700ff9); + INSTANCE_WR(ctx, i/4 + 1, 0x0436086c); + INSTANCE_WR(ctx, i/4 + 2, 0x000c001b); } - if (instance != nouveau_chip_instance_get(dev, dev_priv->fifos[channel].ramin_grctx)) - DRM_ERROR("nv20_graph_context_restore_current : bad instance\n"); + for(i = 0x30bc; i< 0x30cc; i += 4) + INSTANCE_WR(ctx, i/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x3450/4, 0x3f800000); + INSTANCE_WR(ctx, 0x380c/4, 0x3f800000); + INSTANCE_WR(ctx, 0x3820/4, 0x3f800000); + INSTANCE_WR(ctx, 0x384c/4, 0x40000000); + INSTANCE_WR(ctx, 0x3850/4, 0x3f800000); + INSTANCE_WR(ctx, 0x3854/4, 0x3f000000); + INSTANCE_WR(ctx, 0x385c/4, 0x40000000); + INSTANCE_WR(ctx, 0x3860/4, 0x3f800000); + INSTANCE_WR(ctx, 0x3868/4, 0xbf800000); + INSTANCE_WR(ctx, 0x3870/4, 0xbf800000); +} + +int nv20_graph_create_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); + unsigned int ctx_size; + unsigned int idoffs = 0x28/4; + int ret; + + switch (dev_priv->chipset) { + case 0x20: + ctx_size = NV20_GRCTX_SIZE; + ctx_init = nv20_graph_context_init; + idoffs = 0; + break; + case 0x25: + case 0x28: + ctx_size = NV25_GRCTX_SIZE; + ctx_init = nv25_graph_context_init; + break; + case 0x2a: + ctx_size = NV2A_GRCTX_SIZE; + ctx_init = nv2a_graph_context_init; + idoffs = 0; + break; + case 0x30: + case 0x31: + ctx_size = NV30_31_GRCTX_SIZE; + ctx_init = nv30_31_graph_context_init; + break; + case 0x34: + ctx_size = NV34_GRCTX_SIZE; + ctx_init = nv34_graph_context_init; + break; + case 0x35: + case 0x36: + ctx_size = NV35_36_GRCTX_SIZE; + ctx_init = nv35_36_graph_context_init; + break; + default: + ctx_size = 0; + ctx_init = nv35_36_graph_context_init; + DRM_ERROR("Please contact the devs if you want your NV%x" + " card to work\n", dev_priv->chipset); + return -ENOSYS; + break; + } + + if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16, + NVOBJ_FLAG_ZERO_ALLOC, + &chan->ramin_grctx))) + return ret; + + /* Initialise default context values */ + ctx_init(dev, chan->ramin_grctx->gpuobj); + + /* nv20: INSTANCE_WR(chan->ramin_grctx->gpuobj, 10, chan->id<<24); */ + INSTANCE_WR(chan->ramin_grctx->gpuobj, idoffs, (chan->id<<24)|0x1); + /* CTX_USER */ + + INSTANCE_WR(dev_priv->ctx_table->gpuobj, chan->id, + chan->ramin_grctx->instance >> 4); - NV_WRITE(NV10_PGRAPH_CTX_USER, channel << 24); - NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_SIZE, instance); - NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_POINTER, 1 /* restore ctx */); + return 0; } -void nouveau_nv20_context_switch(drm_device_t *dev) +void nv20_graph_destroy_context(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - int channel, channel_old; + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (chan->ramin_grctx) + nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); + + INSTANCE_WR(dev_priv->ctx_table->gpuobj, chan->id, 0); +} - channel=NV_READ(NV03_PFIFO_CACHE1_PUSH1)&(nouveau_fifo_number(dev)-1); - channel_old = (NV_READ(NV10_PGRAPH_CTX_USER) >> 24) & (nouveau_fifo_number(dev)-1); +int nv20_graph_load_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t inst; - DRM_DEBUG("NV: PGRAPH context switch interrupt channel %x -> %x\n",channel_old, channel); + if (!chan->ramin_grctx) + return -EINVAL; + inst = chan->ramin_grctx->instance >> 4; - NV_WRITE(NV04_PGRAPH_FIFO,0x0); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_XFER, + NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD); - nv20_graph_context_save_current(dev, channel_old); - nouveau_wait_for_idle(dev); + return 0; +} - NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10000000); +int nv20_graph_save_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t inst; + + if (!chan->ramin_grctx) + return -EINVAL; + inst = chan->ramin_grctx->instance >> 4; - nv20_graph_context_restore(dev, channel); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_XFER, + NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE); nouveau_wait_for_idle(dev); - - if ((NV_READ(NV10_PGRAPH_CTX_USER) >> 24) != channel) - DRM_ERROR("nouveau_nv20_context_switch : wrong channel restored %x %x!!!\n", channel, NV_READ(NV10_PGRAPH_CTX_USER) >> 24); + return 0; +} - NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100); - NV_WRITE(NV10_PGRAPH_FFINTFC_ST2, NV_READ(NV10_PGRAPH_FFINTFC_ST2)&0xCFFFFFFF); +static void nv20_graph_rdi(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; - NV_WRITE(NV04_PGRAPH_FIFO,0x1); + NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x2c80000); + for (i = 0; i < 32; i++) + NV_WRITE(NV10_PGRAPH_RDI_DATA, 0); + + nouveau_wait_for_idle(dev); } -int nv20_graph_init(drm_device_t *dev) { - drm_nouveau_private_t *dev_priv = - (drm_nouveau_private_t *)dev->dev_private; - int i; +int nv20_graph_init(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = + (struct drm_nouveau_private *)dev->dev_private; uint32_t tmp, vramsz; + int ret, i; NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); @@ -145,25 +689,24 @@ int nv20_graph_init(drm_device_t *dev) { /* Create Context Pointer Table */ dev_priv->ctx_table_size = 32 * 4; - dev_priv->ctx_table = nouveau_instmem_alloc(dev, dev_priv->ctx_table_size, 4); - if (!dev_priv->ctx_table) - return DRM_ERR(ENOMEM); + if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, + dev_priv->ctx_table_size, 16, + NVOBJ_FLAG_ZERO_ALLOC, + &dev_priv->ctx_table))) + return ret; - for (i=0; i< dev_priv->ctx_table_size; i+=4) - INSTANCE_WR(dev_priv->ctx_table, i/4, 0x00000000); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_TABLE, + dev_priv->ctx_table->instance >> 4); - NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_TABLE, nouveau_chip_instance_get(dev, dev_priv->ctx_table)); - - //XXX need to be done and save/restore for each fifo ??? nv20_graph_rdi(dev); - NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000); NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF); + NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000); NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x00118700); - NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xF20E0431); + NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xF20E0435); /* 0x4 = auto ctx switch */ NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x00000000); NV_WRITE(0x40009C , 0x00000040); @@ -228,7 +771,98 @@ int nv20_graph_init(drm_device_t *dev) { return 0; } -void nv20_graph_takedown(drm_device_t *dev) +void nv20_graph_takedown(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + nouveau_gpuobj_ref_del(dev, &dev_priv->ctx_table); +} + +int nv30_graph_init(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t vramsz, tmp; + int ret, i; + + NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & + ~NV_PMC_ENABLE_PGRAPH); + NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | + NV_PMC_ENABLE_PGRAPH); + + /* Create Context Pointer Table */ + dev_priv->ctx_table_size = 32 * 4; + if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, + dev_priv->ctx_table_size, 16, + NVOBJ_FLAG_ZERO_ALLOC, + &dev_priv->ctx_table))) + return ret; + + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_TABLE, + dev_priv->ctx_table->instance >> 4); + + NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF); + NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); + + NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); + NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000); + NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x401287c0); + NV_WRITE(0x400890, 0x01b463ff); + NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xf2de0475); + NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x00008000); + NV_WRITE(NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04bdff6); + NV_WRITE(0x400B80, 0x1003d888); + NV_WRITE(0x400098, 0x00000000); + NV_WRITE(0x40009C, 0x0005ad00); + NV_WRITE(0x400B88, 0x62ff00ff); // suspiciously like PGRAPH_DEBUG_2 + NV_WRITE(0x4000a0, 0x00000000); + NV_WRITE(0x4000a4, 0x00000008); + NV_WRITE(0x4008a8, 0xb784a400); + NV_WRITE(0x400ba0, 0x002f8685); + NV_WRITE(0x400ba4, 0x00231f3f); + NV_WRITE(0x4008a4, 0x40000020); + NV_WRITE(0x400B84, 0x0c000000); + NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x62ff0f7f); + NV_WRITE(0x4000c0, 0x00000016); + + /* copy tile info from PFB */ + for (i=0; i<NV10_PFB_TILE__SIZE; i++) { + NV_WRITE(NV10_PGRAPH_TILE(i), NV_READ(NV10_PFB_TILE(i))); + NV_WRITE(NV10_PGRAPH_TLIMIT(i), NV_READ(NV10_PFB_TLIMIT(i))); + NV_WRITE(NV10_PGRAPH_TSIZE(i), NV_READ(NV10_PFB_TSIZE(i))); + NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i))); + } + + NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100); + NV_WRITE(NV10_PGRAPH_STATE , 0xFFFFFFFF); + NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001); + + /* begin RAM config */ + vramsz = drm_get_resource_len(dev, 0) - 1; + NV_WRITE(0x4009A4, NV_READ(NV04_PFB_CFG0)); + NV_WRITE(0x4009A8, NV_READ(NV04_PFB_CFG1)); + NV_WRITE(0x400750, 0x00EA0000); + NV_WRITE(0x400754, NV_READ(NV04_PFB_CFG0)); + NV_WRITE(0x400750, 0x00EA0004); + NV_WRITE(0x400754, NV_READ(NV04_PFB_CFG1)); + NV_WRITE(0x400820, 0); + NV_WRITE(0x400824, 0); + NV_WRITE(0x400864, vramsz-1); + NV_WRITE(0x400868, vramsz-1); + + NV_WRITE(0x400B20, 0x00000000); + NV_WRITE(0x400B04, 0xFFFFFFFF); + + /* per-context state, doesn't belong here */ + tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00; + NV_WRITE(NV10_PGRAPH_SURFACE, tmp); + tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100; + NV_WRITE(NV10_PGRAPH_SURFACE, tmp); + + NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMIN, 0); + NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMIN, 0); + NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff); + NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff); + + return 0; } diff --git a/shared-core/nv30_graph.c b/shared-core/nv30_graph.c deleted file mode 100644 index f4faadd8..00000000 --- a/shared-core/nv30_graph.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Based on nv40_graph.c - * Someday this will all go away... - */ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -/* - * This is obviously not the correct size. - */ -#define NV30_GRCTX_SIZE (23840) - -/*TODO: deciper what each offset in the context represents. The below - * contexts are taken from dumps just after the 3D object is - * created. - */ -static void nv30_graph_context_init(drm_device_t *dev, struct mem_block *ctx) -{ - drm_nouveau_private_t *dev_priv = dev->dev_private; - int i; - - INSTANCE_WR(ctx, 0x28/4, 0x10000000); - INSTANCE_WR(ctx, 0x40c/4, 0x00000101); - INSTANCE_WR(ctx, 0x420/4, 0x00000111); - INSTANCE_WR(ctx, 0x424/4, 0x00000060); - INSTANCE_WR(ctx, 0x440/4, 0x00000080); - INSTANCE_WR(ctx, 0x444/4, 0xffff0000); - INSTANCE_WR(ctx, 0x448/4, 0x00000001); - INSTANCE_WR(ctx, 0x45c/4, 0x44400000); - INSTANCE_WR(ctx, 0x448/4, 0xffff0000); - INSTANCE_WR(ctx, 0x4dc/4, 0xfff00000); - INSTANCE_WR(ctx, 0x4e0/4, 0xfff00000); - INSTANCE_WR(ctx, 0x4e8/4, 0x00011100); - - for (i = 0x504; i <= 0x540; i += 4) - INSTANCE_WR(ctx, i/4, 0x7ff00000); - - INSTANCE_WR(ctx, 0x54c/4, 0x4b7fffff); - INSTANCE_WR(ctx, 0x588/4, 0x00000080); - INSTANCE_WR(ctx, 0x58c/4, 0x30201000); - INSTANCE_WR(ctx, 0x590/4, 0x70605040); - INSTANCE_WR(ctx, 0x594/4, 0xb8a89888); - INSTANCE_WR(ctx, 0x598/4, 0xf8e8d8c8); - INSTANCE_WR(ctx, 0x5ac/4, 0xb0000000); - - for (i = 0x604; i <= 0x640; i += 4) - INSTANCE_WR(ctx, i/4, 0x00010588); - - for (i = 0x644; i <= 0x680; i += 4) - INSTANCE_WR(ctx, i/4, 0x00030303); - - for (i = 0x6c4; i <= 0x700; i += 4) - INSTANCE_WR(ctx, i/4, 0x0008aae4); - - for (i = 0x704; i <= 0x740; i += 4) - INSTANCE_WR(ctx, i/4, 0x1012000); - - for (i = 0x744; i <= 0x780; i += 4) - INSTANCE_WR(ctx, i/4, 0x0080008); - - INSTANCE_WR(ctx, 0x860/4, 0x00040000); - INSTANCE_WR(ctx, 0x864/4, 0x00010000); - INSTANCE_WR(ctx, 0x868/4, 0x00040000); - INSTANCE_WR(ctx, 0x86c/4, 0x00040000); - INSTANCE_WR(ctx, 0x870/4, 0x00040000); - INSTANCE_WR(ctx, 0x874/4, 0x00040000); - - for (i = 0x00; i <= 0x1170; i += 0x10) - { - INSTANCE_WR(ctx, (0x1f24 + i)/4, 0x000c001b); - INSTANCE_WR(ctx, (0x1f20 + i)/4, 0x0436086c); - INSTANCE_WR(ctx, (0x1f1c + i)/4, 0x10700ff9); - } - - INSTANCE_WR(ctx, 0x30bc/4, 0x0000ffff); - INSTANCE_WR(ctx, 0x30c0/4, 0x0000ffff); - INSTANCE_WR(ctx, 0x30c4/4, 0x0000ffff); - INSTANCE_WR(ctx, 0x30c8/4, 0x0000ffff); - - INSTANCE_WR(ctx, 0x380c/4, 0x3f800000); - INSTANCE_WR(ctx, 0x3450/4, 0x3f800000); - INSTANCE_WR(ctx, 0x3820/4, 0x3f800000); - INSTANCE_WR(ctx, 0x3854/4, 0x3f800000); - INSTANCE_WR(ctx, 0x3850/4, 0x3f000000); - INSTANCE_WR(ctx, 0x384c/4, 0x40000000); - INSTANCE_WR(ctx, 0x3868/4, 0xbf800000); - INSTANCE_WR(ctx, 0x3860/4, 0x3f800000); - INSTANCE_WR(ctx, 0x386c/4, 0x40000000); - INSTANCE_WR(ctx, 0x3870/4, 0xbf800000); - - for (i = 0x4e0; i <= 0x4e1c; i += 4) - INSTANCE_WR(ctx, i/4, 0x001c527d); - INSTANCE_WR(ctx, 0x4e40, 0x001c527c); - - INSTANCE_WR(ctx, 0x5680/4, 0x000a0000); - INSTANCE_WR(ctx, 0x87c/4, 0x10000000); - INSTANCE_WR(ctx, 0x28/4, 0x10000011); -} - - -int nv30_graph_context_create(drm_device_t *dev, int channel) -{ - drm_nouveau_private_t *dev_priv = - (drm_nouveau_private_t *)dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - void (*ctx_init)(drm_device_t *, struct mem_block *); - unsigned int ctx_size; - int i; - - switch (dev_priv->chipset) { - default: - ctx_size = NV30_GRCTX_SIZE; - ctx_init = nv30_graph_context_init; - break; - } - - /* Alloc and clear RAMIN to store the context */ - chan->ramin_grctx = nouveau_instmem_alloc(dev, ctx_size, 4); - if (!chan->ramin_grctx) - return DRM_ERR(ENOMEM); - for (i=0; i<ctx_size; i+=4) - INSTANCE_WR(chan->ramin_grctx, i/4, 0x00000000); - - /* Initialise default context values */ - ctx_init(dev, chan->ramin_grctx); - - INSTANCE_WR(chan->ramin_grctx, 10, channel << 24); /* CTX_USER */ - INSTANCE_WR(dev_priv->ctx_table, channel, nouveau_chip_instance_get(dev, chan->ramin_grctx)); - - return 0; -} - -int nv30_graph_init(drm_device_t *dev) -{ - drm_nouveau_private_t *dev_priv = - (drm_nouveau_private_t *)dev->dev_private; - uint32_t vramsz, tmp; - int i; - - NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & - ~NV_PMC_ENABLE_PGRAPH); - NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | - NV_PMC_ENABLE_PGRAPH); - - /* Create Context Pointer Table */ - dev_priv->ctx_table_size = 32 * 4; - dev_priv->ctx_table = nouveau_instmem_alloc(dev, dev_priv->ctx_table_size, 4); - if (!dev_priv->ctx_table) - return DRM_ERR(ENOMEM); - - for (i=0; i< dev_priv->ctx_table_size; i+=4) - INSTANCE_WR(dev_priv->ctx_table, i/4, 0x00000000); - - NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_TABLE, nouveau_chip_instance_get(dev, dev_priv->ctx_table)); - - NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000); - NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF); - - NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); - NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000); - NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x401287c0); - NV_WRITE(0x400890, 0x00140000); - NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xf0de0475); - NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x10008000); - NV_WRITE(NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04b1f36); - NV_WRITE(0x400B80, 0x1003d888); - NV_WRITE(0x400B84, 0x0c000000); - NV_WRITE(0x400B88, 0x62ff0f7f); - NV_WRITE(0x400098, 0x000000c0); - NV_WRITE(0x40009C, 0x0005dc00); - NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x62ff0f7f); - NV_WRITE(0x4000a0, 0x00000000); - NV_WRITE(0x4000a4, 0x00000008); - - /* copy tile info from PFB */ - for (i=0; i<NV10_PFB_TILE__SIZE; i++) { - NV_WRITE(NV10_PGRAPH_TILE(i), NV_READ(NV10_PFB_TILE(i))); - NV_WRITE(NV10_PGRAPH_TLIMIT(i), NV_READ(NV10_PFB_TLIMIT(i))); - NV_WRITE(NV10_PGRAPH_TSIZE(i), NV_READ(NV10_PFB_TSIZE(i))); - NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i))); - } - - NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100); - NV_WRITE(NV10_PGRAPH_STATE , 0xFFFFFFFF); - NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001); - - /* begin RAM config */ - vramsz = drm_get_resource_len(dev, 0) - 1; - NV_WRITE(0x4009A4, NV_READ(NV04_PFB_CFG0)); - NV_WRITE(0x4009A8, NV_READ(NV04_PFB_CFG1)); - NV_WRITE(0x400750, 0x00EA0000); - NV_WRITE(0x400754, NV_READ(NV04_PFB_CFG0)); - NV_WRITE(0x400750, 0x00EA0004); - NV_WRITE(0x400754, NV_READ(NV04_PFB_CFG1)); - NV_WRITE(0x400820, 0); - NV_WRITE(0x400824, 0); - NV_WRITE(0x400864, vramsz-1); - NV_WRITE(0x400868, vramsz-1); - - NV_WRITE(0x400B20, 0x00000000); - NV_WRITE(0x400B04, 0xFFFFFFFF); - - /* per-context state, doesn't belong here */ - tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00; - NV_WRITE(NV10_PGRAPH_SURFACE, tmp); - tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100; - NV_WRITE(NV10_PGRAPH_SURFACE, tmp); - - NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMIN, 0); - NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMIN, 0); - NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff); - NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff); - - return 0; -} - -void nv30_graph_takedown(drm_device_t *dev) -{ -} - diff --git a/shared-core/nv40_fb.c b/shared-core/nv40_fb.c index 83a7580e..2cbb40e4 100644 --- a/shared-core/nv40_fb.c +++ b/shared-core/nv40_fb.c @@ -4,9 +4,9 @@ #include "nouveau_drm.h" int -nv40_fb_init(drm_device_t *dev) +nv40_fb_init(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t fb_bar_size, tmp; int num_tiles; int i; @@ -50,7 +50,7 @@ nv40_fb_init(drm_device_t *dev) } void -nv40_fb_takedown(drm_device_t *dev) +nv40_fb_takedown(struct drm_device *dev) { } diff --git a/shared-core/nv40_fifo.c b/shared-core/nv40_fifo.c new file mode 100644 index 00000000..ce3f8fdd --- /dev/null +++ b/shared-core/nv40_fifo.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + + +#define RAMFC_WR(offset,val) INSTANCE_WR(chan->ramfc->gpuobj, \ + NV40_RAMFC_##offset/4, (val)) +#define RAMFC_RD(offset) INSTANCE_RD(chan->ramfc->gpuobj, \ + NV40_RAMFC_##offset/4) +#define NV40_RAMFC(c) (dev_priv->ramfc_offset + ((c)*NV40_RAMFC__SIZE)) +#define NV40_RAMFC__SIZE 128 + +int +nv40_fifo_create_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + if ((ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0, + NV40_RAMFC__SIZE, + NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ZERO_FREE, + NULL, &chan->ramfc))) + return ret; + + /* Fill entries that are seen filled in dumps of nvidia driver just + * after channel's is put into DMA mode + */ + RAMFC_WR(DMA_PUT , chan->pushbuf_base); + RAMFC_WR(DMA_GET , chan->pushbuf_base); + RAMFC_WR(DMA_INSTANCE , chan->pushbuf->instance >> 4); + RAMFC_WR(DMA_FETCH , NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | + NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | +#ifdef __BIG_ENDIAN + NV_PFIFO_CACHE1_BIG_ENDIAN | +#endif + 0x30000000 /* no idea.. */); + RAMFC_WR(DMA_SUBROUTINE, 0); + RAMFC_WR(GRCTX_INSTANCE, chan->ramin_grctx->instance >> 4); + RAMFC_WR(DMA_TIMESLICE , 0x0001FFFF); + + /* enable the fifo dma operation */ + NV_WRITE(NV04_PFIFO_MODE,NV_READ(NV04_PFIFO_MODE)|(1<<chan->id)); + return 0; +} + +void +nv40_fifo_destroy_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + + NV_WRITE(NV04_PFIFO_MODE, NV_READ(NV04_PFIFO_MODE)&~(1<<chan->id)); + + if (chan->ramfc) + nouveau_gpuobj_ref_del(dev, &chan->ramfc); +} + +int +nv40_fifo_load_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t tmp, tmp2; + + NV_WRITE(NV04_PFIFO_CACHE1_DMA_GET , RAMFC_RD(DMA_GET)); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUT , RAMFC_RD(DMA_PUT)); + NV_WRITE(NV10_PFIFO_CACHE1_REF_CNT , RAMFC_RD(REF_CNT)); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_INSTANCE , RAMFC_RD(DMA_INSTANCE)); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_DCOUNT , RAMFC_RD(DMA_DCOUNT)); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_STATE , RAMFC_RD(DMA_STATE)); + + /* No idea what 0x2058 is.. */ + tmp = RAMFC_RD(DMA_FETCH); + tmp2 = NV_READ(0x2058) & 0xFFF; + tmp2 |= (tmp & 0x30000000); + NV_WRITE(0x2058, tmp2); + tmp &= ~0x30000000; + NV_WRITE(NV04_PFIFO_CACHE1_DMA_FETCH , tmp); + + NV_WRITE(NV04_PFIFO_CACHE1_ENGINE , RAMFC_RD(ENGINE)); + NV_WRITE(NV04_PFIFO_CACHE1_PULL1 , RAMFC_RD(PULL1_ENGINE)); + NV_WRITE(NV10_PFIFO_CACHE1_ACQUIRE_VALUE , RAMFC_RD(ACQUIRE_VALUE)); + NV_WRITE(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, RAMFC_RD(ACQUIRE_TIMESTAMP)); + NV_WRITE(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT , RAMFC_RD(ACQUIRE_TIMEOUT)); + NV_WRITE(NV10_PFIFO_CACHE1_SEMAPHORE , RAMFC_RD(SEMAPHORE)); + NV_WRITE(NV10_PFIFO_CACHE1_DMA_SUBROUTINE , RAMFC_RD(DMA_SUBROUTINE)); + NV_WRITE(NV40_PFIFO_GRCTX_INSTANCE , RAMFC_RD(GRCTX_INSTANCE)); + NV_WRITE(0x32e4, RAMFC_RD(UNK_40)); + /* NVIDIA does this next line twice... */ + NV_WRITE(0x32e8, RAMFC_RD(UNK_44)); + NV_WRITE(0x2088, RAMFC_RD(UNK_4C)); + NV_WRITE(0x3300, RAMFC_RD(UNK_50)); + + /* not sure what part is PUT, and which is GET.. never seen a non-zero + * value appear in a mmio-trace yet.. + */ +#if 0 + tmp = NV_READ(UNK_84); + NV_WRITE(NV_PFIFO_CACHE1_GET, tmp ???); + NV_WRITE(NV_PFIFO_CACHE1_PUT, tmp ???); +#endif + + /* Don't clobber the TIMEOUT_ENABLED flag when restoring from RAMFC */ + tmp = NV_READ(NV04_PFIFO_DMA_TIMESLICE) & ~0x1FFFF; + tmp |= RAMFC_RD(DMA_TIMESLICE) & 0x1FFFF; + NV_WRITE(NV04_PFIFO_DMA_TIMESLICE, tmp); + + /* Set channel active, and in DMA mode */ + NV_WRITE(NV03_PFIFO_CACHE1_PUSH1 , 0x00010000 | chan->id); + /* Reset DMA_CTL_AT_INFO to INVALID */ + tmp = NV_READ(NV04_PFIFO_CACHE1_DMA_CTL) & ~(1<<31); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_CTL, tmp); + + return 0; +} + +int +nv40_fifo_save_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t tmp; + + RAMFC_WR(DMA_PUT , NV_READ(NV04_PFIFO_CACHE1_DMA_PUT)); + RAMFC_WR(DMA_GET , NV_READ(NV04_PFIFO_CACHE1_DMA_GET)); + RAMFC_WR(REF_CNT , NV_READ(NV10_PFIFO_CACHE1_REF_CNT)); + RAMFC_WR(DMA_INSTANCE , NV_READ(NV04_PFIFO_CACHE1_DMA_INSTANCE)); + RAMFC_WR(DMA_DCOUNT , NV_READ(NV04_PFIFO_CACHE1_DMA_DCOUNT)); + RAMFC_WR(DMA_STATE , NV_READ(NV04_PFIFO_CACHE1_DMA_STATE)); + + tmp = NV_READ(NV04_PFIFO_CACHE1_DMA_FETCH); + tmp |= NV_READ(0x2058) & 0x30000000; + RAMFC_WR(DMA_FETCH , tmp); + + RAMFC_WR(ENGINE , NV_READ(NV04_PFIFO_CACHE1_ENGINE)); + RAMFC_WR(PULL1_ENGINE , NV_READ(NV04_PFIFO_CACHE1_PULL1)); + RAMFC_WR(ACQUIRE_VALUE , NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); + tmp = NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP); + RAMFC_WR(ACQUIRE_TIMESTAMP, tmp); + RAMFC_WR(ACQUIRE_TIMEOUT , NV_READ(NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); + RAMFC_WR(SEMAPHORE , NV_READ(NV10_PFIFO_CACHE1_SEMAPHORE)); + + /* NVIDIA read 0x3228 first, then write DMA_GET here.. maybe something + * more involved depending on the value of 0x3228? + */ + RAMFC_WR(DMA_SUBROUTINE , NV_READ(NV04_PFIFO_CACHE1_DMA_GET)); + + RAMFC_WR(GRCTX_INSTANCE , NV_READ(NV40_PFIFO_GRCTX_INSTANCE)); + + /* No idea what the below is for exactly, ripped from a mmio-trace */ + RAMFC_WR(UNK_40 , NV_READ(NV40_PFIFO_UNK32E4)); + + /* NVIDIA do this next line twice.. bug? */ + RAMFC_WR(UNK_44 , NV_READ(0x32e8)); + RAMFC_WR(UNK_4C , NV_READ(0x2088)); + RAMFC_WR(UNK_50 , NV_READ(0x3300)); + +#if 0 /* no real idea which is PUT/GET in UNK_48.. */ + tmp = NV_READ(NV04_PFIFO_CACHE1_GET); + tmp |= (NV_READ(NV04_PFIFO_CACHE1_PUT) << 16); + RAMFC_WR(UNK_48 , tmp); +#endif + + return 0; +} + +int +nv40_fifo_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + if ((ret = nouveau_fifo_init(dev))) + return ret; + + NV_WRITE(NV04_PFIFO_DMA_TIMESLICE, 0x2101ffff); + return 0; +} + diff --git a/shared-core/nv40_graph.c b/shared-core/nv40_graph.c index 792734ed..7ce4273d 100644 --- a/shared-core/nv40_graph.c +++ b/shared-core/nv40_graph.c @@ -1,7 +1,32 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" /* The sizes are taken from the difference between the start of two * grctx addresses while running the nvidia driver. Probably slightly @@ -9,9 +34,13 @@ * between the contexts */ #define NV40_GRCTX_SIZE (175*1024) +#define NV41_GRCTX_SIZE (92*1024) #define NV43_GRCTX_SIZE (70*1024) #define NV46_GRCTX_SIZE (70*1024) /* probably ~64KiB */ +#define NV47_GRCTX_SIZE (125*1024) +#define NV49_GRCTX_SIZE (164640) #define NV4A_GRCTX_SIZE (64*1024) +#define NV4B_GRCTX_SIZE (164640) #define NV4C_GRCTX_SIZE (25*1024) #define NV4E_GRCTX_SIZE (25*1024) @@ -19,13 +48,14 @@ * contexts are taken from dumps just after the 3D object is * created. */ -static void nv40_graph_context_init(drm_device_t *dev, struct mem_block *ctx) +static void +nv40_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; int i; /* Always has the "instance address" of itself at offset 0 */ - INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx)); + INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); /* unknown */ INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff); INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff); @@ -160,12 +190,122 @@ static void nv40_graph_context_init(drm_device_t *dev, struct mem_block *ctx) } static void -nv43_graph_context_init(drm_device_t *dev, struct mem_block *ctx) +nv41_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; + + INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); + INSTANCE_WR(ctx, 0x00000024/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x00000028/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x00000030/4, 0x00000001); + INSTANCE_WR(ctx, 0x0000011c/4, 0x20010001); + INSTANCE_WR(ctx, 0x00000120/4, 0x0f73ef00); + INSTANCE_WR(ctx, 0x00000128/4, 0x02008821); + for (i = 0x00000178; i <= 0x00000180; i += 4) + INSTANCE_WR(ctx, i/4, 0x00000040); + INSTANCE_WR(ctx, 0x00000188/4, 0x00000040); + for (i = 0x00000194; i <= 0x000001b0; i += 4) + INSTANCE_WR(ctx, i/4, 0x80000000); + INSTANCE_WR(ctx, 0x000001d0/4, 0x0b0b0b0c); + INSTANCE_WR(ctx, 0x00000340/4, 0x00040000); + for (i = 0x00000350; i <= 0x0000035c; i += 4) + INSTANCE_WR(ctx, i/4, 0x55555555); + INSTANCE_WR(ctx, 0x00000388/4, 0x00000008); + INSTANCE_WR(ctx, 0x0000039c/4, 0x00001010); + INSTANCE_WR(ctx, 0x000003cc/4, 0x00000111); + INSTANCE_WR(ctx, 0x000003d0/4, 0x00080060); + INSTANCE_WR(ctx, 0x000003ec/4, 0x00000080); + INSTANCE_WR(ctx, 0x000003f0/4, 0xffff0000); + INSTANCE_WR(ctx, 0x000003f4/4, 0x00000001); + INSTANCE_WR(ctx, 0x00000408/4, 0x46400000); + INSTANCE_WR(ctx, 0x00000418/4, 0xffff0000); + INSTANCE_WR(ctx, 0x00000424/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x00000428/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x00000430/4, 0x00011100); + for (i = 0x0000044c; i <= 0x00000488; i += 4) + INSTANCE_WR(ctx, i/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x00000494/4, 0x4b7fffff); + INSTANCE_WR(ctx, 0x000004bc/4, 0x30201000); + INSTANCE_WR(ctx, 0x000004c0/4, 0x70605040); + INSTANCE_WR(ctx, 0x000004c4/4, 0xb8a89888); + INSTANCE_WR(ctx, 0x000004c8/4, 0xf8e8d8c8); + INSTANCE_WR(ctx, 0x000004dc/4, 0x40100000); + INSTANCE_WR(ctx, 0x000004f8/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x0000052c/4, 0x435185d6); + INSTANCE_WR(ctx, 0x00000530/4, 0x2155b699); + INSTANCE_WR(ctx, 0x00000534/4, 0xfedcba98); + INSTANCE_WR(ctx, 0x00000538/4, 0x00000098); + INSTANCE_WR(ctx, 0x00000548/4, 0xffffffff); + INSTANCE_WR(ctx, 0x0000054c/4, 0x00ff7000); + INSTANCE_WR(ctx, 0x00000550/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x00000560/4, 0x00ff0000); + INSTANCE_WR(ctx, 0x00000598/4, 0x00ffff00); + for (i = 0x000005dc; i <= 0x00000618; i += 4) + INSTANCE_WR(ctx, i/4, 0x00018488); + for (i = 0x0000061c; i <= 0x00000658; i += 4) + INSTANCE_WR(ctx, i/4, 0x00028202); + for (i = 0x0000069c; i <= 0x000006d8; i += 4) + INSTANCE_WR(ctx, i/4, 0x0000aae4); + for (i = 0x000006dc; i <= 0x00000718; i += 4) + INSTANCE_WR(ctx, i/4, 0x01012000); + for (i = 0x0000071c; i <= 0x00000758; i += 4) + INSTANCE_WR(ctx, i/4, 0x00080008); + for (i = 0x0000079c; i <= 0x000007d8; i += 4) + INSTANCE_WR(ctx, i/4, 0x00100008); + for (i = 0x0000082c; i <= 0x00000838; i += 4) + INSTANCE_WR(ctx, i/4, 0x0001bc80); + for (i = 0x0000083c; i <= 0x00000848; i += 4) + INSTANCE_WR(ctx, i/4, 0x00000202); + for (i = 0x0000085c; i <= 0x00000868; i += 4) + INSTANCE_WR(ctx, i/4, 0x00000008); + for (i = 0x0000087c; i <= 0x00000888; i += 4) + INSTANCE_WR(ctx, i/4, 0x00080008); + INSTANCE_WR(ctx, 0x0000089c/4, 0x00000002); + INSTANCE_WR(ctx, 0x000008d0/4, 0x00000021); + INSTANCE_WR(ctx, 0x000008d4/4, 0x030c30c3); + INSTANCE_WR(ctx, 0x000008e0/4, 0x3e020200); + INSTANCE_WR(ctx, 0x000008e4/4, 0x00ffffff); + INSTANCE_WR(ctx, 0x000008e8/4, 0x20103f00); + INSTANCE_WR(ctx, 0x000008f4/4, 0x00020000); + INSTANCE_WR(ctx, 0x0000092c/4, 0x00008100); + INSTANCE_WR(ctx, 0x000009b8/4, 0x00000001); + INSTANCE_WR(ctx, 0x000009fc/4, 0x00001001); + INSTANCE_WR(ctx, 0x00000a04/4, 0x00000003); + INSTANCE_WR(ctx, 0x00000a08/4, 0x00888001); + INSTANCE_WR(ctx, 0x00000aac/4, 0x00000005); + INSTANCE_WR(ctx, 0x00000ab8/4, 0x0000ffff); + for (i = 0x00000ad4; i <= 0x00000ae4; i += 4) + INSTANCE_WR(ctx, i/4, 0x00005555); + INSTANCE_WR(ctx, 0x00000ae8/4, 0x00000001); + INSTANCE_WR(ctx, 0x00000b20/4, 0x00000001); + for (i = 0x00002ee8; i <= 0x00002f60; i += 8) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for (i = 0x00005168; i <= 0x00007358; i += 24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for (i = 0x00007368; i <= 0x00007758; i += 16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for (i = 0x0000a068; i <= 0x0000c258; i += 24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for (i = 0x0000c268; i <= 0x0000c658; i += 16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for (i = 0x0000ef68; i <= 0x00011158; i += 24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for (i = 0x00011168; i <= 0x00011558; i += 16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for (i = 0x00013e68; i <= 0x00016058; i += 24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for (i = 0x00016068; i <= 0x00016458; i += 16) + INSTANCE_WR(ctx, i/4, 0x3f800000); +}; + +static void +nv43_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; int i; - INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx)); + INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff); INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff); INSTANCE_WR(ctx, 0x00030/4, 0x00000001); @@ -275,12 +415,13 @@ nv43_graph_context_init(drm_device_t *dev, struct mem_block *ctx) INSTANCE_WR(ctx, i/4, 0x3f800000); }; -static void nv46_graph_context_init(drm_device_t *dev, struct mem_block *ctx) +static void +nv46_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; int i; - INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx)); + INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); INSTANCE_WR(ctx, 0x00040/4, 0x0000ffff); INSTANCE_WR(ctx, 0x00044/4, 0x0000ffff); INSTANCE_WR(ctx, 0x0004c/4, 0x00000001); @@ -425,12 +566,366 @@ static void nv46_graph_context_init(drm_device_t *dev, struct mem_block *ctx) INSTANCE_WR(ctx, i/4, 0x3f800000); } -static void nv4a_graph_context_init(drm_device_t *dev, struct mem_block *ctx) +/* This may only work on 7800 AGP cards, will include a warning */ +static void +nv47_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; int i; - INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx)); + INSTANCE_WR(ctx, 0x00000000/4, ctx->im_pramin->start); + INSTANCE_WR(ctx, 0x00000024/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x00000028/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x00000030/4, 0x00000001); + INSTANCE_WR(ctx, 0x0000011c/4, 0x20010001); + INSTANCE_WR(ctx, 0x00000120/4, 0x0f73ef00); + INSTANCE_WR(ctx, 0x00000128/4, 0x02008821); + INSTANCE_WR(ctx, 0x00000178/4, 0x00000040); + INSTANCE_WR(ctx, 0x0000017c/4, 0x00000040); + INSTANCE_WR(ctx, 0x00000180/4, 0x00000040); + INSTANCE_WR(ctx, 0x00000188/4, 0x00000040); + for (i=0x00000194; i<=0x000001b0; i+=4) + INSTANCE_WR(ctx, i/4, 0x80000000); + INSTANCE_WR(ctx, 0x000001d0/4, 0x0b0b0b0c); + INSTANCE_WR(ctx, 0x00000340/4, 0x00040000); + INSTANCE_WR(ctx, 0x00000350/4, 0x55555555); + INSTANCE_WR(ctx, 0x00000354/4, 0x55555555); + INSTANCE_WR(ctx, 0x00000358/4, 0x55555555); + INSTANCE_WR(ctx, 0x0000035c/4, 0x55555555); + INSTANCE_WR(ctx, 0x00000388/4, 0x00000008); + INSTANCE_WR(ctx, 0x0000039c/4, 0x00001010); + for (i=0x000003c0; i<=0x000003fc; i+=4) + INSTANCE_WR(ctx, i/4, 0x00000111); + INSTANCE_WR(ctx, 0x00000454/4, 0x00000111); + INSTANCE_WR(ctx, 0x00000458/4, 0x00080060); + INSTANCE_WR(ctx, 0x00000474/4, 0x00000080); + INSTANCE_WR(ctx, 0x00000478/4, 0xffff0000); + INSTANCE_WR(ctx, 0x0000047c/4, 0x00000001); + INSTANCE_WR(ctx, 0x00000490/4, 0x46400000); + INSTANCE_WR(ctx, 0x000004a0/4, 0xffff0000); + for (i=0x000004a4; i<=0x000004e0; i+=4) + INSTANCE_WR(ctx, i/4, 0x88888888); + INSTANCE_WR(ctx, 0x000004f4/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x000004f8/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x00000500/4, 0x00011100); + for (i=0x0000051c; i<=0x00000558; i+=4) + INSTANCE_WR(ctx, i/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x00000564/4, 0x4b7fffff); + INSTANCE_WR(ctx, 0x0000058c/4, 0x30201000); + INSTANCE_WR(ctx, 0x00000590/4, 0x70605040); + INSTANCE_WR(ctx, 0x00000594/4, 0xb8a89888); + INSTANCE_WR(ctx, 0x00000598/4, 0xf8e8d8c8); + INSTANCE_WR(ctx, 0x000005ac/4, 0x40100000); + INSTANCE_WR(ctx, 0x000005c8/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x000005fc/4, 0x435185d6); + INSTANCE_WR(ctx, 0x00000600/4, 0x2155b699); + INSTANCE_WR(ctx, 0x00000604/4, 0xfedcba98); + INSTANCE_WR(ctx, 0x00000608/4, 0x00000098); + INSTANCE_WR(ctx, 0x00000618/4, 0xffffffff); + INSTANCE_WR(ctx, 0x0000061c/4, 0x00ff7000); + INSTANCE_WR(ctx, 0x00000620/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x00000630/4, 0x00ff0000); + INSTANCE_WR(ctx, 0x0000066c/4, 0x00ffff00); + for (i=0x000006b0; i<=0x000006ec; i+=4) + INSTANCE_WR(ctx, i/4, 0x00018488); + for (i=0x000006f0; i<=0x0000072c; i+=4) + INSTANCE_WR(ctx, i/4, 0x00028202); + for (i=0x00000770; i<=0x000007ac; i+=4) + INSTANCE_WR(ctx, i/4, 0x0000aae4); + for (i=0x000007b0; i<=0x000007ec; i+=4) + INSTANCE_WR(ctx, i/4, 0x01012000); + for (i=0x000007f0; i<=0x0000082c; i+=4) + INSTANCE_WR(ctx, i/4, 0x00080008); + for (i=0x00000870; i<=0x000008ac; i+=4) + INSTANCE_WR(ctx, i/4, 0x00100008); + INSTANCE_WR(ctx, 0x00000900/4, 0x0001bc80); + INSTANCE_WR(ctx, 0x00000904/4, 0x0001bc80); + INSTANCE_WR(ctx, 0x00000908/4, 0x0001bc80); + INSTANCE_WR(ctx, 0x0000090c/4, 0x0001bc80); + INSTANCE_WR(ctx, 0x00000910/4, 0x00000202); + INSTANCE_WR(ctx, 0x00000914/4, 0x00000202); + INSTANCE_WR(ctx, 0x00000918/4, 0x00000202); + INSTANCE_WR(ctx, 0x0000091c/4, 0x00000202); + for (i=0x00000930; i<=0x0000095c; i+=4) + INSTANCE_WR(ctx, i/4, 0x00000008); + INSTANCE_WR(ctx, 0x00000970/4, 0x00000002); + INSTANCE_WR(ctx, 0x000009a4/4, 0x00000021); + INSTANCE_WR(ctx, 0x000009a8/4, 0x030c30c3); + INSTANCE_WR(ctx, 0x000009b4/4, 0x3e020200); + INSTANCE_WR(ctx, 0x000009b8/4, 0x00ffffff); + INSTANCE_WR(ctx, 0x000009bc/4, 0x40103f00); + INSTANCE_WR(ctx, 0x000009c8/4, 0x00040000); + INSTANCE_WR(ctx, 0x00000a00/4, 0x00008100); + INSTANCE_WR(ctx, 0x00000a8c/4, 0x00000001); + INSTANCE_WR(ctx, 0x00000ad0/4, 0x00001001); + INSTANCE_WR(ctx, 0x00000adc/4, 0x00000003); + INSTANCE_WR(ctx, 0x00000ae0/4, 0x00888001); + for (i=0x00000b10; i<=0x00000b8c; i+=4) + INSTANCE_WR(ctx, i/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00000bb4/4, 0x00000005); + INSTANCE_WR(ctx, 0x00000bc0/4, 0x0000ffff); + for (i=0x00000bdc; i<=0x00000bf8; i+=4) + INSTANCE_WR(ctx, i/4, 0x00005555); + INSTANCE_WR(ctx, 0x00000bfc/4, 0x00000001); + INSTANCE_WR(ctx, 0x00000c34/4, 0x00000001); + INSTANCE_WR(ctx, 0x00000c38/4, 0x08e00001); + INSTANCE_WR(ctx, 0x00000c3c/4, 0x000e3000); + for (i=0x00003000; i<=0x00003078; i+=8) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for (i=0x00004dc0; i<=0x00006fb0; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for (i=0x00006fc0; i<=0x000073b0; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for (i=0x00009800; i<=0x0000b9f0; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for (i=0x0000ba00; i<=0x00010430; i+=24) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for (i=0x00010440; i<=0x00010830; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for (i=0x00012c80; i<=0x00014e70; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for (i=0x00014e80; i<=0x00015270; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for (i=0x000176c0; i<=0x000198b0; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for (i=0x000198c0; i<=0x00019cb0; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for (i=0x0001c100; i<=0x0001e2f0; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for (i=0x0001e300; i<=0x0001e6f0; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); +} + +static void +nv49_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; + + INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); + INSTANCE_WR(ctx, 0x00004/4, 0x0000c040); + INSTANCE_WR(ctx, 0x00008/4, 0x0000c040); + INSTANCE_WR(ctx, 0x0000c/4, 0x0000c040); + INSTANCE_WR(ctx, 0x00010/4, 0x0000c040); + INSTANCE_WR(ctx, 0x00014/4, 0x0000c040); + INSTANCE_WR(ctx, 0x00018/4, 0x0000c040); + INSTANCE_WR(ctx, 0x0001c/4, 0x0000c040); + INSTANCE_WR(ctx, 0x00020/4, 0x0000c040); + INSTANCE_WR(ctx, 0x000c4/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x000c8/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x000d0/4, 0x00000001); + INSTANCE_WR(ctx, 0x001bc/4, 0x20010001); + INSTANCE_WR(ctx, 0x001c0/4, 0x0f73ef00); + INSTANCE_WR(ctx, 0x001c8/4, 0x02008821); + INSTANCE_WR(ctx, 0x00218/4, 0x00000040); + INSTANCE_WR(ctx, 0x0021c/4, 0x00000040); + INSTANCE_WR(ctx, 0x00220/4, 0x00000040); + INSTANCE_WR(ctx, 0x00228/4, 0x00000040); + INSTANCE_WR(ctx, 0x00234/4, 0x80000000); + INSTANCE_WR(ctx, 0x00238/4, 0x80000000); + INSTANCE_WR(ctx, 0x0023c/4, 0x80000000); + INSTANCE_WR(ctx, 0x00240/4, 0x80000000); + INSTANCE_WR(ctx, 0x00244/4, 0x80000000); + INSTANCE_WR(ctx, 0x00248/4, 0x80000000); + INSTANCE_WR(ctx, 0x0024c/4, 0x80000000); + INSTANCE_WR(ctx, 0x00250/4, 0x80000000); + INSTANCE_WR(ctx, 0x00270/4, 0x0b0b0b0c); + INSTANCE_WR(ctx, 0x003e0/4, 0x00040000); + INSTANCE_WR(ctx, 0x003f0/4, 0x55555555); + INSTANCE_WR(ctx, 0x003f4/4, 0x55555555); + INSTANCE_WR(ctx, 0x003f8/4, 0x55555555); + INSTANCE_WR(ctx, 0x003fc/4, 0x55555555); + INSTANCE_WR(ctx, 0x00428/4, 0x00000008); + INSTANCE_WR(ctx, 0x0043c/4, 0x00001010); + INSTANCE_WR(ctx, 0x00460/4, 0x00000111); + INSTANCE_WR(ctx, 0x00464/4, 0x00000111); + INSTANCE_WR(ctx, 0x00468/4, 0x00000111); + INSTANCE_WR(ctx, 0x0046c/4, 0x00000111); + INSTANCE_WR(ctx, 0x00470/4, 0x00000111); + INSTANCE_WR(ctx, 0x00474/4, 0x00000111); + INSTANCE_WR(ctx, 0x00478/4, 0x00000111); + INSTANCE_WR(ctx, 0x0047c/4, 0x00000111); + INSTANCE_WR(ctx, 0x00480/4, 0x00000111); + INSTANCE_WR(ctx, 0x00484/4, 0x00000111); + INSTANCE_WR(ctx, 0x00488/4, 0x00000111); + INSTANCE_WR(ctx, 0x0048c/4, 0x00000111); + INSTANCE_WR(ctx, 0x00490/4, 0x00000111); + INSTANCE_WR(ctx, 0x00494/4, 0x00000111); + INSTANCE_WR(ctx, 0x00498/4, 0x00000111); + INSTANCE_WR(ctx, 0x0049c/4, 0x00000111); + INSTANCE_WR(ctx, 0x004f4/4, 0x00000111); + INSTANCE_WR(ctx, 0x004f8/4, 0x00080060); + INSTANCE_WR(ctx, 0x00514/4, 0x00000080); + INSTANCE_WR(ctx, 0x00518/4, 0xffff0000); + INSTANCE_WR(ctx, 0x0051c/4, 0x00000001); + INSTANCE_WR(ctx, 0x00530/4, 0x46400000); + INSTANCE_WR(ctx, 0x00540/4, 0xffff0000); + INSTANCE_WR(ctx, 0x00544/4, 0x88888888); + INSTANCE_WR(ctx, 0x00548/4, 0x88888888); + INSTANCE_WR(ctx, 0x0054c/4, 0x88888888); + INSTANCE_WR(ctx, 0x00550/4, 0x88888888); + INSTANCE_WR(ctx, 0x00554/4, 0x88888888); + INSTANCE_WR(ctx, 0x00558/4, 0x88888888); + INSTANCE_WR(ctx, 0x0055c/4, 0x88888888); + INSTANCE_WR(ctx, 0x00560/4, 0x88888888); + INSTANCE_WR(ctx, 0x00564/4, 0x88888888); + INSTANCE_WR(ctx, 0x00568/4, 0x88888888); + INSTANCE_WR(ctx, 0x0056c/4, 0x88888888); + INSTANCE_WR(ctx, 0x00570/4, 0x88888888); + INSTANCE_WR(ctx, 0x00574/4, 0x88888888); + INSTANCE_WR(ctx, 0x00578/4, 0x88888888); + INSTANCE_WR(ctx, 0x0057c/4, 0x88888888); + INSTANCE_WR(ctx, 0x00580/4, 0x88888888); + INSTANCE_WR(ctx, 0x00594/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x00598/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x005a0/4, 0x00011100); + INSTANCE_WR(ctx, 0x005bc/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005c0/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005c4/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005c8/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005cc/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005d0/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005d4/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005d8/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005dc/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005e0/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005e4/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005e8/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005ec/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005f0/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005f4/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005f8/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x00604/4, 0x4b7fffff); + INSTANCE_WR(ctx, 0x0062c/4, 0x30201000); + INSTANCE_WR(ctx, 0x00630/4, 0x70605040); + INSTANCE_WR(ctx, 0x00634/4, 0xb8a89888); + INSTANCE_WR(ctx, 0x00638/4, 0xf8e8d8c8); + INSTANCE_WR(ctx, 0x0064c/4, 0x40100000); + INSTANCE_WR(ctx, 0x00668/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x0069c/4, 0x435185d6); + INSTANCE_WR(ctx, 0x006a0/4, 0x2155b699); + INSTANCE_WR(ctx, 0x006a4/4, 0xfedcba98); + INSTANCE_WR(ctx, 0x006a8/4, 0x00000098); + INSTANCE_WR(ctx, 0x006b8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x006bc/4, 0x00ff7000); + INSTANCE_WR(ctx, 0x006c0/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x006d0/4, 0x00ff0000); + INSTANCE_WR(ctx, 0x0070c/4, 0x00ffff00); + for (i=0x00750; i<=0x0078c; i+=4) + INSTANCE_WR(ctx, i/4, 0x00018488); + for (i=0x00790; i<=0x007cc; i+=4) + INSTANCE_WR(ctx, i/4, 0x00028202); + for (i=0x00810; i<=0x0084c; i+=4) + INSTANCE_WR(ctx, i/4, 0x0000aae4); + for (i=0x00850; i<=0x0088c; i+=4) + INSTANCE_WR(ctx, i/4, 0x01012000); + for (i=0x00890; i<=0x008cc; i+=4) + INSTANCE_WR(ctx, i/4, 0x00080008); + for (i=0x00910; i<=0x0094c; i+=4) + INSTANCE_WR(ctx, i/4, 0x00100008); + for (i=0x009a0; i<=0x009ac; i+=4) + INSTANCE_WR(ctx, i/4, 0x0001bc80); + for (i=0x009b0; i<=0x009bc; i+=4) + INSTANCE_WR(ctx, i/4, 0x00000202); + for (i=0x009d0; i<=0x009dc; i+=4) + INSTANCE_WR(ctx, i/4, 0x00000008); + for (i=0x009f0; i<=0x009fc; i+=4) + INSTANCE_WR(ctx, i/4, 0x00080008); + INSTANCE_WR(ctx, 0x00a10/4, 0x00000002); + INSTANCE_WR(ctx, 0x00a44/4, 0x00000421); + INSTANCE_WR(ctx, 0x00a48/4, 0x030c30c3); + INSTANCE_WR(ctx, 0x00a54/4, 0x3e020200); + INSTANCE_WR(ctx, 0x00a58/4, 0x00ffffff); + INSTANCE_WR(ctx, 0x00a5c/4, 0x20103f00); + INSTANCE_WR(ctx, 0x00a68/4, 0x00040000); + INSTANCE_WR(ctx, 0x00aa0/4, 0x00008100); + INSTANCE_WR(ctx, 0x00b2c/4, 0x00000001); + INSTANCE_WR(ctx, 0x00b70/4, 0x00001001); + INSTANCE_WR(ctx, 0x00b7c/4, 0x00000003); + INSTANCE_WR(ctx, 0x00b80/4, 0x00888001); + INSTANCE_WR(ctx, 0x00bb0/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bb4/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bb8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bbc/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bc0/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bc4/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bc8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bcc/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bd0/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bd4/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bd8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bdc/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00be0/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00be4/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00be8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bec/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bf0/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bf4/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bf8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bfc/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c00/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c04/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c08/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c0c/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c10/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c14/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c18/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c1c/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c20/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c24/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c28/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c2c/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c54/4, 0x00000005); + INSTANCE_WR(ctx, 0x00c60/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x00c7c/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c80/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c84/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c88/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c8c/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c90/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c94/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c98/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c9c/4, 0x00000001); + INSTANCE_WR(ctx, 0x00cd4/4, 0x00000001); + INSTANCE_WR(ctx, 0x00cd8/4, 0x08e00001); + INSTANCE_WR(ctx, 0x00cdc/4, 0x000e3000); + for(i=0x030a0; i<=0x03118; i+=8) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for(i=0x098a0; i<=0x0ba90; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x0baa0; i<=0x0be90; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for(i=0x0e2e0; i<=0x0fff0; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x10008; i<=0x104d0; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x104e0; i<=0x108d0; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for(i=0x12d20; i<=0x14f10; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x14f20; i<=0x15310; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for(i=0x17760; i<=0x19950; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x19960; i<=0x19d50; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for(i=0x1c1a0; i<=0x1e390; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x1e3a0; i<=0x1e790; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for(i=0x20be0; i<=0x22dd0; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x22de0; i<=0x231d0; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); +} + +static void +nv4a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; + + INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff); INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff); INSTANCE_WR(ctx, 0x00030/4, 0x00000001); @@ -541,13 +1036,228 @@ static void nv4a_graph_context_init(drm_device_t *dev, struct mem_block *ctx) INSTANCE_WR(ctx, i/4, 0x3f800000); } +static void +nv4b_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i; -static void nv4c_graph_context_init(drm_device_t *dev, struct mem_block *ctx) + INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); + INSTANCE_WR(ctx, 0x00004/4, 0x0000c040); + INSTANCE_WR(ctx, 0x00008/4, 0x0000c040); + INSTANCE_WR(ctx, 0x0000c/4, 0x0000c040); + INSTANCE_WR(ctx, 0x00010/4, 0x0000c040); + INSTANCE_WR(ctx, 0x00014/4, 0x0000c040); + INSTANCE_WR(ctx, 0x00018/4, 0x0000c040); + INSTANCE_WR(ctx, 0x0001c/4, 0x0000c040); + INSTANCE_WR(ctx, 0x00020/4, 0x0000c040); + INSTANCE_WR(ctx, 0x000c4/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x000c8/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x000d0/4, 0x00000001); + INSTANCE_WR(ctx, 0x001bc/4, 0x20010001); + INSTANCE_WR(ctx, 0x001c0/4, 0x0f73ef00); + INSTANCE_WR(ctx, 0x001c8/4, 0x02008821); + INSTANCE_WR(ctx, 0x00218/4, 0x00000040); + INSTANCE_WR(ctx, 0x0021c/4, 0x00000040); + INSTANCE_WR(ctx, 0x00220/4, 0x00000040); + INSTANCE_WR(ctx, 0x00228/4, 0x00000040); + INSTANCE_WR(ctx, 0x00234/4, 0x80000000); + INSTANCE_WR(ctx, 0x00238/4, 0x80000000); + INSTANCE_WR(ctx, 0x0023c/4, 0x80000000); + INSTANCE_WR(ctx, 0x00240/4, 0x80000000); + INSTANCE_WR(ctx, 0x00244/4, 0x80000000); + INSTANCE_WR(ctx, 0x00248/4, 0x80000000); + INSTANCE_WR(ctx, 0x0024c/4, 0x80000000); + INSTANCE_WR(ctx, 0x00250/4, 0x80000000); + INSTANCE_WR(ctx, 0x00270/4, 0x0b0b0b0c); + INSTANCE_WR(ctx, 0x003e0/4, 0x00040000); + INSTANCE_WR(ctx, 0x003f0/4, 0x55555555); + INSTANCE_WR(ctx, 0x003f4/4, 0x55555555); + INSTANCE_WR(ctx, 0x003f8/4, 0x55555555); + INSTANCE_WR(ctx, 0x003fc/4, 0x55555555); + INSTANCE_WR(ctx, 0x00428/4, 0x00000008); + INSTANCE_WR(ctx, 0x0043c/4, 0x00001010); + INSTANCE_WR(ctx, 0x00460/4, 0x00000111); + INSTANCE_WR(ctx, 0x00464/4, 0x00000111); + INSTANCE_WR(ctx, 0x00468/4, 0x00000111); + INSTANCE_WR(ctx, 0x0046c/4, 0x00000111); + INSTANCE_WR(ctx, 0x00470/4, 0x00000111); + INSTANCE_WR(ctx, 0x00474/4, 0x00000111); + INSTANCE_WR(ctx, 0x00478/4, 0x00000111); + INSTANCE_WR(ctx, 0x0047c/4, 0x00000111); + INSTANCE_WR(ctx, 0x00480/4, 0x00000111); + INSTANCE_WR(ctx, 0x00484/4, 0x00000111); + INSTANCE_WR(ctx, 0x00488/4, 0x00000111); + INSTANCE_WR(ctx, 0x0048c/4, 0x00000111); + INSTANCE_WR(ctx, 0x00490/4, 0x00000111); + INSTANCE_WR(ctx, 0x00494/4, 0x00000111); + INSTANCE_WR(ctx, 0x00498/4, 0x00000111); + INSTANCE_WR(ctx, 0x0049c/4, 0x00000111); + INSTANCE_WR(ctx, 0x004f4/4, 0x00000111); + INSTANCE_WR(ctx, 0x004f8/4, 0x00080060); + INSTANCE_WR(ctx, 0x00514/4, 0x00000080); + INSTANCE_WR(ctx, 0x00518/4, 0xffff0000); + INSTANCE_WR(ctx, 0x0051c/4, 0x00000001); + INSTANCE_WR(ctx, 0x00530/4, 0x46400000); + INSTANCE_WR(ctx, 0x00540/4, 0xffff0000); + INSTANCE_WR(ctx, 0x00544/4, 0x88888888); + INSTANCE_WR(ctx, 0x00548/4, 0x88888888); + INSTANCE_WR(ctx, 0x0054c/4, 0x88888888); + INSTANCE_WR(ctx, 0x00550/4, 0x88888888); + INSTANCE_WR(ctx, 0x00554/4, 0x88888888); + INSTANCE_WR(ctx, 0x00558/4, 0x88888888); + INSTANCE_WR(ctx, 0x0055c/4, 0x88888888); + INSTANCE_WR(ctx, 0x00560/4, 0x88888888); + INSTANCE_WR(ctx, 0x00564/4, 0x88888888); + INSTANCE_WR(ctx, 0x00568/4, 0x88888888); + INSTANCE_WR(ctx, 0x0056c/4, 0x88888888); + INSTANCE_WR(ctx, 0x00570/4, 0x88888888); + INSTANCE_WR(ctx, 0x00574/4, 0x88888888); + INSTANCE_WR(ctx, 0x00578/4, 0x88888888); + INSTANCE_WR(ctx, 0x0057c/4, 0x88888888); + INSTANCE_WR(ctx, 0x00580/4, 0x88888888); + INSTANCE_WR(ctx, 0x00594/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x00598/4, 0x0fff0000); + INSTANCE_WR(ctx, 0x005a0/4, 0x00011100); + INSTANCE_WR(ctx, 0x005bc/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005c0/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005c4/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005c8/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005cc/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005d0/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005d4/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005d8/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005dc/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005e0/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005e4/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005e8/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005ec/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005f0/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005f4/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x005f8/4, 0x07ff0000); + INSTANCE_WR(ctx, 0x00604/4, 0x4b7fffff); + INSTANCE_WR(ctx, 0x0062c/4, 0x30201000); + INSTANCE_WR(ctx, 0x00630/4, 0x70605040); + INSTANCE_WR(ctx, 0x00634/4, 0xb8a89888); + INSTANCE_WR(ctx, 0x00638/4, 0xf8e8d8c8); + INSTANCE_WR(ctx, 0x0064c/4, 0x40100000); + INSTANCE_WR(ctx, 0x00668/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x0069c/4, 0x435185d6); + INSTANCE_WR(ctx, 0x006a0/4, 0x2155b699); + INSTANCE_WR(ctx, 0x006a4/4, 0xfedcba98); + INSTANCE_WR(ctx, 0x006a8/4, 0x00000098); + INSTANCE_WR(ctx, 0x006b8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x006bc/4, 0x00ff7000); + INSTANCE_WR(ctx, 0x006c0/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x006d0/4, 0x00ff0000); + INSTANCE_WR(ctx, 0x0070c/4, 0x00ffff00); + for (i=0x00750; i<=0x0078c; i+=4) + INSTANCE_WR(ctx, i/4, 0x00018488); + for (i=0x00790; i<=0x007cc; i+=4) + INSTANCE_WR(ctx, i/4, 0x00028202); + for (i=0x00810; i<=0x0084c; i+=4) + INSTANCE_WR(ctx, i/4, 0x0000aae4); + for (i=0x00850; i<=0x0088c; i+=4) + INSTANCE_WR(ctx, i/4, 0x01012000); + for (i=0x00890; i<=0x008cc; i+=4) + INSTANCE_WR(ctx, i/4, 0x00080008); + for (i=0x00910; i<=0x0094c; i+=4) + INSTANCE_WR(ctx, i/4, 0x00100008); + for (i=0x009a0; i<=0x009ac; i+=4) + INSTANCE_WR(ctx, i/4, 0x0001bc80); + for (i=0x009b0; i<=0x009bc; i+=4) + INSTANCE_WR(ctx, i/4, 0x00000202); + for (i=0x009d0; i<=0x009dc; i+=4) + INSTANCE_WR(ctx, i/4, 0x00000008); + for (i=0x009f0; i<=0x009fc; i+=4) + INSTANCE_WR(ctx, i/4, 0x00080008); + INSTANCE_WR(ctx, 0x00a10/4, 0x00000002); + INSTANCE_WR(ctx, 0x00a44/4, 0x00000421); + INSTANCE_WR(ctx, 0x00a48/4, 0x030c30c3); + INSTANCE_WR(ctx, 0x00a54/4, 0x3e020200); + INSTANCE_WR(ctx, 0x00a58/4, 0x00ffffff); + INSTANCE_WR(ctx, 0x00a5c/4, 0x20103f00); + INSTANCE_WR(ctx, 0x00a68/4, 0x00040000); + INSTANCE_WR(ctx, 0x00aa0/4, 0x00008100); + INSTANCE_WR(ctx, 0x00b2c/4, 0x00000001); + INSTANCE_WR(ctx, 0x00b70/4, 0x00001001); + INSTANCE_WR(ctx, 0x00b7c/4, 0x00000003); + INSTANCE_WR(ctx, 0x00b80/4, 0x00888001); + INSTANCE_WR(ctx, 0x00bb0/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bb4/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bb8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bbc/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bc0/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bc4/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bc8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bcc/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bd0/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bd4/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bd8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bdc/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00be0/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00be4/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00be8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bec/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bf0/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bf4/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bf8/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00bfc/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c00/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c04/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c08/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c0c/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c10/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c14/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c18/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c1c/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c20/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c24/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c28/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c2c/4, 0xffffffff); + INSTANCE_WR(ctx, 0x00c54/4, 0x00000005); + INSTANCE_WR(ctx, 0x00c60/4, 0x0000ffff); + INSTANCE_WR(ctx, 0x00c7c/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c80/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c84/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c88/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c8c/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c90/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c94/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c98/4, 0x00005555); + INSTANCE_WR(ctx, 0x00c9c/4, 0x00000001); + INSTANCE_WR(ctx, 0x00cd4/4, 0x00000001); + INSTANCE_WR(ctx, 0x00cd8/4, 0x08e00001); + INSTANCE_WR(ctx, 0x00cdc/4, 0x000e3000); + for(i=0x030a0; i<=0x03118; i+=8) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for(i=0x098a0; i<=0x0ba90; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x0baa0; i<=0x0be90; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for(i=0x0e2e0; i<=0x0fff0; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x10008; i<=0x104d0; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x104e0; i<=0x108d0; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for(i=0x12d20; i<=0x14f10; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x14f20; i<=0x15310; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); + for(i=0x17760; i<=0x19950; i+=24) + INSTANCE_WR(ctx, i/4, 0x00000001); + for(i=0x19960; i<=0x19d50; i+=16) + INSTANCE_WR(ctx, i/4, 0x3f800000); +} + +static void +nv4c_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; int i; - INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx)); + INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff); INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff); INSTANCE_WR(ctx, 0x00030/4, 0x00000001); @@ -648,12 +1358,13 @@ static void nv4c_graph_context_init(drm_device_t *dev, struct mem_block *ctx) INSTANCE_WR(ctx, i/4, 0x3f800000); } -static void nv4e_graph_context_init(drm_device_t *dev, struct mem_block *ctx) +static void +nv4e_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; int i; - INSTANCE_WR(ctx, 0x00000/4, nouveau_chip_instance_get(dev, ctx)); + INSTANCE_WR(ctx, 0x00000/4, ctx->im_pramin->start); INSTANCE_WR(ctx, 0x00024/4, 0x0000ffff); INSTANCE_WR(ctx, 0x00028/4, 0x0000ffff); INSTANCE_WR(ctx, 0x00030/4, 0x00000001); @@ -755,20 +1466,24 @@ static void nv4e_graph_context_init(drm_device_t *dev, struct mem_block *ctx) } int -nv40_graph_context_create(drm_device_t *dev, int channel) +nv40_graph_create_context(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv = - (drm_nouveau_private_t *)dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - void (*ctx_init)(drm_device_t *, struct mem_block *); + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *); unsigned int ctx_size; - int i; + int ret; switch (dev_priv->chipset) { case 0x40: ctx_size = NV40_GRCTX_SIZE; ctx_init = nv40_graph_context_init; break; + case 0x41: + case 0x42: + ctx_size = NV41_GRCTX_SIZE; + ctx_init = nv41_graph_context_init; + break; case 0x43: ctx_size = NV43_GRCTX_SIZE; ctx_init = nv43_graph_context_init; @@ -777,10 +1492,24 @@ nv40_graph_context_create(drm_device_t *dev, int channel) ctx_size = NV46_GRCTX_SIZE; ctx_init = nv46_graph_context_init; break; + case 0x47: + DRM_INFO("NV47 warning: If your card behaves strangely, please come to the irc channel\n"); + ctx_size = NV47_GRCTX_SIZE; + ctx_init = nv47_graph_context_init; + break; + case 0x49: + ctx_size = NV49_GRCTX_SIZE; + ctx_init = nv49_graph_context_init; + break; + case 0x44: case 0x4a: ctx_size = NV4A_GRCTX_SIZE; ctx_init = nv4a_graph_context_init; break; + case 0x4b: + ctx_size = NV4B_GRCTX_SIZE; + ctx_init = nv4b_graph_context_init; + break; case 0x4c: ctx_size = NV4C_GRCTX_SIZE; ctx_init = nv4c_graph_context_init; @@ -795,102 +1524,113 @@ nv40_graph_context_create(drm_device_t *dev, int channel) break; } - /* Alloc and clear RAMIN to store the context */ - chan->ramin_grctx = nouveau_instmem_alloc(dev, ctx_size, 4); - if (!chan->ramin_grctx) - return DRM_ERR(ENOMEM); - for (i=0; i<ctx_size; i+=4) - INSTANCE_WR(chan->ramin_grctx, i/4, 0x00000000); + if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16, + NVOBJ_FLAG_ZERO_ALLOC, + &chan->ramin_grctx))) + return ret; /* Initialise default context values */ - ctx_init(dev, chan->ramin_grctx); + ctx_init(dev, chan->ramin_grctx->gpuobj); return 0; } -/* Save current context (from PGRAPH) into the channel's context - *XXX: fails sometimes, not sure why.. - */ void -nv40_graph_context_save_current(drm_device_t *dev) +nv40_graph_destroy_context(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv = - (drm_nouveau_private_t *)dev->dev_private; - uint32_t instance; + nouveau_gpuobj_ref_del(chan->dev, &chan->ramin_grctx); +} + +static int +nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t old_cp, tv = 1000, tmp; int i; - NV_WRITE(NV04_PGRAPH_FIFO, 0); + old_cp = NV_READ(NV20_PGRAPH_CHANNEL_CTX_POINTER); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); - instance = NV_READ(0x40032C) & 0xFFFFF; - if (!instance) { - NV_WRITE(NV04_PGRAPH_FIFO, 1); - return; - } + tmp = NV_READ(NV40_PGRAPH_CTXCTL_0310); + tmp |= save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE : + NV40_PGRAPH_CTXCTL_0310_XFER_LOAD; + NV_WRITE(NV40_PGRAPH_CTXCTL_0310, tmp); + + tmp = NV_READ(NV40_PGRAPH_CTXCTL_0304); + tmp |= NV40_PGRAPH_CTXCTL_0304_XFER_CTX; + NV_WRITE(NV40_PGRAPH_CTXCTL_0304, tmp); - NV_WRITE(0x400784, instance); - NV_WRITE(0x400310, NV_READ(0x400310) | 0x20); - NV_WRITE(0x400304, 1); - /* just in case, we don't want to spin in-kernel forever */ - for (i=0; i<1000; i++) { - if (NV_READ(0x40030C) == 0) + for (i = 0; i < tv; i++) { + if (NV_READ(NV40_PGRAPH_CTXCTL_030C) == 0) break; } - if (i==1000) { - DRM_ERROR("failed to save current grctx to ramin\n"); - DRM_ERROR("instance = 0x%08x\n", NV_READ(0x40032C)); - DRM_ERROR("0x40030C = 0x%08x\n", NV_READ(0x40030C)); - NV_WRITE(NV04_PGRAPH_FIFO, 1); - return; + + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, old_cp); + + if (i == tv) { + uint32_t ucstat = NV_READ(NV40_PGRAPH_CTXCTL_UCODE_STAT); + DRM_ERROR("Failed: Instance=0x%08x Save=%d\n", inst, save); + DRM_ERROR("IP: 0x%02x, Opcode: 0x%08x\n", + ucstat >> NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT, + ucstat & NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK); + DRM_ERROR("0x40030C = 0x%08x\n", + NV_READ(NV40_PGRAPH_CTXCTL_030C)); + return -EBUSY; } - NV_WRITE(NV04_PGRAPH_FIFO, 1); + return 0; +} + +/* Save current context (from PGRAPH) into the channel's context + *XXX: fails sometimes, not sure why.. + */ +int +nv40_graph_save_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + uint32_t inst; + + if (!chan->ramin_grctx) + return -EINVAL; + inst = chan->ramin_grctx->instance >> 4; + + return nv40_graph_transfer_context(dev, inst, 1); } /* Restore the context for a specific channel into PGRAPH * XXX: fails sometimes.. not sure why */ -void -nv40_graph_context_restore(drm_device_t *dev, int channel) +int +nv40_graph_load_context(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv = - (drm_nouveau_private_t *)dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - uint32_t instance; - int i; - - instance = nouveau_chip_instance_get(dev, chan->ramin_grctx); + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t inst; + int ret; - NV_WRITE(NV04_PGRAPH_FIFO, 0); - NV_WRITE(0x400784, instance); - NV_WRITE(0x400310, NV_READ(0x400310) | 0x40); - NV_WRITE(0x400304, 1); - /* just in case, we don't want to spin in-kernel forever */ - for (i=0; i<1000; i++) { - if (NV_READ(0x40030C) == 0) - break; - } - if (i==1000) { - DRM_ERROR("failed to restore grctx for ch%d to PGRAPH\n", - channel); - DRM_ERROR("instance = 0x%08x\n", instance); - DRM_ERROR("0x40030C = 0x%08x\n", NV_READ(0x40030C)); - NV_WRITE(NV04_PGRAPH_FIFO, 1); - return; - } + if (!chan->ramin_grctx) + return -EINVAL; + inst = chan->ramin_grctx->instance >> 4; + ret = nv40_graph_transfer_context(dev, inst, 0); + if (ret) + return ret; /* 0x40032C, no idea of it's exact function. Could simply be a * record of the currently active PGRAPH context. It's currently * unknown as to what bit 24 does. The nv ddx has it set, so we will * set it here too. */ - NV_WRITE(0x40032C, instance | 0x01000000); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); + NV_WRITE(NV40_PGRAPH_CTXCTL_CUR, + (inst & NV40_PGRAPH_CTXCTL_CUR_INST_MASK) | + NV40_PGRAPH_CTXCTL_CUR_LOADED); /* 0x32E0 records the instance address of the active FIFO's PGRAPH * context. If at any time this doesn't match 0x40032C, you will * recieve PGRAPH_INTR_CONTEXT_SWITCH */ - NV_WRITE(NV40_PFIFO_GRCTX_INSTANCE, instance); - NV_WRITE(NV04_PGRAPH_FIFO, 1); + NV_WRITE(NV40_PFIFO_GRCTX_INSTANCE, inst); + return 0; } /* Some voodoo that makes context switching work without the binary driver @@ -943,6 +1683,37 @@ static uint32_t nv40_ctx_voodoo[] = { ~0 }; +static uint32_t nv41_ctx_voodoo[] = { + 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, + 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409306, + 0x0040a068, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, + 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968, + 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, + 0x004020e6, 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, + 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, + 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, + 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, + 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, + 0x001046ec, 0x00500060, 0x00404087, 0x0060000d, 0x004079e6, 0x002000f1, + 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, + 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, + 0x00200020, 0x001006cc, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, + 0x0010c3d7, 0x001043e1, 0x00500060, 0x00200233, 0x0060000a, 0x00104800, + 0x00108901, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00148a00, + 0x00108a14, 0x00200020, 0x00100b00, 0x00134b2c, 0x0010cd00, 0x0010cd04, + 0x00114d08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, + 0x002002d2, 0x0060000a, 0x00300000, 0x00200680, 0x00407200, 0x00200684, + 0x00800001, 0x00200b1a, 0x0060000a, 0x00206380, 0x0040788a, 0x00201480, + 0x00800041, 0x00408900, 0x00600006, 0x004085e6, 0x00700080, 0x0020007a, + 0x0060000a, 0x00104280, 0x002002d2, 0x0060000a, 0x00200004, 0x00800001, + 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a068, 0x00700000, + 0x00200000, 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, 0x00500060, + 0x00600007, 0x00409388, 0x0060000f, 0x00500060, 0x00200000, 0x0060000a, + 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x00940400, 0x00200020, + 0x0060000b, 0x00500069, 0x0060000c, 0x00402168, 0x0040a206, 0x0040a305, + 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 +}; + static uint32_t nv43_ctx_voodoo[] = { 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409565, 0x00409a06, @@ -976,6 +1747,39 @@ static uint32_t nv43_ctx_voodoo[] = { ~0 }; +static uint32_t nv44_ctx_voodoo[] = { + 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, + 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409a65, 0x00409f06, + 0x0040ac68, 0x0040248f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, + 0x001041c6, 0x00104040, 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, + 0x00402320, 0x00402321, 0x00402322, 0x00402324, 0x00402326, 0x0040232b, + 0x001040c5, 0x00402328, 0x001040c5, 0x00402320, 0x00402468, 0x0060000d, + 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, 0x00402be6, + 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, 0x00110158, + 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, 0x001041c9, + 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, 0x001242c0, + 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, 0x0011415f, + 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, 0x001046ec, + 0x00500060, 0x00404b87, 0x0060000d, 0x004084e6, 0x002000f1, 0x0060000a, + 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, 0x0011068b, 0x00168691, + 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, 0x001646cc, + 0x001186e6, 0x001046ed, 0x001246f0, 0x002000c0, 0x00100700, 0x0010c3d7, + 0x001043e1, 0x00500060, 0x00200232, 0x0060000a, 0x00104800, 0x00108901, + 0x00104910, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00148a00, + 0x00108a14, 0x00160b00, 0x00134b2c, 0x0010cd00, 0x0010cd04, 0x0010cd08, + 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, 0x00104f06, 0x002002c8, + 0x0060000a, 0x00300000, 0x00200080, 0x00407d00, 0x00200084, 0x00800001, + 0x00200510, 0x0060000a, 0x002037e0, 0x0040838a, 0x00201320, 0x00800029, + 0x00409400, 0x00600006, 0x004090e6, 0x00700080, 0x0020007a, 0x0060000a, + 0x00104280, 0x002002c8, 0x0060000a, 0x00200004, 0x00800001, 0x00700000, + 0x00200000, 0x0060000a, 0x00106002, 0x0040ac68, 0x00700000, 0x00200000, + 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, 0x00500060, 0x00600007, + 0x00409e88, 0x0060000f, 0x00000000, 0x00500060, 0x00200000, 0x0060000a, + 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x01940000, 0x00200020, + 0x0060000b, 0x00500069, 0x0060000c, 0x00402c68, 0x0040ae06, 0x0040af05, + 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 +}; + static uint32_t nv46_ctx_voodoo[] = { 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00408f65, 0x00409306, @@ -1007,6 +1811,71 @@ static uint32_t nv46_ctx_voodoo[] = { 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 }; +static uint32_t nv47_ctx_voodoo[] = { + 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, + 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409265, 0x00409606, + 0x0040a368, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, + 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968, + 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, + 0x004020e6, 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, + 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, + 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, + 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, + 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d12, + 0x00500060, 0x00403f87, 0x0060000d, 0x00407ce6, 0x002000f0, 0x0060000a, + 0x00200020, 0x00100620, 0x00154650, 0x00104668, 0x0017466d, 0x0011068b, + 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, 0x001146c6, + 0x00200022, 0x001006cc, 0x001246f0, 0x002000c0, 0x00100700, 0x0010c3d7, + 0x001043e1, 0x00500060, 0x00200268, 0x0060000a, 0x00104800, 0x00108901, + 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00144a00, 0x00104a19, + 0x0010ca1c, 0x00110b00, 0x00200028, 0x00100b08, 0x00134c2e, 0x0010cd00, + 0x0010cd04, 0x00120d08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, + 0x00104f06, 0x00105406, 0x00105709, 0x00200318, 0x0060000a, 0x00300000, + 0x00200680, 0x00407500, 0x00200684, 0x00800001, 0x00200b60, 0x0060000a, + 0x00209540, 0x00407b8a, 0x00201350, 0x00800041, 0x00408c00, 0x00600006, + 0x004088e6, 0x00700080, 0x0020007a, 0x0060000a, 0x00104280, 0x00200318, + 0x0060000a, 0x00200004, 0x00800001, 0x00700000, 0x00200000, 0x0060000a, + 0x00106002, 0x0040a368, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, + 0x00700080, 0x00400a68, 0x00500060, 0x00600007, 0x00409688, 0x0060000f, + 0x00500060, 0x00200000, 0x0060000a, 0x00700000, 0x00106001, 0x0091a880, + 0x00901ffe, 0x10940000, 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, + 0x00402168, 0x0040a506, 0x0040a605, 0x00600009, 0x00700005, 0x00700006, + 0x0060000e, ~0 +}; + +//this is used for nv49 and nv4b +static uint32_t nv49_4b_ctx_voodoo[] ={ + 0x00400564, 0x00400505, 0x00408165, 0x00408206, 0x00409e68, 0x00200020, + 0x0060000a, 0x00700080, 0x00104042, 0x00200020, 0x0060000a, 0x00700000, + 0x001040c5, 0x00400f26, 0x00401068, 0x0060000d, 0x0070008f, 0x0070000e, + 0x00408d68, 0x004015e6, 0x007000a0, 0x00700080, 0x0040180f, 0x00700000, + 0x00200029, 0x0060000a, 0x0011814d, 0x00110158, 0x00105401, 0x0020003a, + 0x00100051, 0x001040c5, 0x0010c1c4, 0x001041c9, 0x0010c1dc, 0x00150210, + 0x0012c225, 0x00108238, 0x0010823e, 0x001242c0, 0x00200040, 0x00100280, + 0x00128100, 0x00128120, 0x00128143, 0x0011415f, 0x0010815c, 0x0010c140, + 0x00104029, 0x00110400, 0x00104d12, 0x00500060, 0x004071e6, 0x00200118, + 0x0060000a, 0x00200020, 0x00100620, 0x00154650, 0x00104668, 0x0017466d, + 0x0011068b, 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, + 0x001146c6, 0x00200022, 0x001006cc, 0x001246f0, 0x002000c0, 0x00100700, + 0x0010c3d7, 0x001043e1, 0x00500060, 0x00200290, 0x0060000a, 0x00104800, + 0x00108901, 0x00124920, 0x0020001f, 0x00100940, 0x00140965, 0x00144a00, + 0x00104a19, 0x0010ca1c, 0x00110b00, 0x00200028, 0x00100b08, 0x00134c2e, + 0x0010cd00, 0x0010cd04, 0x00120d08, 0x00104d80, 0x00104e00, 0x0012d600, + 0x00105c00, 0x00104f06, 0x00105406, 0x00105709, 0x00200340, 0x0060000a, + 0x00300000, 0x00200680, 0x00406a0f, 0x00200684, 0x00800001, 0x00200b88, + 0x0060000a, 0x00209540, 0x0040708a, 0x00201350, 0x00800041, 0x00407c0f, + 0x00600006, 0x00407ce6, 0x00700080, 0x002000a2, 0x0060000a, 0x00104280, + 0x00200340, 0x0060000a, 0x00200004, 0x00800001, 0x0070008e, 0x00408d68, + 0x0040020f, 0x00600006, 0x00409e68, 0x00600007, 0x0070000f, 0x0070000e, + 0x00408d68, 0x0091a880, 0x00901ffe, 0x10940000, 0x00200020, 0x0060000b, + 0x00500069, 0x0060000c, 0x00401568, 0x00700000, 0x00200001, 0x0040910e, + 0x00200021, 0x0060000a, 0x00409b0d, 0x00104a40, 0x00104a50, 0x00104a60, + 0x00104a70, 0x00104a80, 0x00104a90, 0x00104aa0, 0x00104ab0, 0x00407e0e, + 0x0040130f, 0x00408568, 0x0040a006, 0x0040a105, 0x00600009, 0x00700005, + 0x00700006, 0x0060000e, ~0 +}; + + static uint32_t nv4a_ctx_voodoo[] = { 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409965, 0x00409e06, @@ -1040,6 +1909,37 @@ static uint32_t nv4a_ctx_voodoo[] = { 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 }; +static uint32_t nv4c_ctx_voodoo[] = { + 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, + 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409065, 0x00409406, + 0x0040a168, 0x0040198f, 0x00200001, 0x0060000a, 0x00700080, 0x00104042, + 0x00200001, 0x0060000a, 0x00700000, 0x001040c5, 0x00401826, 0x00401968, + 0x0060000d, 0x00200000, 0x0060000a, 0x00700000, 0x00106000, 0x00700080, + 0x004020e6, 0x007000a0, 0x00500060, 0x00200001, 0x0060000a, 0x0011814d, + 0x00110158, 0x00105401, 0x0020003a, 0x00100051, 0x001040c5, 0x0010c1c4, + 0x001041c9, 0x0010c1dc, 0x00150210, 0x0012c225, 0x00108238, 0x0010823e, + 0x001242c0, 0x00200040, 0x00100280, 0x00128100, 0x00128120, 0x00128143, + 0x0011415f, 0x0010815c, 0x0010c140, 0x00104029, 0x00110400, 0x00104d10, + 0x0010427e, 0x001046ec, 0x00500060, 0x00404187, 0x0060000d, 0x00407ae6, + 0x002000f2, 0x0060000a, 0x00148653, 0x00104668, 0x0010c66d, 0x00120682, + 0x0011068b, 0x00168691, 0x001046ae, 0x001046b0, 0x001206b4, 0x001046c4, + 0x001146c6, 0x00200020, 0x001006cc, 0x001046ed, 0x001246f0, 0x002000c0, + 0x00100700, 0x0010c3d7, 0x001043e1, 0x00500060, 0x00200234, 0x0060000a, + 0x00104800, 0x00108901, 0x00104910, 0x00124920, 0x0020001f, 0x00100940, + 0x00140965, 0x00148a00, 0x00108a14, 0x00140b00, 0x00134b2c, 0x0010cd00, + 0x0010cd04, 0x00104d08, 0x00104d80, 0x00104e00, 0x0012d600, 0x00105c00, + 0x00104f06, 0x002002c0, 0x0060000a, 0x00300000, 0x00200080, 0x00407300, + 0x00200084, 0x00800001, 0x00200508, 0x0060000a, 0x00201320, 0x0040798a, + 0xfffffaf8, 0x00800029, 0x00408a00, 0x00600006, 0x004086e6, 0x00700080, + 0x0020007a, 0x0060000a, 0x00104280, 0x002002c0, 0x0060000a, 0x00200004, + 0x00800001, 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x0040a168, + 0x00700000, 0x00200000, 0x0060000a, 0x00106002, 0x00700080, 0x00400a68, + 0x00500060, 0x00600007, 0x00409488, 0x0060000f, 0x00500060, 0x00200000, + 0x0060000a, 0x00700000, 0x00106001, 0x00910880, 0x00901ffe, 0x01940000, + 0x00200020, 0x0060000b, 0x00500069, 0x0060000c, 0x00402168, 0x0040a306, + 0x0040a405, 0x00600009, 0x00700005, 0x00700006, 0x0060000e, ~0 +}; + static uint32_t nv4e_ctx_voodoo[] = { 0x00400889, 0x00200000, 0x0060000a, 0x00200000, 0x00300000, 0x00800001, 0x00700009, 0x0060000e, 0x00400d64, 0x00400d05, 0x00409565, 0x00409a06, @@ -1083,10 +1983,10 @@ static uint32_t nv4e_ctx_voodoo[] = { * C51 0x4e */ int -nv40_graph_init(drm_device_t *dev) +nv40_graph_init(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = - (drm_nouveau_private_t *)dev->dev_private; + struct drm_nouveau_private *dev_priv = + (struct drm_nouveau_private *)dev->dev_private; uint32_t *ctx_voodoo; uint32_t vramsz, tmp; int i, j; @@ -1098,9 +1998,16 @@ nv40_graph_init(drm_device_t *dev) switch (dev_priv->chipset) { case 0x40: ctx_voodoo = nv40_ctx_voodoo; break; + case 0x41: + case 0x42: ctx_voodoo = nv41_ctx_voodoo; break; case 0x43: ctx_voodoo = nv43_ctx_voodoo; break; + case 0x44: ctx_voodoo = nv44_ctx_voodoo; break; case 0x46: ctx_voodoo = nv46_ctx_voodoo; break; + case 0x47: ctx_voodoo = nv47_ctx_voodoo; break; + case 0x49: ctx_voodoo = nv49_4b_ctx_voodoo; break; case 0x4a: ctx_voodoo = nv4a_ctx_voodoo; break; + case 0x4b: ctx_voodoo = nv49_4b_ctx_voodoo; break; + case 0x4c: ctx_voodoo = nv4c_ctx_voodoo; break; case 0x4e: ctx_voodoo = nv4e_ctx_voodoo; break; default: DRM_ERROR("Unknown ctx_voodoo for chipset 0x%02x\n", @@ -1114,18 +2021,18 @@ nv40_graph_init(drm_device_t *dev) DRM_DEBUG("Loading context-switch voodoo\n"); i = 0; - NV_WRITE(0x400324, 0); + NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); while (ctx_voodoo[i] != ~0) { - NV_WRITE(0x400328, ctx_voodoo[i]); + NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_DATA, ctx_voodoo[i]); i++; } } /* No context present currently */ - NV_WRITE(0x40032C, 0x00000000); + NV_WRITE(NV40_PGRAPH_CTXCTL_CUR, 0x00000000); - NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000); NV_WRITE(NV03_PGRAPH_INTR , 0xFFFFFFFF); + NV_WRITE(NV40_PGRAPH_INTR_EN, 0xFFFFFFFF); NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000); @@ -1311,7 +2218,7 @@ nv40_graph_init(drm_device_t *dev) return 0; } -void nv40_graph_takedown(drm_device_t *dev) +void nv40_graph_takedown(struct drm_device *dev) { } diff --git a/shared-core/nv40_mc.c b/shared-core/nv40_mc.c index 8dbd96fd..c7db9023 100644 --- a/shared-core/nv40_mc.c +++ b/shared-core/nv40_mc.c @@ -4,9 +4,9 @@ #include "nouveau_drm.h" int -nv40_mc_init(drm_device_t *dev) +nv40_mc_init(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t tmp; /* Power up everything, resetting each individual unit will @@ -14,8 +14,6 @@ nv40_mc_init(drm_device_t *dev) */ NV_WRITE(NV03_PMC_ENABLE, 0xFFFFFFFF); - NV_WRITE(NV03_PMC_INTR_EN_0, 0); - switch (dev_priv->chipset) { case 0x44: case 0x46: /* G72 */ @@ -35,7 +33,7 @@ nv40_mc_init(drm_device_t *dev) } void -nv40_mc_takedown(drm_device_t *dev) +nv40_mc_takedown(struct drm_device *dev) { } diff --git a/shared-core/nv50_fifo.c b/shared-core/nv50_fifo.c new file mode 100644 index 00000000..7859544a --- /dev/null +++ b/shared-core/nv50_fifo.c @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" + +typedef struct { + struct nouveau_gpuobj_ref *thingo; +} nv50_fifo_priv; + +#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) + +static void +nv50_fifo_init_thingo(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + nv50_fifo_priv *priv = dev_priv->Engine.fifo.priv; + struct nouveau_gpuobj_ref *thingo = priv->thingo; + int i, fi=2; + + DRM_DEBUG("\n"); + + INSTANCE_WR(thingo->gpuobj, 0, 0x7e); + INSTANCE_WR(thingo->gpuobj, 1, 0x7e); + for (i = 1; i < 127; i++, fi) { + if (dev_priv->fifos[i]) { + INSTANCE_WR(thingo->gpuobj, fi, i); + fi++; + } + } + + NV_WRITE(0x32f4, thingo->instance >> 12); + NV_WRITE(0x32ec, fi); + NV_WRITE(0x2500, 0x101); +} + +static int +nv50_fifo_channel_enable(struct drm_device *dev, int channel, int nt) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = dev_priv->fifos[channel]; + uint32_t inst; + + DRM_DEBUG("ch%d\n", channel); + + if (!chan->ramfc) + return -EINVAL; + + if (IS_G80) inst = chan->ramfc->instance >> 12; + else inst = chan->ramfc->instance >> 8; + NV_WRITE(NV50_PFIFO_CTX_TABLE(channel), + inst | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); + + if (!nt) nv50_fifo_init_thingo(dev); + return 0; +} + +static void +nv50_fifo_channel_disable(struct drm_device *dev, int channel, int nt) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t inst; + + DRM_DEBUG("ch%d, nt=%d\n", channel, nt); + + if (IS_G80) inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80; + else inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84; + NV_WRITE(NV50_PFIFO_CTX_TABLE(channel), inst); + + if (!nt) nv50_fifo_init_thingo(dev); +} + +static void +nv50_fifo_init_reset(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t pmc_e; + + DRM_DEBUG("\n"); + + pmc_e = NV_READ(NV03_PMC_ENABLE); + NV_WRITE(NV03_PMC_ENABLE, pmc_e & ~NV_PMC_ENABLE_PFIFO); + pmc_e = NV_READ(NV03_PMC_ENABLE); + NV_WRITE(NV03_PMC_ENABLE, pmc_e | NV_PMC_ENABLE_PFIFO); +} + +static void +nv50_fifo_init_intr(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + DRM_DEBUG("\n"); + + NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF); + NV_WRITE(NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF); +} + +static void +nv50_fifo_init_context_table(struct drm_device *dev) +{ + int i; + + DRM_DEBUG("\n"); + + for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) + nv50_fifo_channel_disable(dev, i, 1); + nv50_fifo_init_thingo(dev); +} + +static void +nv50_fifo_init_regs__nv(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + DRM_DEBUG("\n"); + + NV_WRITE(0x250c, 0x6f3cfc34); +} + +static int +nv50_fifo_init_regs(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + DRM_DEBUG("\n"); + + NV_WRITE(0x2500, 0); + NV_WRITE(0x3250, 0); + NV_WRITE(0x3220, 0); + NV_WRITE(0x3204, 0); + NV_WRITE(0x3210, 0); + NV_WRITE(0x3270, 0); + + /* Enable dummy channels setup by nv50_instmem.c */ + nv50_fifo_channel_enable(dev, 0, 1); + nv50_fifo_channel_enable(dev, 127, 1); + + return 0; +} + +int +nv50_fifo_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + nv50_fifo_priv *priv; + int ret; + + DRM_DEBUG("\n"); + + priv = drm_calloc(1, sizeof(*priv), DRM_MEM_DRIVER); + if (!priv) + return -ENOMEM; + dev_priv->Engine.fifo.priv = priv; + + nv50_fifo_init_reset(dev); + nv50_fifo_init_intr(dev); + + if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, (128+2)*4, 0x1000, + NVOBJ_FLAG_ZERO_ALLOC, + &priv->thingo))) { + DRM_ERROR("error creating thingo: %d\n", ret); + return ret; + } + + nv50_fifo_init_context_table(dev); + + nv50_fifo_init_regs__nv(dev); + if ((ret = nv50_fifo_init_regs(dev))) + return ret; + + return 0; +} + +void +nv50_fifo_takedown(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + nv50_fifo_priv *priv = dev_priv->Engine.fifo.priv; + + DRM_DEBUG("\n"); + + if (!priv) + return; + + nouveau_gpuobj_ref_del(dev, &priv->thingo); + + dev_priv->Engine.fifo.priv = NULL; + drm_free(priv, sizeof(*priv), DRM_MEM_DRIVER); +} + +int +nv50_fifo_create_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *ramfc = NULL; + int ret; + + DRM_DEBUG("ch%d\n", chan->id); + + if (IS_G80) { + uint32_t ramfc_offset = chan->ramin->gpuobj->im_pramin->start; + uint32_t vram_offset = chan->ramin->gpuobj->im_backing->start; + if ((ret = nouveau_gpuobj_new_fake(dev, ramfc_offset, + vram_offset, 0x100, + NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ZERO_FREE, + &ramfc, &chan->ramfc))) + return ret; + } else { + if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 0x100, + 256, + NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ZERO_FREE, + &chan->ramfc))) + return ret; + ramfc = chan->ramfc->gpuobj; + } + + INSTANCE_WR(ramfc, 0x48/4, chan->pushbuf->instance >> 4); + INSTANCE_WR(ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4)); + INSTANCE_WR(ramfc, 0x3c/4, 0x000f0078); /* fetch? */ + INSTANCE_WR(ramfc, 0x44/4, 0x2101ffff); + INSTANCE_WR(ramfc, 0x60/4, 0x7fffffff); + INSTANCE_WR(ramfc, 0x10/4, 0x00000000); + INSTANCE_WR(ramfc, 0x08/4, 0x00000000); + INSTANCE_WR(ramfc, 0x40/4, 0x00000000); + INSTANCE_WR(ramfc, 0x50/4, 0x2039b2e0); + INSTANCE_WR(ramfc, 0x54/4, 0x000f0000); + INSTANCE_WR(ramfc, 0x7c/4, 0x30000001); + INSTANCE_WR(ramfc, 0x78/4, 0x00000000); + INSTANCE_WR(ramfc, 0x4c/4, chan->pushbuf_mem->size - 1); + + if (!IS_G80) { + INSTANCE_WR(chan->ramin->gpuobj, 0, chan->id); + INSTANCE_WR(chan->ramin->gpuobj, 1, chan->ramfc->instance); + + INSTANCE_WR(ramfc, 0x88/4, 0x3d520); /* some vram addy >> 10 */ + INSTANCE_WR(ramfc, 0x98/4, chan->ramin->instance >> 12); + } + + if ((ret = nv50_fifo_channel_enable(dev, chan->id, 0))) { + DRM_ERROR("error enabling ch%d: %d\n", chan->id, ret); + nouveau_gpuobj_ref_del(dev, &chan->ramfc); + return ret; + } + + return 0; +} + +void +nv50_fifo_destroy_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + + DRM_DEBUG("ch%d\n", chan->id); + + nv50_fifo_channel_disable(dev, chan->id, 0); + + /* Dummy channel, also used on ch 127 */ + if (chan->id == 0) + nv50_fifo_channel_disable(dev, 127, 0); + + nouveau_gpuobj_ref_del(dev, &chan->ramfc); +} + +int +nv50_fifo_load_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *ramfc = chan->ramfc->gpuobj; + + DRM_DEBUG("ch%d\n", chan->id); + + /*XXX: incomplete, only touches the regs that NV does */ + + NV_WRITE(0x3244, 0); + NV_WRITE(0x3240, 0); + + NV_WRITE(0x3224, INSTANCE_RD(ramfc, 0x3c/4)); + NV_WRITE(NV04_PFIFO_CACHE1_DMA_INSTANCE, INSTANCE_RD(ramfc, 0x48/4)); + NV_WRITE(0x3234, INSTANCE_RD(ramfc, 0x4c/4)); + NV_WRITE(0x3254, 1); + NV_WRITE(NV03_PFIFO_RAMHT, INSTANCE_RD(ramfc, 0x80/4)); + + if (!IS_G80) { + NV_WRITE(0x340c, INSTANCE_RD(ramfc, 0x88/4)); + NV_WRITE(0x3410, INSTANCE_RD(ramfc, 0x98/4)); + } + + NV_WRITE(NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); + return 0; +} + +int +nv50_fifo_save_context(struct nouveau_channel *chan) +{ + DRM_DEBUG("ch%d\n", chan->id); + DRM_ERROR("stub!\n"); + return 0; +} + diff --git a/shared-core/nv50_graph.c b/shared-core/nv50_graph.c new file mode 100644 index 00000000..e5bbf65e --- /dev/null +++ b/shared-core/nv50_graph.c @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" + +#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) + +static void +nv50_graph_init_reset(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t pmc_e; + + DRM_DEBUG("\n"); + + pmc_e = NV_READ(NV03_PMC_ENABLE); + NV_WRITE(NV03_PMC_ENABLE, pmc_e & ~NV_PMC_ENABLE_PGRAPH); + pmc_e = NV_READ(NV03_PMC_ENABLE); + NV_WRITE(NV03_PMC_ENABLE, pmc_e | NV_PMC_ENABLE_PGRAPH); +} + +static void +nv50_graph_init_intr(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + DRM_DEBUG("\n"); + NV_WRITE(NV03_PGRAPH_INTR, 0xffffffff); + NV_WRITE(NV40_PGRAPH_INTR_EN, 0xffffffff); +} + +static void +nv50_graph_init_regs__nv(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + DRM_DEBUG("\n"); + + NV_WRITE(0x400804, 0xc0000000); + NV_WRITE(0x406800, 0xc0000000); + NV_WRITE(0x400c04, 0xc0000000); + NV_WRITE(0x401804, 0xc0000000); + NV_WRITE(0x405018, 0xc0000000); + NV_WRITE(0x402000, 0xc0000000); + + NV_WRITE(0x400108, 0xffffffff); + + NV_WRITE(0x400824, 0x00004000); + NV_WRITE(0x400500, 0x00010001); +} + +static void +nv50_graph_init_regs(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + DRM_DEBUG("\n"); + + NV_WRITE(NV04_PGRAPH_DEBUG_3, (1<<2) /* HW_CONTEXT_SWITCH_ENABLED */); +} + +static uint32_t nv84_ctx_voodoo[] = { + 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89, + 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff, + 0x00700009, 0x0041634d, 0x00402944, 0x00402905, 0x0040290d, 0x00413e06, + 0x00600005, 0x004015c5, 0x00600011, 0x0040270b, 0x004021c5, 0x00700000, + 0x00700081, 0x00600004, 0x0050004a, 0x00216f40, 0x00600007, 0x00c02801, + 0x0020002e, 0x00800001, 0x005000cb, 0x0090ffff, 0x0091ffff, 0x00200020, + 0x00600008, 0x0050004c, 0x00600009, 0x00413e45, 0x0041594d, 0x0070009d, + 0x00402dcf, 0x0070009f, 0x0050009f, 0x00402ac0, 0x00200200, 0x00600008, + 0x00402a4f, 0x00402ac0, 0x004030cc, 0x00700081, 0x00200000, 0x00600006, + 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00216f40, 0x00600007, + 0x00c00b01, 0x0020001e, 0x00800001, 0x005000cb, 0x00c000ff, 0x00700080, + 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x00200480, 0x00600007, + 0x00300000, 0x00c000ff, 0x00c800ff, 0x00414907, 0x00202916, 0x008000ff, + 0x0040508c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, 0x0070000f, + 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001c0242, 0x00120302, + 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000f, + 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, 0x00160b02, + 0x00120b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407, + 0x00111409, 0x0011140b, 0x002000cb, 0x00101500, 0x0040790f, 0x0040794b, + 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x0040798c, + 0x005000cb, 0x00000000, 0x0020002b, 0x00101a05, 0x00131c00, 0x00121c04, + 0x00141c20, 0x00111c25, 0x00131c40, 0x00121c44, 0x00141c60, 0x00111c65, + 0x00131c80, 0x00121c84, 0x00141ca0, 0x00111ca5, 0x00131cc0, 0x00121cc4, + 0x00141ce0, 0x00111ce5, 0x00131f00, 0x00191f40, 0x0040a1e0, 0x002001ed, + 0x00600006, 0x00200044, 0x00102080, 0x001120c6, 0x001520c9, 0x001920d0, + 0x00122100, 0x00122103, 0x00162200, 0x00122207, 0x00112280, 0x00112300, + 0x00112302, 0x00122380, 0x0011238b, 0x00112394, 0x0011239c, 0x0040bee1, + 0x00200254, 0x00600006, 0x00200044, 0x00102480, 0x0040af0f, 0x0040af4b, + 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x0040af8c, + 0x005000cb, 0x00000000, 0x001124c6, 0x001524c9, 0x001924d0, 0x00122500, + 0x00122503, 0x00162600, 0x00122607, 0x00112680, 0x00112700, 0x00112702, + 0x00122780, 0x0011278b, 0x00112794, 0x0011279c, 0x0040d1e2, 0x002002bb, + 0x00600006, 0x00200044, 0x00102880, 0x001128c6, 0x001528c9, 0x001928d0, + 0x00122900, 0x00122903, 0x00162a00, 0x00122a07, 0x00112a80, 0x00112b00, + 0x00112b02, 0x00122b80, 0x00112b8b, 0x00112b94, 0x00112b9c, 0x0040eee3, + 0x00200322, 0x00600006, 0x00200044, 0x00102c80, 0x0040df0f, 0x0040df4b, + 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x0040df8c, + 0x005000cb, 0x00000000, 0x00112cc6, 0x00152cc9, 0x00192cd0, 0x00122d00, + 0x00122d03, 0x00162e00, 0x00122e07, 0x00112e80, 0x00112f00, 0x00112f02, + 0x00122f80, 0x00112f8b, 0x00112f94, 0x00112f9c, 0x004101e4, 0x00200389, + 0x00600006, 0x00200044, 0x00103080, 0x001130c6, 0x001530c9, 0x001930d0, + 0x00123100, 0x00123103, 0x00163200, 0x00123207, 0x00113280, 0x00113300, + 0x00113302, 0x00123380, 0x0011338b, 0x00113394, 0x0011339c, 0x00411ee5, + 0x002003f0, 0x00600006, 0x00200044, 0x00103480, 0x00410f0f, 0x00410f4b, + 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x0070008f, 0x00410f8c, + 0x005000cb, 0x00000000, 0x001134c6, 0x001534c9, 0x001934d0, 0x00123500, + 0x00123503, 0x00163600, 0x00123607, 0x00113680, 0x00113700, 0x00113702, + 0x00123780, 0x0011378b, 0x00113794, 0x0011379c, 0x00000000, 0x0041250f, + 0x005000cb, 0x00214d40, 0x00600007, 0x0020043e, 0x008800ff, 0x005000cb, + 0x00412887, 0x0060000a, 0x00000000, 0x00413700, 0x007000a0, 0x00700080, + 0x00200480, 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, 0x005000cb, + 0x00700000, 0x00200000, 0x00600006, 0x00111bfe, 0x0041594d, 0x00700000, + 0x00200000, 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, 0x0040114d, + 0x00700081, 0x00600004, 0x0050004a, 0x00414388, 0x0060000b, 0x00200000, + 0x00600006, 0x00700000, 0x0041590b, 0x00111bfd, 0x0040424d, 0x00202916, + 0x008000fd, 0x005000cb, 0x00c00002, 0x00200480, 0x00600007, 0x00200160, + 0x00800002, 0x005000cb, 0x00c01802, 0x002027b6, 0x00800002, 0x005000cb, + 0x00404e4d, 0x0060000b, 0x0041574d, 0x00700001, 0x005000cf, 0x00700003, + 0x00415e06, 0x00415f05, 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, + 0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ~0 +}; + +static void +nv50_graph_init_ctxctl(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t *voodoo; + + DRM_DEBUG("\n"); + + switch (dev_priv->chipset) { + case 0x84: + voodoo = nv84_ctx_voodoo; + break; + default: + DRM_ERROR("no voodoo for chipset NV%02x\n", dev_priv->chipset); + break; + } + + if (voodoo) { + NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); + while (*voodoo != ~0) { + NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_DATA, *voodoo); + voodoo++; + } + } + + NV_WRITE(0x400320, 4); + NV_WRITE(NV40_PGRAPH_CTXCTL_CUR, 0); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, 0); +} + +int +nv50_graph_init(struct drm_device *dev) +{ + DRM_DEBUG("\n"); + + nv50_graph_init_reset(dev); + nv50_graph_init_intr(dev); + nv50_graph_init_regs__nv(dev); + nv50_graph_init_regs(dev); + nv50_graph_init_ctxctl(dev); + + return 0; +} + +void +nv50_graph_takedown(struct drm_device *dev) +{ + DRM_DEBUG("\n"); +} + +int +nv50_graph_create_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; + struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; + int grctx_size = 0x60000, hdr; + int ret; + + DRM_DEBUG("ch%d\n", chan->id); + + if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, + grctx_size, 0x1000, + NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ZERO_FREE, + &chan->ramin_grctx))) + return ret; + + hdr = IS_G80 ? 0x200 : 0x20; + INSTANCE_WR(ramin, (hdr + 0x00)/4, 0x00190002); + INSTANCE_WR(ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + + grctx_size - 1); + INSTANCE_WR(ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance); + INSTANCE_WR(ramin, (hdr + 0x0c)/4, 0); + INSTANCE_WR(ramin, (hdr + 0x10)/4, 0); + INSTANCE_WR(ramin, (hdr + 0x14)/4, 0x00010000); + + if ((ret = engine->graph.load_context(chan))) { + DRM_ERROR("Error hacking up initial context: %d\n", ret); + return ret; + } + + return 0; +} + +void +nv50_graph_destroy_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i, hdr; + + DRM_DEBUG("ch%d\n", chan->id); + + hdr = IS_G80 ? 0x200 : 0x20; + for (i=hdr; i<hdr+24; i+=4) + INSTANCE_WR(chan->ramin->gpuobj, i/4, 0); + + nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx); +} + +static int +nv50_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t old_cp, tv = 20000; + int i; + + DRM_DEBUG("inst=0x%08x, save=%d\n", inst, save); + + old_cp = NV_READ(NV20_PGRAPH_CHANNEL_CTX_POINTER); + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst | (1<<31)); + NV_WRITE(0x400824, NV_READ(0x400824) | + (save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE : + NV40_PGRAPH_CTXCTL_0310_XFER_LOAD)); + NV_WRITE(NV40_PGRAPH_CTXCTL_0304, NV40_PGRAPH_CTXCTL_0304_XFER_CTX); + + for (i = 0; i < tv; i++) { + if (NV_READ(NV40_PGRAPH_CTXCTL_030C) == 0) + break; + } + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, old_cp); + + if (i == tv) { + DRM_ERROR("failed: inst=0x%08x save=%d\n", inst, save); + DRM_ERROR("0x40030C = 0x%08x\n", + NV_READ(NV40_PGRAPH_CTXCTL_030C)); + return -EBUSY; + } + + return 0; +} + +int +nv50_graph_load_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t inst = ((chan->ramin->instance >> 12) | (1<<31)); + int ret; (void)ret; + + DRM_DEBUG("ch%d\n", chan->id); + +#if 0 + if ((ret = nv50_graph_transfer_context(dev, inst, 0))) + return ret; +#endif + + NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst); + NV_WRITE(0x400320, 4); + NV_WRITE(NV40_PGRAPH_CTXCTL_CUR, inst); + + return 0; +} + +int +nv50_graph_save_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + uint32_t inst = ((chan->ramin->instance >> 12) | (1<<31)); + + DRM_DEBUG("ch%d\n", chan->id); + + return nv50_graph_transfer_context(dev, inst, 1); +} + diff --git a/shared-core/nv50_instmem.c b/shared-core/nv50_instmem.c new file mode 100644 index 00000000..1eeb54df --- /dev/null +++ b/shared-core/nv50_instmem.c @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" + +typedef struct { + uint32_t save1700[5]; /* 0x1700->0x1710 */ + + struct nouveau_gpuobj_ref *pramin_pt; + struct nouveau_gpuobj_ref *pramin_bar; +} nv50_instmem_priv; + +#define NV50_INSTMEM_PAGE_SHIFT 12 +#define NV50_INSTMEM_PAGE_SIZE (1 << NV50_INSTMEM_PAGE_SHIFT) +#define NV50_INSTMEM_PT_SIZE(a) (((a) >> 12) << 3) + +/*NOTE: - Assumes 0x1700 already covers the correct MiB of PRAMIN + */ +#define BAR0_WI32(g,o,v) do { \ + uint32_t offset; \ + if ((g)->im_backing) { \ + offset = (g)->im_backing->start; \ + } else { \ + offset = chan->ramin->gpuobj->im_backing->start; \ + offset += (g)->im_pramin->start; \ + } \ + offset += (o); \ + NV_WRITE(NV_RAMIN + (offset & 0xfffff), (v)); \ +} while(0) + +int +nv50_instmem_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan; + uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size; + nv50_instmem_priv *priv; + int ret, i; + uint32_t v; + + priv = drm_calloc(1, sizeof(*priv), DRM_MEM_DRIVER); + if (!priv) + return -ENOMEM; + dev_priv->Engine.instmem.priv = priv; + + /* Reserve the last MiB of VRAM, we should probably try to avoid + * setting up the below tables over the top of the VBIOS image at + * some point. + */ + dev_priv->ramin_rsvd_vram = 1 << 20; + c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram; + c_size = 128 << 10; + c_vmpd = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200; + c_ramfc = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20; + c_base = c_vmpd + 0x4000; + pt_size = NV50_INSTMEM_PT_SIZE(dev_priv->ramin->size); + + DRM_DEBUG(" Rsvd VRAM base: 0x%08x\n", c_offset); + DRM_DEBUG(" VBIOS image: 0x%08x\n", (NV_READ(0x619f04)&~0xff)<<8); + DRM_DEBUG(" Aperture size: %d MiB\n", + (uint32_t)dev_priv->ramin->size >> 20); + DRM_DEBUG(" PT size: %d KiB\n", pt_size >> 10); + + NV_WRITE(NV50_PUNK_BAR0_PRAMIN, (c_offset >> 16)); + + /* Create a fake channel, and use it as our "dummy" channels 0/127. + * The main reason for creating a channel is so we can use the gpuobj + * code. However, it's probably worth noting that NVIDIA also setup + * their channels 0/127 with the same values they configure here. + * So, there may be some other reason for doing this. + * + * Have to create the entire channel manually, as the real channel + * creation code assumes we have PRAMIN access, and we don't until + * we're done here. + */ + chan = drm_calloc(1, sizeof(*chan), DRM_MEM_DRIVER); + if (!chan) + return -ENOMEM; + chan->id = 0; + chan->dev = dev; + chan->file_priv = (struct drm_file *)-2; + dev_priv->fifos[0] = dev_priv->fifos[127] = chan; + + /* Channel's PRAMIN object + heap */ + if ((ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, 128<<10, 0, + NULL, &chan->ramin))) + return ret; + + if (nouveau_mem_init_heap(&chan->ramin_heap, c_base, c_size - c_base)) + return -ENOMEM; + + /* RAMFC + zero channel's PRAMIN up to start of VM pagedir */ + if ((ret = nouveau_gpuobj_new_fake(dev, c_ramfc, c_offset + c_ramfc, + 0x4000, 0, NULL, &chan->ramfc))) + return ret; + + for (i = 0; i < c_vmpd; i += 4) + BAR0_WI32(chan->ramin->gpuobj, i, 0); + + /* VM page directory */ + if ((ret = nouveau_gpuobj_new_fake(dev, c_vmpd, c_offset + c_vmpd, + 0x4000, 0, &chan->vm_pd, NULL))) + return ret; + for (i = 0; i < 0x4000; i += 8) { + BAR0_WI32(chan->vm_pd, i + 0x00, 0x00000000); + BAR0_WI32(chan->vm_pd, i + 0x04, 0x00000000); + } + + /* PRAMIN page table, cheat and map into VM at 0x0000000000. + * We map the entire fake channel into the start of the PRAMIN BAR + */ + if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000, + 0, &priv->pramin_pt))) + return ret; + + for (i = 0, v = c_offset; i < pt_size; i+=8, v+=0x1000) { + if (v < (c_offset + c_size)) + BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v | 1); + else + BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000009); + BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); + } + + BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63); + BAR0_WI32(chan->vm_pd, 0x04, 0x00000000); + + /* DMA object for PRAMIN BAR */ + if ((ret = nouveau_gpuobj_new_ref(dev, chan, chan, 0, 6*4, 16, 0, + &priv->pramin_bar))) + return ret; + BAR0_WI32(priv->pramin_bar->gpuobj, 0x00, 0x7fc00000); + BAR0_WI32(priv->pramin_bar->gpuobj, 0x04, dev_priv->ramin->size - 1); + BAR0_WI32(priv->pramin_bar->gpuobj, 0x08, 0x00000000); + BAR0_WI32(priv->pramin_bar->gpuobj, 0x0c, 0x00000000); + BAR0_WI32(priv->pramin_bar->gpuobj, 0x10, 0x00000000); + BAR0_WI32(priv->pramin_bar->gpuobj, 0x14, 0x00000000); + + /* Poke the relevant regs, and pray it works :) */ + NV_WRITE(NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12)); + NV_WRITE(NV50_PUNK_UNK1710, 0); + NV_WRITE(NV50_PUNK_BAR_CFG_BASE, (chan->ramin->instance >> 12) | + NV50_PUNK_BAR_CFG_BASE_VALID); + NV_WRITE(NV50_PUNK_BAR1_CTXDMA, 0); + NV_WRITE(NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->instance >> 4) | + NV50_PUNK_BAR3_CTXDMA_VALID); + + /* Assume that praying isn't enough, check that we can re-read the + * entire fake channel back from the PRAMIN BAR */ + for (i = 0; i < c_size; i+=4) { + if (NV_READ(NV_RAMIN + i) != NV_RI32(i)) { + DRM_ERROR("Error reading back PRAMIN at 0x%08x\n", i); + return -EINVAL; + } + } + + /* Global PRAMIN heap */ + if (nouveau_mem_init_heap(&dev_priv->ramin_heap, + c_size, dev_priv->ramin->size - c_size)) { + dev_priv->ramin_heap = NULL; + DRM_ERROR("Failed to init RAMIN heap\n"); + } + + /*XXX: incorrect, but needed to make hash func "work" */ + dev_priv->ramht_offset = 0x10000; + dev_priv->ramht_bits = 9; + dev_priv->ramht_size = (1 << dev_priv->ramht_bits); + return 0; +} + +void +nv50_instmem_takedown(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + nv50_instmem_priv *priv = dev_priv->Engine.instmem.priv; + struct nouveau_channel *chan = dev_priv->fifos[0]; + int i; + + DRM_DEBUG("\n"); + + if (!priv) + return; + + /* Restore state from before init */ + for (i = 0x1700; i <= 0x1710; i+=4) + NV_WRITE(i, priv->save1700[(i-0x1700)/4]); + + nouveau_gpuobj_ref_del(dev, &priv->pramin_bar); + nouveau_gpuobj_ref_del(dev, &priv->pramin_pt); + + /* Destroy dummy channel */ + if (chan) { + nouveau_gpuobj_del(dev, &chan->vm_pd); + nouveau_gpuobj_ref_del(dev, &chan->ramfc); + nouveau_gpuobj_ref_del(dev, &chan->ramin); + nouveau_mem_takedown(&chan->ramin_heap); + + dev_priv->fifos[0] = dev_priv->fifos[127] = NULL; + drm_free(chan, sizeof(*chan), DRM_MEM_DRIVER); + } + + dev_priv->Engine.instmem.priv = NULL; + drm_free(priv, sizeof(*priv), DRM_MEM_DRIVER); +} + +int +nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, uint32_t *sz) +{ + if (gpuobj->im_backing) + return -EINVAL; + + *sz = (*sz + (NV50_INSTMEM_PAGE_SIZE-1)) & ~(NV50_INSTMEM_PAGE_SIZE-1); + if (*sz == 0) + return -EINVAL; + + gpuobj->im_backing = nouveau_mem_alloc(dev, NV50_INSTMEM_PAGE_SIZE, + *sz, NOUVEAU_MEM_FB, + (struct drm_file *)-2); + if (!gpuobj->im_backing) { + DRM_ERROR("Couldn't allocate vram to back PRAMIN pages\n"); + return -ENOMEM; + } + + return 0; +} + +void +nv50_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (gpuobj && gpuobj->im_backing) { + if (gpuobj->im_bound) + dev_priv->Engine.instmem.unbind(dev, gpuobj); + nouveau_mem_free(dev, gpuobj->im_backing); + gpuobj->im_backing = NULL; + } +} + +int +nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + nv50_instmem_priv *priv = dev_priv->Engine.instmem.priv; + uint32_t pte, pte_end, vram; + + if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) + return -EINVAL; + + DRM_DEBUG("st=0x%0llx sz=0x%0llx\n", + gpuobj->im_pramin->start, gpuobj->im_pramin->size); + + pte = (gpuobj->im_pramin->start >> 12) << 3; + pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; + vram = gpuobj->im_backing->start; + + DRM_DEBUG("pramin=0x%llx, pte=%d, pte_end=%d\n", + gpuobj->im_pramin->start, pte, pte_end); + DRM_DEBUG("first vram page: 0x%llx\n", + gpuobj->im_backing->start); + + while (pte < pte_end) { + INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 0)/4, vram | 1); + INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); + + pte += 8; + vram += NV50_INSTMEM_PAGE_SIZE; + } + + gpuobj->im_bound = 1; + return 0; +} + +int +nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + nv50_instmem_priv *priv = dev_priv->Engine.instmem.priv; + uint32_t pte, pte_end; + + if (gpuobj->im_bound == 0) + return -EINVAL; + + pte = (gpuobj->im_pramin->start >> 12) << 3; + pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; + while (pte < pte_end) { + INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 0)/4, 0x00000009); + INSTANCE_WR(priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); + pte += 8; + } + + gpuobj->im_bound = 0; + return 0; +} + diff --git a/shared-core/nv50_mc.c b/shared-core/nv50_mc.c new file mode 100644 index 00000000..b111826b --- /dev/null +++ b/shared-core/nv50_mc.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" + +int +nv50_mc_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + NV_WRITE(NV03_PMC_ENABLE, 0xFFFFFFFF); + + return 0; +} + +void nv50_mc_takedown(struct drm_device *dev) +{ +} diff --git a/shared-core/r128_cce.c b/shared-core/r128_cce.c index a2ee18b7..5bed45bc 100644 --- a/shared-core/r128_cce.c +++ b/shared-core/r128_cce.c @@ -81,7 +81,7 @@ static u32 r128_cce_microcode[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static int R128_READ_PLL(drm_device_t * dev, int addr) +static int R128_READ_PLL(struct drm_device * dev, int addr) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -129,7 +129,7 @@ static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv) #if R128_FIFO_DEBUG DRM_ERROR("failed!\n"); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries) @@ -146,7 +146,7 @@ static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries) #if R128_FIFO_DEBUG DRM_ERROR("failed!\n"); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv) @@ -168,7 +168,7 @@ static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv) #if R128_FIFO_DEBUG DRM_ERROR("failed!\n"); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } /* ================================================================ @@ -227,7 +227,7 @@ int r128_do_cce_idle(drm_r128_private_t * dev_priv) DRM_ERROR("failed!\n"); r128_status(dev_priv); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } /* Start the Concurrent Command Engine. @@ -271,7 +271,7 @@ static void r128_do_cce_stop(drm_r128_private_t * dev_priv) /* Reset the engine. This will stop the CCE if it is running. */ -static int r128_do_engine_reset(drm_device_t * dev) +static int r128_do_engine_reset(struct drm_device * dev) { drm_r128_private_t *dev_priv = dev->dev_private; u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; @@ -308,7 +308,7 @@ static int r128_do_engine_reset(drm_device_t * dev) return 0; } -static void r128_cce_init_ring_buffer(drm_device_t * dev, +static void r128_cce_init_ring_buffer(struct drm_device * dev, drm_r128_private_t * dev_priv) { u32 ring_start; @@ -347,7 +347,7 @@ static void r128_cce_init_ring_buffer(drm_device_t * dev, R128_WRITE(R128_BUS_CNTL, tmp); } -static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) +static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) { drm_r128_private_t *dev_priv; @@ -355,7 +355,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; memset(dev_priv, 0, sizeof(drm_r128_private_t)); @@ -365,7 +365,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) DRM_ERROR("PCI GART memory not allocated!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->usec_timeout = init->usec_timeout; @@ -374,7 +374,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) DRM_DEBUG("TIMEOUT problem!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->cce_mode = init->cce_mode; @@ -394,7 +394,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) DRM_DEBUG("Bad cce_mode!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } switch (init->cce_mode) { @@ -461,7 +461,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) DRM_ERROR("could not find sarea!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); @@ -469,21 +469,21 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) DRM_ERROR("could not find mmio region!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->cce_ring = drm_core_findmap(dev, init->ring_offset); if (!dev_priv->cce_ring) { DRM_ERROR("could not find cce ring region!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); if (!dev_priv->ring_rptr) { DRM_ERROR("could not find ring read pointer!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); @@ -491,7 +491,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) DRM_ERROR("could not find dma buffer region!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } if (!dev_priv->is_pci) { @@ -501,7 +501,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) DRM_ERROR("could not find agp texture region!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } } @@ -520,7 +520,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) DRM_ERROR("Could not ioremap agp regions!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return DRM_ERR(ENOMEM); + return -ENOMEM; } } else #endif @@ -567,7 +567,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) DRM_ERROR("failed to init PCI GART!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return DRM_ERR(ENOMEM); + return -ENOMEM; } R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr); #if __OS_HAS_AGP @@ -584,7 +584,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) return 0; } -int r128_do_cleanup_cce(drm_device_t * dev) +int r128_do_cleanup_cce(struct drm_device * dev) { /* Make sure interrupts are disabled here because the uninstall ioctl @@ -623,35 +623,30 @@ int r128_do_cleanup_cce(drm_device_t * dev) return 0; } -int r128_cce_init(DRM_IOCTL_ARGS) +int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_r128_init_t init; + drm_r128_init_t *init = data; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_COPY_FROM_USER_IOCTL(init, (drm_r128_init_t __user *) data, - sizeof(init)); - - switch (init.func) { + switch (init->func) { case R128_INIT_CCE: - return r128_do_init_cce(dev, &init); + return r128_do_init_cce(dev, init); case R128_CLEANUP_CCE: return r128_do_cleanup_cce(dev); } - return DRM_ERR(EINVAL); + return -EINVAL; } -int r128_cce_start(DRM_IOCTL_ARGS) +int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) { DRM_DEBUG("%s while CCE running\n", __FUNCTION__); @@ -666,30 +661,26 @@ int r128_cce_start(DRM_IOCTL_ARGS) /* Stop the CCE. The engine must have been idled before calling this * routine. */ -int r128_cce_stop(DRM_IOCTL_ARGS) +int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_cce_stop_t stop; + drm_r128_cce_stop_t *stop = data; int ret; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t __user *) data, - sizeof(stop)); + LOCK_TEST_WITH_RETURN(dev, file_priv); /* Flush any pending CCE commands. This ensures any outstanding * commands are exectuted by the engine before we turn it off. */ - if (stop.flush) { + if (stop->flush) { r128_do_cce_flush(dev_priv); } /* If we fail to make the engine go idle, we return an error * code so that the DRM ioctl wrapper can try again. */ - if (stop.idle) { + if (stop->idle) { ret = r128_do_cce_idle(dev_priv); if (ret) return ret; @@ -709,17 +700,16 @@ int r128_cce_stop(DRM_IOCTL_ARGS) /* Just reset the CCE ring. Called as part of an X Server engine reset. */ -int r128_cce_reset(DRM_IOCTL_ARGS) +int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_DEBUG("%s called before init done\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } r128_do_cce_reset(dev_priv); @@ -730,13 +720,12 @@ int r128_cce_reset(DRM_IOCTL_ARGS) return 0; } -int r128_cce_idle(DRM_IOCTL_ARGS) +int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (dev_priv->cce_running) { r128_do_cce_flush(dev_priv); @@ -745,19 +734,18 @@ int r128_cce_idle(DRM_IOCTL_ARGS) return r128_do_cce_idle(dev_priv); } -int r128_engine_reset(DRM_IOCTL_ARGS) +int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); return r128_do_engine_reset(dev); } -int r128_fullscreen(DRM_IOCTL_ARGS) +int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv) { - return DRM_ERR(EINVAL); + return -EINVAL; } /* ================================================================ @@ -767,18 +755,18 @@ int r128_fullscreen(DRM_IOCTL_ARGS) #define R128_BUFFER_FREE 0 #if 0 -static int r128_freelist_init(drm_device_t * dev) +static int r128_freelist_init(struct drm_device * dev) { - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; drm_r128_private_t *dev_priv = dev->dev_private; - drm_buf_t *buf; + struct drm_buf *buf; drm_r128_buf_priv_t *buf_priv; drm_r128_freelist_t *entry; int i; dev_priv->head = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER); if (dev_priv->head == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; memset(dev_priv->head, 0, sizeof(drm_r128_freelist_t)); dev_priv->head->age = R128_BUFFER_USED; @@ -789,7 +777,7 @@ static int r128_freelist_init(drm_device_t * dev) entry = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER); if (!entry) - return DRM_ERR(ENOMEM); + return -ENOMEM; entry->age = R128_BUFFER_FREE; entry->buf = buf; @@ -813,12 +801,12 @@ static int r128_freelist_init(drm_device_t * dev) } #endif -static drm_buf_t *r128_freelist_get(drm_device_t * dev) +static struct drm_buf *r128_freelist_get(struct drm_device * dev) { - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_buf_priv_t *buf_priv; - drm_buf_t *buf; + struct drm_buf *buf; int i, t; /* FIXME: Optimize -- use freelist code */ @@ -826,7 +814,7 @@ static drm_buf_t *r128_freelist_get(drm_device_t * dev) for (i = 0; i < dma->buf_count; i++) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if (buf->filp == 0) + if (buf->file_priv == 0) return buf; } @@ -851,13 +839,13 @@ static drm_buf_t *r128_freelist_get(drm_device_t * dev) return NULL; } -void r128_freelist_reset(drm_device_t * dev) +void r128_freelist_reset(struct drm_device * dev) { - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; int i; for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[i]; + struct drm_buf *buf = dma->buflist[i]; drm_r128_buf_priv_t *buf_priv = buf->dev_private; buf_priv->age = 0; } @@ -881,68 +869,64 @@ int r128_wait_ring(drm_r128_private_t * dev_priv, int n) /* FIXME: This is being ignored... */ DRM_ERROR("failed!\n"); - return DRM_ERR(EBUSY); + return -EBUSY; } -static int r128_cce_get_buffers(DRMFILE filp, drm_device_t * dev, drm_dma_t * d) +static int r128_cce_get_buffers(struct drm_device * dev, + struct drm_file *file_priv, + struct drm_dma * d) { int i; - drm_buf_t *buf; + struct drm_buf *buf; for (i = d->granted_count; i < d->request_count; i++) { buf = r128_freelist_get(dev); if (!buf) - return DRM_ERR(EAGAIN); + return -EAGAIN; - buf->filp = filp; + buf->file_priv = file_priv; if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, sizeof(buf->idx))) - return DRM_ERR(EFAULT); + return -EFAULT; if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, sizeof(buf->total))) - return DRM_ERR(EFAULT); + return -EFAULT; d->granted_count++; } return 0; } -int r128_cce_buffers(DRM_IOCTL_ARGS) +int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; int ret = 0; - drm_dma_t __user *argp = (void __user *)data; - drm_dma_t d; + struct drm_dma *d = data; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d)); + LOCK_TEST_WITH_RETURN(dev, file_priv); /* Please don't send us buffers. */ - if (d.send_count != 0) { + if (d->send_count != 0) { DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d.send_count); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, d->send_count); + return -EINVAL; } /* We'll send you buffers. */ - if (d.request_count < 0 || d.request_count > dma->buf_count) { + if (d->request_count < 0 || d->request_count > dma->buf_count) { DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d.request_count, dma->buf_count); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, d->request_count, dma->buf_count); + return -EINVAL; } - d.granted_count = 0; + d->granted_count = 0; - if (d.request_count) { - ret = r128_cce_get_buffers(filp, dev, &d); + if (d->request_count) { + ret = r128_cce_get_buffers(dev, file_priv, d); } - DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d)); - return ret; } diff --git a/shared-core/r128_drm.h b/shared-core/r128_drm.h index 6e8af313..8d8878b5 100644 --- a/shared-core/r128_drm.h +++ b/shared-core/r128_drm.h @@ -153,7 +153,7 @@ typedef struct drm_r128_sarea { /* The current cliprects, or a subset thereof. */ - drm_clip_rect_t boxes[R128_NR_SAREA_CLIPRECTS]; + struct drm_clip_rect boxes[R128_NR_SAREA_CLIPRECTS]; unsigned int nbox; /* Counters for client-side throttling of rendering clients. @@ -161,7 +161,7 @@ typedef struct drm_r128_sarea { unsigned int last_frame; unsigned int last_dispatch; - drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS + 1]; + struct drm_tex_region tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS + 1]; unsigned int tex_age[R128_NR_TEX_HEAPS]; int ctx_owner; int pfAllowPageFlip; /* number of 3d windows (0,1,2 or more) */ @@ -222,11 +222,7 @@ typedef struct drm_r128_init { R128_INIT_CCE = 0x01, R128_CLEANUP_CCE = 0x02 } func; -#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0) - int sarea_priv_offset; -#else unsigned long sarea_priv_offset; -#endif int is_pci; int cce_mode; int cce_secure; @@ -240,21 +236,12 @@ typedef struct drm_r128_init { unsigned int depth_offset, depth_pitch; unsigned int span_offset; -#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0) - unsigned int fb_offset; - unsigned int mmio_offset; - unsigned int ring_offset; - unsigned int ring_rptr_offset; - unsigned int buffers_offset; - unsigned int agp_textures_offset; -#else unsigned long fb_offset; unsigned long mmio_offset; unsigned long ring_offset; unsigned long ring_rptr_offset; unsigned long buffers_offset; unsigned long agp_textures_offset; -#endif } drm_r128_init_t; typedef struct drm_r128_cce_stop { @@ -264,15 +251,10 @@ typedef struct drm_r128_cce_stop { typedef struct drm_r128_clear { unsigned int flags; -#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0) - int x, y, w, h; -#endif unsigned int clear_color; unsigned int clear_depth; -#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0) unsigned int color_mask; unsigned int depth_mask; -#endif } drm_r128_clear_t; typedef struct drm_r128_vertex { diff --git a/shared-core/r128_drv.h b/shared-core/r128_drv.h index 90868356..cb0c41cb 100644 --- a/shared-core/r128_drv.h +++ b/shared-core/r128_drv.h @@ -57,7 +57,7 @@ typedef struct drm_r128_freelist { unsigned int age; - drm_buf_t *buf; + struct drm_buf *buf; struct drm_r128_freelist *next; struct drm_r128_freelist *prev; } drm_r128_freelist_t; @@ -97,6 +97,8 @@ typedef struct drm_r128_private { u32 crtc_offset; u32 crtc_offset_cntl; + atomic_t vbl_received; + u32 color_fmt; unsigned int front_offset; unsigned int front_pitch; @@ -118,7 +120,7 @@ typedef struct drm_r128_private { drm_local_map_t *cce_ring; drm_local_map_t *ring_rptr; drm_local_map_t *agp_textures; - drm_ati_pcigart_info gart_info; + struct ati_pcigart_info gart_info; } drm_r128_private_t; typedef struct drm_r128_buf_priv { @@ -129,34 +131,36 @@ typedef struct drm_r128_buf_priv { drm_r128_freelist_t *list_entry; } drm_r128_buf_priv_t; -extern drm_ioctl_desc_t r128_ioctls[]; +extern struct drm_ioctl_desc r128_ioctls[]; extern int r128_max_ioctl; /* r128_cce.c */ -extern int r128_cce_init(DRM_IOCTL_ARGS); -extern int r128_cce_start(DRM_IOCTL_ARGS); -extern int r128_cce_stop(DRM_IOCTL_ARGS); -extern int r128_cce_reset(DRM_IOCTL_ARGS); -extern int r128_cce_idle(DRM_IOCTL_ARGS); -extern int r128_engine_reset(DRM_IOCTL_ARGS); -extern int r128_fullscreen(DRM_IOCTL_ARGS); -extern int r128_cce_buffers(DRM_IOCTL_ARGS); +extern int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void r128_freelist_reset(drm_device_t * dev); +extern void r128_freelist_reset(struct drm_device * dev); extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); -extern int r128_do_cleanup_cce(drm_device_t * dev); - -extern int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence); +extern int r128_do_cleanup_cce(struct drm_device * dev); +extern int r128_enable_vblank(struct drm_device *dev, int crtc); +extern void r128_disable_vblank(struct drm_device *dev, int crtc); +extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); -extern void r128_driver_irq_preinstall(drm_device_t * dev); -extern void r128_driver_irq_postinstall(drm_device_t * dev); -extern void r128_driver_irq_uninstall(drm_device_t * dev); -extern void r128_driver_lastclose(drm_device_t * dev); -extern void r128_driver_preclose(drm_device_t * dev, DRMFILE filp); +extern void r128_driver_irq_preinstall(struct drm_device * dev); +extern int r128_driver_irq_postinstall(struct drm_device * dev); +extern void r128_driver_irq_uninstall(struct drm_device * dev); +extern void r128_driver_lastclose(struct drm_device * dev); +extern void r128_driver_preclose(struct drm_device * dev, + struct drm_file *file_priv); extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); @@ -428,7 +432,7 @@ do { \ DRM_UDELAY(1); \ } \ DRM_ERROR( "ring space check failed!\n" ); \ - return DRM_ERR(EBUSY); \ + return -EBUSY; \ } \ __ring_space_done: \ ; \ diff --git a/shared-core/r128_irq.c b/shared-core/r128_irq.c index 87f8ca2b..5b95bd89 100644 --- a/shared-core/r128_irq.c +++ b/shared-core/r128_irq.c @@ -35,9 +35,19 @@ #include "r128_drm.h" #include "r128_drv.h" +u32 r128_get_vblank_counter(struct drm_device *dev, int crtc) +{ + const drm_r128_private_t *dev_priv = dev->dev_private; + + if (crtc != 0) + return 0; + + return atomic_read(&dev_priv->vbl_received); +} + irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) { - drm_device_t *dev = (drm_device_t *) arg; + struct drm_device *dev = (struct drm_device *) arg; drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; int status; @@ -46,33 +56,41 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) /* VBLANK interrupt */ if (status & R128_CRTC_VBLANK_INT) { R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); - atomic_inc(&dev->vbl_received); - DRM_WAKEUP(&dev->vbl_queue); - drm_vbl_send_signals(dev); + atomic_inc(&dev_priv->vbl_received); + drm_handle_vblank(dev, 0); return IRQ_HANDLED; } return IRQ_NONE; } -int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) +int r128_enable_vblank(struct drm_device *dev, int crtc) { - unsigned int cur_vblank; - int ret = 0; + drm_r128_private_t *dev_priv = dev->dev_private; - /* Assume that the user has missed the current sequence number - * by about a day rather than she wants to wait for years - * using vertical blanks... - */ - DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(&dev->vbl_received)) - - *sequence) <= (1 << 23))); + if (crtc != 0) { + DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); + return -EINVAL; + } - *sequence = cur_vblank; + R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); + return 0; +} + +void r128_disable_vblank(struct drm_device *dev, int crtc) +{ + if (crtc != 0) + DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); - return ret; + /* + * FIXME: implement proper interrupt disable by using the vblank + * counter register (if available) + * + * R128_WRITE(R128_GEN_INT_CNTL, + * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN); + */ } -void r128_driver_irq_preinstall(drm_device_t * dev) +void r128_driver_irq_preinstall(struct drm_device * dev) { drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; @@ -82,15 +100,12 @@ void r128_driver_irq_preinstall(drm_device_t * dev) R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); } -void r128_driver_irq_postinstall(drm_device_t * dev) +int r128_driver_irq_postinstall(struct drm_device * dev) { - drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; - - /* Turn on VBL interrupt */ - R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); + return drm_vblank_init(dev, 1); } -void r128_driver_irq_uninstall(drm_device_t * dev) +void r128_driver_irq_uninstall(struct drm_device * dev) { drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; if (!dev_priv) diff --git a/shared-core/r128_state.c b/shared-core/r128_state.c index 17b11e7d..b7f483ca 100644 --- a/shared-core/r128_state.c +++ b/shared-core/r128_state.c @@ -38,7 +38,7 @@ */ static void r128_emit_clip_rects(drm_r128_private_t * dev_priv, - drm_clip_rect_t * boxes, int count) + struct drm_clip_rect * boxes, int count) { u32 aux_sc_cntl = 0x00000000; RING_LOCALS; @@ -352,13 +352,13 @@ static void r128_print_dirty(const char *msg, unsigned int flags) (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : ""); } -static void r128_cce_dispatch_clear(drm_device_t * dev, +static void r128_cce_dispatch_clear(struct drm_device * dev, drm_r128_clear_t * clear) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; - drm_clip_rect_t *pbox = sarea_priv->boxes; + struct drm_clip_rect *pbox = sarea_priv->boxes; unsigned int flags = clear->flags; int i; RING_LOCALS; @@ -458,12 +458,12 @@ static void r128_cce_dispatch_clear(drm_device_t * dev, } } -static void r128_cce_dispatch_swap(drm_device_t * dev) +static void r128_cce_dispatch_swap(struct drm_device * dev) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; - drm_clip_rect_t *pbox = sarea_priv->boxes; + struct drm_clip_rect *pbox = sarea_priv->boxes; int i; RING_LOCALS; DRM_DEBUG("%s\n", __FUNCTION__); @@ -524,7 +524,7 @@ static void r128_cce_dispatch_swap(drm_device_t * dev) ADVANCE_RING(); } -static void r128_cce_dispatch_flip(drm_device_t * dev) +static void r128_cce_dispatch_flip(struct drm_device * dev) { drm_r128_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -567,7 +567,7 @@ static void r128_cce_dispatch_flip(drm_device_t * dev) ADVANCE_RING(); } -static void r128_cce_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf) +static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_buf_priv_t *buf_priv = buf->dev_private; @@ -637,8 +637,8 @@ static void r128_cce_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf) sarea_priv->nbox = 0; } -static void r128_cce_dispatch_indirect(drm_device_t * dev, - drm_buf_t * buf, int start, int end) +static void r128_cce_dispatch_indirect(struct drm_device * dev, + struct drm_buf * buf, int start, int end) { drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_buf_priv_t *buf_priv = buf->dev_private; @@ -692,8 +692,8 @@ static void r128_cce_dispatch_indirect(drm_device_t * dev, dev_priv->sarea_priv->last_dispatch++; } -static void r128_cce_dispatch_indices(drm_device_t * dev, - drm_buf_t * buf, +static void r128_cce_dispatch_indices(struct drm_device * dev, + struct drm_buf * buf, int start, int end, int count) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -776,12 +776,13 @@ static void r128_cce_dispatch_indices(drm_device_t * dev, sarea_priv->nbox = 0; } -static int r128_cce_dispatch_blit(DRMFILE filp, - drm_device_t * dev, drm_r128_blit_t * blit) +static int r128_cce_dispatch_blit(struct drm_device * dev, + struct drm_file *file_priv, + drm_r128_blit_t * blit) { drm_r128_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; drm_r128_buf_priv_t *buf_priv; u32 *data; int dword_shift, dwords; @@ -809,7 +810,7 @@ static int r128_cce_dispatch_blit(DRMFILE filp, break; default: DRM_ERROR("invalid blit format %d\n", blit->format); - return DRM_ERR(EINVAL); + return -EINVAL; } /* Flush the pixel cache, and mark the contents as Read Invalid. @@ -829,14 +830,14 @@ static int r128_cce_dispatch_blit(DRMFILE filp, buf = dma->buflist[blit->idx]; buf_priv = buf->dev_private; - if (buf->filp != filp) { + if (buf->file_priv != file_priv) { DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, buf->file_priv); + return -EINVAL; } if (buf->pending) { DRM_ERROR("sending pending buffer %d\n", blit->idx); - return DRM_ERR(EINVAL); + return -EINVAL; } buf_priv->discard = 1; @@ -887,7 +888,7 @@ static int r128_cce_dispatch_blit(DRMFILE filp, * have hardware stencil support. */ -static int r128_cce_dispatch_write_span(drm_device_t * dev, +static int r128_cce_dispatch_write_span(struct drm_device * dev, drm_r128_depth_t * depth) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -900,22 +901,22 @@ static int r128_cce_dispatch_write_span(drm_device_t * dev, count = depth->n; if (count > 4096 || count <= 0) - return DRM_ERR(EMSGSIZE); + return -EMSGSIZE; if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) { - return DRM_ERR(EFAULT); + return -EFAULT; } if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) { - return DRM_ERR(EFAULT); + return -EFAULT; } buffer_size = depth->n * sizeof(u32); buffer = drm_alloc(buffer_size, DRM_MEM_BUFS); if (buffer == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { drm_free(buffer, buffer_size, DRM_MEM_BUFS); - return DRM_ERR(EFAULT); + return -EFAULT; } mask_size = depth->n * sizeof(u8); @@ -923,12 +924,12 @@ static int r128_cce_dispatch_write_span(drm_device_t * dev, mask = drm_alloc(mask_size, DRM_MEM_BUFS); if (mask == NULL) { drm_free(buffer, buffer_size, DRM_MEM_BUFS); - return DRM_ERR(ENOMEM); + return -ENOMEM; } if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { drm_free(buffer, buffer_size, DRM_MEM_BUFS); drm_free(mask, mask_size, DRM_MEM_BUFS); - return DRM_ERR(EFAULT); + return -EFAULT; } for (i = 0; i < count; i++, x++) { @@ -983,7 +984,7 @@ static int r128_cce_dispatch_write_span(drm_device_t * dev, return 0; } -static int r128_cce_dispatch_write_pixels(drm_device_t * dev, +static int r128_cce_dispatch_write_pixels(struct drm_device * dev, drm_r128_depth_t * depth) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -996,28 +997,28 @@ static int r128_cce_dispatch_write_pixels(drm_device_t * dev, count = depth->n; if (count > 4096 || count <= 0) - return DRM_ERR(EMSGSIZE); + return -EMSGSIZE; xbuf_size = count * sizeof(*x); ybuf_size = count * sizeof(*y); x = drm_alloc(xbuf_size, DRM_MEM_BUFS); if (x == NULL) { - return DRM_ERR(ENOMEM); + return -ENOMEM; } y = drm_alloc(ybuf_size, DRM_MEM_BUFS); if (y == NULL) { drm_free(x, xbuf_size, DRM_MEM_BUFS); - return DRM_ERR(ENOMEM); + return -ENOMEM; } if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { drm_free(x, xbuf_size, DRM_MEM_BUFS); drm_free(y, ybuf_size, DRM_MEM_BUFS); - return DRM_ERR(EFAULT); + return -EFAULT; } if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) { drm_free(x, xbuf_size, DRM_MEM_BUFS); drm_free(y, ybuf_size, DRM_MEM_BUFS); - return DRM_ERR(EFAULT); + return -EFAULT; } buffer_size = depth->n * sizeof(u32); @@ -1025,13 +1026,13 @@ static int r128_cce_dispatch_write_pixels(drm_device_t * dev, if (buffer == NULL) { drm_free(x, xbuf_size, DRM_MEM_BUFS); drm_free(y, ybuf_size, DRM_MEM_BUFS); - return DRM_ERR(ENOMEM); + return -ENOMEM; } if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { drm_free(x, xbuf_size, DRM_MEM_BUFS); drm_free(y, ybuf_size, DRM_MEM_BUFS); drm_free(buffer, buffer_size, DRM_MEM_BUFS); - return DRM_ERR(EFAULT); + return -EFAULT; } if (depth->mask) { @@ -1041,14 +1042,14 @@ static int r128_cce_dispatch_write_pixels(drm_device_t * dev, drm_free(x, xbuf_size, DRM_MEM_BUFS); drm_free(y, ybuf_size, DRM_MEM_BUFS); drm_free(buffer, buffer_size, DRM_MEM_BUFS); - return DRM_ERR(ENOMEM); + return -ENOMEM; } if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { drm_free(x, xbuf_size, DRM_MEM_BUFS); drm_free(y, ybuf_size, DRM_MEM_BUFS); drm_free(buffer, buffer_size, DRM_MEM_BUFS); drm_free(mask, mask_size, DRM_MEM_BUFS); - return DRM_ERR(EFAULT); + return -EFAULT; } for (i = 0; i < count; i++) { @@ -1105,7 +1106,7 @@ static int r128_cce_dispatch_write_pixels(drm_device_t * dev, return 0; } -static int r128_cce_dispatch_read_span(drm_device_t * dev, +static int r128_cce_dispatch_read_span(struct drm_device * dev, drm_r128_depth_t * depth) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -1115,13 +1116,13 @@ static int r128_cce_dispatch_read_span(drm_device_t * dev, count = depth->n; if (count > 4096 || count <= 0) - return DRM_ERR(EMSGSIZE); + return -EMSGSIZE; if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) { - return DRM_ERR(EFAULT); + return -EFAULT; } if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) { - return DRM_ERR(EFAULT); + return -EFAULT; } BEGIN_RING(7); @@ -1148,7 +1149,7 @@ static int r128_cce_dispatch_read_span(drm_device_t * dev, return 0; } -static int r128_cce_dispatch_read_pixels(drm_device_t * dev, +static int r128_cce_dispatch_read_pixels(struct drm_device * dev, drm_r128_depth_t * depth) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -1159,7 +1160,7 @@ static int r128_cce_dispatch_read_pixels(drm_device_t * dev, count = depth->n; if (count > 4096 || count <= 0) - return DRM_ERR(EMSGSIZE); + return -EMSGSIZE; if (count > dev_priv->depth_pitch) { count = dev_priv->depth_pitch; @@ -1169,22 +1170,22 @@ static int r128_cce_dispatch_read_pixels(drm_device_t * dev, ybuf_size = count * sizeof(*y); x = drm_alloc(xbuf_size, DRM_MEM_BUFS); if (x == NULL) { - return DRM_ERR(ENOMEM); + return -ENOMEM; } y = drm_alloc(ybuf_size, DRM_MEM_BUFS); if (y == NULL) { drm_free(x, xbuf_size, DRM_MEM_BUFS); - return DRM_ERR(ENOMEM); + return -ENOMEM; } if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { drm_free(x, xbuf_size, DRM_MEM_BUFS); drm_free(y, ybuf_size, DRM_MEM_BUFS); - return DRM_ERR(EFAULT); + return -EFAULT; } if (DRM_COPY_FROM_USER(y, depth->y, ybuf_size)) { drm_free(x, xbuf_size, DRM_MEM_BUFS); drm_free(y, ybuf_size, DRM_MEM_BUFS); - return DRM_ERR(EFAULT); + return -EFAULT; } for (i = 0; i < count; i++) { @@ -1220,7 +1221,7 @@ static int r128_cce_dispatch_read_pixels(drm_device_t * dev, * Polygon stipple */ -static void r128_cce_dispatch_stipple(drm_device_t * dev, u32 * stipple) +static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple) { drm_r128_private_t *dev_priv = dev->dev_private; int i; @@ -1241,25 +1242,21 @@ static void r128_cce_dispatch_stipple(drm_device_t * dev, u32 * stipple) * IOCTL functions */ -static int r128_cce_clear(DRM_IOCTL_ARGS) +static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_clear_t clear; + drm_r128_clear_t *clear = data; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(clear, (drm_r128_clear_t __user *) data, - sizeof(clear)); + LOCK_TEST_WITH_RETURN(dev, file_priv); RING_SPACE_TEST_WITH_RETURN(dev_priv); if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; - r128_cce_dispatch_clear(dev, &clear); + r128_cce_dispatch_clear(dev, clear); COMMIT_RING(); /* Make sure we restore the 3D state next time. @@ -1269,7 +1266,7 @@ static int r128_cce_clear(DRM_IOCTL_ARGS) return 0; } -static int r128_do_init_pageflip(drm_device_t * dev) +static int r128_do_init_pageflip(struct drm_device * dev) { drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); @@ -1288,7 +1285,7 @@ static int r128_do_init_pageflip(drm_device_t * dev) return 0; } -static int r128_do_cleanup_pageflip(drm_device_t * dev) +static int r128_do_cleanup_pageflip(struct drm_device * dev) { drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); @@ -1309,13 +1306,12 @@ static int r128_do_cleanup_pageflip(drm_device_t * dev) * They can & should be intermixed to support multiple 3d windows. */ -static int r128_cce_flip(DRM_IOCTL_ARGS) +static int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; DRM_DEBUG("%s\n", __FUNCTION__); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); RING_SPACE_TEST_WITH_RETURN(dev_priv); @@ -1328,14 +1324,13 @@ static int r128_cce_flip(DRM_IOCTL_ARGS) return 0; } -static int r128_cce_swap(DRM_IOCTL_ARGS) +static int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; DRM_DEBUG("%s\n", __FUNCTION__); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); RING_SPACE_TEST_WITH_RETURN(dev_priv); @@ -1350,58 +1345,54 @@ static int r128_cce_swap(DRM_IOCTL_ARGS) return 0; } -static int r128_cce_vertex(DRM_IOCTL_ARGS) +static int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; drm_r128_buf_priv_t *buf_priv; - drm_r128_vertex_t vertex; + drm_r128_vertex_t *vertex = data; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(vertex, (drm_r128_vertex_t __user *) data, - sizeof(vertex)); - DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", - DRM_CURRENTPID, vertex.idx, vertex.count, vertex.discard); + DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard); - if (vertex.idx < 0 || vertex.idx >= dma->buf_count) { + if (vertex->idx < 0 || vertex->idx >= dma->buf_count) { DRM_ERROR("buffer index %d (of %d max)\n", - vertex.idx, dma->buf_count - 1); - return DRM_ERR(EINVAL); + vertex->idx, dma->buf_count - 1); + return -EINVAL; } - if (vertex.prim < 0 || - vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { - DRM_ERROR("buffer prim %d\n", vertex.prim); - return DRM_ERR(EINVAL); + if (vertex->prim < 0 || + vertex->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { + DRM_ERROR("buffer prim %d\n", vertex->prim); + return -EINVAL; } RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); - buf = dma->buflist[vertex.idx]; + buf = dma->buflist[vertex->idx]; buf_priv = buf->dev_private; - if (buf->filp != filp) { + if (buf->file_priv != file_priv) { DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, buf->file_priv); + return -EINVAL; } if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", vertex.idx); - return DRM_ERR(EINVAL); + DRM_ERROR("sending pending buffer %d\n", vertex->idx); + return -EINVAL; } - buf->used = vertex.count; - buf_priv->prim = vertex.prim; - buf_priv->discard = vertex.discard; + buf->used = vertex->count; + buf_priv->prim = vertex->prim; + buf_priv->discard = vertex->discard; r128_cce_dispatch_vertex(dev, buf); @@ -1409,134 +1400,123 @@ static int r128_cce_vertex(DRM_IOCTL_ARGS) return 0; } -static int r128_cce_indices(DRM_IOCTL_ARGS) +static int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; drm_r128_buf_priv_t *buf_priv; - drm_r128_indices_t elts; + drm_r128_indices_t *elts = data; int count; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(elts, (drm_r128_indices_t __user *) data, - sizeof(elts)); - DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID, - elts.idx, elts.start, elts.end, elts.discard); + elts->idx, elts->start, elts->end, elts->discard); - if (elts.idx < 0 || elts.idx >= dma->buf_count) { + if (elts->idx < 0 || elts->idx >= dma->buf_count) { DRM_ERROR("buffer index %d (of %d max)\n", - elts.idx, dma->buf_count - 1); - return DRM_ERR(EINVAL); + elts->idx, dma->buf_count - 1); + return -EINVAL; } - if (elts.prim < 0 || elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { - DRM_ERROR("buffer prim %d\n", elts.prim); - return DRM_ERR(EINVAL); + if (elts->prim < 0 || + elts->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { + DRM_ERROR("buffer prim %d\n", elts->prim); + return -EINVAL; } RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); - buf = dma->buflist[elts.idx]; + buf = dma->buflist[elts->idx]; buf_priv = buf->dev_private; - if (buf->filp != filp) { + if (buf->file_priv != file_priv) { DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, buf->file_priv); + return -EINVAL; } if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", elts.idx); - return DRM_ERR(EINVAL); + DRM_ERROR("sending pending buffer %d\n", elts->idx); + return -EINVAL; } - count = (elts.end - elts.start) / sizeof(u16); - elts.start -= R128_INDEX_PRIM_OFFSET; + count = (elts->end - elts->start) / sizeof(u16); + elts->start -= R128_INDEX_PRIM_OFFSET; - if (elts.start & 0x7) { - DRM_ERROR("misaligned buffer 0x%x\n", elts.start); - return DRM_ERR(EINVAL); + if (elts->start & 0x7) { + DRM_ERROR("misaligned buffer 0x%x\n", elts->start); + return -EINVAL; } - if (elts.start < buf->used) { - DRM_ERROR("no header 0x%x - 0x%x\n", elts.start, buf->used); - return DRM_ERR(EINVAL); + if (elts->start < buf->used) { + DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used); + return -EINVAL; } - buf->used = elts.end; - buf_priv->prim = elts.prim; - buf_priv->discard = elts.discard; + buf->used = elts->end; + buf_priv->prim = elts->prim; + buf_priv->discard = elts->discard; - r128_cce_dispatch_indices(dev, buf, elts.start, elts.end, count); + r128_cce_dispatch_indices(dev, buf, elts->start, elts->end, count); COMMIT_RING(); return 0; } -static int r128_cce_blit(DRM_IOCTL_ARGS) +static int r128_cce_blit(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_blit_t blit; + drm_r128_blit_t *blit = data; int ret; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(blit, (drm_r128_blit_t __user *) data, - sizeof(blit)); + LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit.idx); + DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx); - if (blit.idx < 0 || blit.idx >= dma->buf_count) { + if (blit->idx < 0 || blit->idx >= dma->buf_count) { DRM_ERROR("buffer index %d (of %d max)\n", - blit.idx, dma->buf_count - 1); - return DRM_ERR(EINVAL); + blit->idx, dma->buf_count - 1); + return -EINVAL; } RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); - ret = r128_cce_dispatch_blit(filp, dev, &blit); + ret = r128_cce_dispatch_blit(dev, file_priv, blit); COMMIT_RING(); return ret; } -static int r128_cce_depth(DRM_IOCTL_ARGS) +static int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_depth_t depth; + drm_r128_depth_t *depth = data; int ret; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(depth, (drm_r128_depth_t __user *) data, - sizeof(depth)); + LOCK_TEST_WITH_RETURN(dev, file_priv); RING_SPACE_TEST_WITH_RETURN(dev_priv); - ret = DRM_ERR(EINVAL); - switch (depth.func) { + ret = -EINVAL; + switch (depth->func) { case R128_WRITE_SPAN: - ret = r128_cce_dispatch_write_span(dev, &depth); + ret = r128_cce_dispatch_write_span(dev, depth); break; case R128_WRITE_PIXELS: - ret = r128_cce_dispatch_write_pixels(dev, &depth); + ret = r128_cce_dispatch_write_pixels(dev, depth); break; case R128_READ_SPAN: - ret = r128_cce_dispatch_read_span(dev, &depth); + ret = r128_cce_dispatch_read_span(dev, depth); break; case R128_READ_PIXELS: - ret = r128_cce_dispatch_read_pixels(dev, &depth); + ret = r128_cce_dispatch_read_pixels(dev, depth); break; } @@ -1544,20 +1524,16 @@ static int r128_cce_depth(DRM_IOCTL_ARGS) return ret; } -static int r128_cce_stipple(DRM_IOCTL_ARGS) +static int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_stipple_t stipple; + drm_r128_stipple_t *stipple = data; u32 mask[32]; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(stipple, (drm_r128_stipple_t __user *) data, - sizeof(stipple)); + LOCK_TEST_WITH_RETURN(dev, file_priv); - if (DRM_COPY_FROM_USER(&mask, stipple.mask, 32 * sizeof(u32))) - return DRM_ERR(EFAULT); + if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32))) + return -EFAULT; RING_SPACE_TEST_WITH_RETURN(dev_priv); @@ -1567,61 +1543,58 @@ static int r128_cce_stipple(DRM_IOCTL_ARGS) return 0; } -static int r128_cce_indirect(DRM_IOCTL_ARGS) +static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; drm_r128_buf_priv_t *buf_priv; - drm_r128_indirect_t indirect; + drm_r128_indirect_t *indirect = data; #if 0 RING_LOCALS; #endif - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(indirect, (drm_r128_indirect_t __user *) data, - sizeof(indirect)); - DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n", - indirect.idx, indirect.start, indirect.end, indirect.discard); + indirect->idx, indirect->start, indirect->end, + indirect->discard); - if (indirect.idx < 0 || indirect.idx >= dma->buf_count) { + if (indirect->idx < 0 || indirect->idx >= dma->buf_count) { DRM_ERROR("buffer index %d (of %d max)\n", - indirect.idx, dma->buf_count - 1); - return DRM_ERR(EINVAL); + indirect->idx, dma->buf_count - 1); + return -EINVAL; } - buf = dma->buflist[indirect.idx]; + buf = dma->buflist[indirect->idx]; buf_priv = buf->dev_private; - if (buf->filp != filp) { + if (buf->file_priv != file_priv) { DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, buf->file_priv); + return -EINVAL; } if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", indirect.idx); - return DRM_ERR(EINVAL); + DRM_ERROR("sending pending buffer %d\n", indirect->idx); + return -EINVAL; } - if (indirect.start < buf->used) { + if (indirect->start < buf->used) { DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n", - indirect.start, buf->used); - return DRM_ERR(EINVAL); + indirect->start, buf->used); + return -EINVAL; } RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); - buf->used = indirect.end; - buf_priv->discard = indirect.discard; + buf->used = indirect->end; + buf_priv->discard = indirect->discard; #if 0 /* Wait for the 3D stream to idle before the indirect buffer @@ -1636,46 +1609,42 @@ static int r128_cce_indirect(DRM_IOCTL_ARGS) * X server. This is insecure and is thus only available to * privileged clients. */ - r128_cce_dispatch_indirect(dev, buf, indirect.start, indirect.end); + r128_cce_dispatch_indirect(dev, buf, indirect->start, indirect->end); COMMIT_RING(); return 0; } -static int r128_getparam(DRM_IOCTL_ARGS) +static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_getparam_t param; + drm_r128_getparam_t *param = data; int value; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(param, (drm_r128_getparam_t __user *) data, - sizeof(param)); - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - switch (param.param) { + switch (param->param) { case R128_PARAM_IRQ_NR: value = dev->irq; break; default: - return DRM_ERR(EINVAL); + return -EINVAL; } - if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { + if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { DRM_ERROR("copy_to_user\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } return 0; } -void r128_driver_preclose(drm_device_t * dev, DRMFILE filp) +void r128_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) { if (dev->dev_private) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -1685,29 +1654,29 @@ void r128_driver_preclose(drm_device_t * dev, DRMFILE filp) } } -void r128_driver_lastclose(drm_device_t * dev) +void r128_driver_lastclose(struct drm_device * dev) { r128_do_cleanup_cce(dev); } -drm_ioctl_desc_t r128_ioctls[] = { - [DRM_IOCTL_NR(DRM_R128_INIT)] = {r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_R128_CCE_START)] = {r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_R128_CCE_STOP)] = {r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_R128_CCE_RESET)] = {r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)] = {r128_cce_idle, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_RESET)] = {r128_engine_reset, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = {r128_fullscreen, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_SWAP)] = {r128_cce_swap, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_FLIP)] = {r128_cce_flip, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_CLEAR)] = {r128_cce_clear, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_VERTEX)] = {r128_cce_vertex, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_INDICES)] = {r128_cce_indices, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_BLIT)] = {r128_cce_blit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_DEPTH)] = {r128_cce_depth, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_STIPPLE)] = {r128_cce_stipple, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_R128_INDIRECT)] = {r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_R128_GETPARAM)] = {r128_getparam, DRM_AUTH}, +struct drm_ioctl_desc r128_ioctls[] = { + DRM_IOCTL_DEF(DRM_R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), + DRM_IOCTL_DEF(DRM_R128_RESET, r128_engine_reset, DRM_AUTH), + DRM_IOCTL_DEF(DRM_R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), + DRM_IOCTL_DEF(DRM_R128_SWAP, r128_cce_swap, DRM_AUTH), + DRM_IOCTL_DEF(DRM_R128_FLIP, r128_cce_flip, DRM_AUTH), + DRM_IOCTL_DEF(DRM_R128_CLEAR, r128_cce_clear, DRM_AUTH), + DRM_IOCTL_DEF(DRM_R128_VERTEX, r128_cce_vertex, DRM_AUTH), + DRM_IOCTL_DEF(DRM_R128_INDICES, r128_cce_indices, DRM_AUTH), + DRM_IOCTL_DEF(DRM_R128_BLIT, r128_cce_blit, DRM_AUTH), + DRM_IOCTL_DEF(DRM_R128_DEPTH, r128_cce_depth, DRM_AUTH), + DRM_IOCTL_DEF(DRM_R128_STIPPLE, r128_cce_stipple, DRM_AUTH), + DRM_IOCTL_DEF(DRM_R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_R128_GETPARAM, r128_getparam, DRM_AUTH), }; int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c index d3c52d43..fe46c2d2 100644 --- a/shared-core/r300_cmdbuf.c +++ b/shared-core/r300_cmdbuf.c @@ -55,7 +55,7 @@ static const int r300_cliprect_cntl[4] = { static int r300_emit_cliprects(drm_radeon_private_t *dev_priv, drm_radeon_kcmd_buffer_t *cmdbuf, int n) { - drm_clip_rect_t box; + struct drm_clip_rect box; int nr; int i; RING_LOCALS; @@ -74,7 +74,7 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv, if (DRM_COPY_FROM_USER_UNCHECKED (&box, &cmdbuf->boxes[n + i], sizeof(box))) { DRM_ERROR("copy cliprect faulted\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } box.x1 = @@ -155,7 +155,8 @@ void r300_init_reg_flags(void) ADD_RANGE(R300_VAP_INPUT_CNTL_0, 2); ADD_RANGE(0x21DC, 1); ADD_RANGE(R300_VAP_UNKNOWN_221C, 1); - ADD_RANGE(0x2220, 4); + ADD_RANGE(R300_VAP_CLIP_X_0, 4); + ADD_RANGE(R300_VAP_PVS_WAITIDLE, 1); ADD_RANGE(R300_VAP_UNKNOWN_2288, 1); ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2); ADD_RANGE(R300_VAP_PVS_CNTL_1, 3); @@ -262,7 +263,7 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * DRM_ERROR ("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n", reg, sz); - return DRM_ERR(EINVAL); + return -EINVAL; } for (i = 0; i < sz; i++) { values[i] = ((int *)cmdbuf->buf)[i]; @@ -274,13 +275,13 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * DRM_ERROR ("Offset failed range check (reg=%04x sz=%d)\n", reg, sz); - return DRM_ERR(EINVAL); + return -EINVAL; } break; default: DRM_ERROR("Register %04x failed check as flag=%02x\n", reg + i * 4, r300_reg_flags[(reg >> 2) + i]); - return DRM_ERR(EINVAL); + return -EINVAL; } } @@ -316,12 +317,12 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv, return 0; if (sz * 4 > cmdbuf->bufsz) - return DRM_ERR(EINVAL); + return -EINVAL; if (reg + sz * 4 >= 0x10000) { DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg, sz); - return DRM_ERR(EINVAL); + return -EINVAL; } if (r300_check_range(reg, sz)) { @@ -361,7 +362,7 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv, if (!sz) return 0; if (sz * 16 > cmdbuf->bufsz) - return DRM_ERR(EINVAL); + return -EINVAL; BEGIN_RING(5 + sz * 4); /* Wait for VAP to come to senses.. */ @@ -390,7 +391,7 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv, RING_LOCALS; if (8 * 4 > cmdbuf->bufsz) - return DRM_ERR(EINVAL); + return -EINVAL; BEGIN_RING(10); OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8)); @@ -420,7 +421,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, if ((count + 1) > MAX_ARRAY_PACKET) { DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", count); - return DRM_ERR(EINVAL); + return -EINVAL; } memset(payload, 0, MAX_ARRAY_PACKET * 4); memcpy(payload, cmdbuf->buf + 4, (count + 1) * 4); @@ -436,7 +437,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, DRM_ERROR ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i); - return DRM_ERR(EINVAL); + return -EINVAL; } k++; i++; @@ -447,7 +448,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, DRM_ERROR ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i); - return DRM_ERR(EINVAL); + return -EINVAL; } k++; i++; @@ -457,7 +458,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, DRM_ERROR ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", k, i, narrays, count + 1); - return DRM_ERR(EINVAL); + return -EINVAL; } /* all clear, output packet */ @@ -491,7 +492,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, ret = !radeon_check_offset(dev_priv, offset); if (ret) { DRM_ERROR("Invalid bitblt first offset is %08X\n", offset); - return DRM_ERR(EINVAL); + return -EINVAL; } } @@ -501,7 +502,7 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, ret = !radeon_check_offset(dev_priv, offset); if (ret) { DRM_ERROR("Invalid bitblt second offset is %08X\n", offset); - return DRM_ERR(EINVAL); + return -EINVAL; } } @@ -529,12 +530,12 @@ static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv, if ((cmd[1] & 0x8000ffff) != 0x80000810) { DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); - return DRM_ERR(EINVAL); + return -EINVAL; } ret = !radeon_check_offset(dev_priv, cmd[2]); if (ret) { DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); - return DRM_ERR(EINVAL); + return -EINVAL; } BEGIN_RING(count+2); @@ -556,7 +557,7 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, RING_LOCALS; if (4 > cmdbuf->bufsz) - return DRM_ERR(EINVAL); + return -EINVAL; /* Fixme !! This simply emits a packet without much checking. We need to be smarter. */ @@ -567,7 +568,7 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, /* Is it packet 3 ? */ if ((header >> 30) != 0x3) { DRM_ERROR("Not a packet3 header (0x%08x)\n", header); - return DRM_ERR(EINVAL); + return -EINVAL; } count = (header >> 16) & 0x3fff; @@ -577,7 +578,7 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, DRM_ERROR ("Expected packet3 of length %d but have only %d bytes left\n", (count + 2) * 4, cmdbuf->bufsz); - return DRM_ERR(EINVAL); + return -EINVAL; } /* Is it a packet type we know about ? */ @@ -599,7 +600,7 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, break; default: DRM_ERROR("Unknown packet3 header (0x%08x)\n", header); - return DRM_ERR(EINVAL); + return -EINVAL; } BEGIN_RING(count + 2); @@ -663,7 +664,7 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv, DRM_ERROR("bad packet3 type %i at %p\n", header.packet3.packet, cmdbuf->buf - sizeof(header)); - return DRM_ERR(EINVAL); + return -EINVAL; } n += R300_SIMULTANEOUS_CLIPRECTS; @@ -705,7 +706,7 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) * The actual age emit is done by r300_do_cp_cmdbuf, which is why you must * be careful about how this function is called. */ -static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf) +static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; @@ -724,11 +725,11 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, RING_LOCALS; if (cmdbuf->bufsz < sizeof(uint64_t) + header.scratch.n_bufs * sizeof(buf_idx) ) { - return DRM_ERR(EINVAL); + return -EINVAL; } if (header.scratch.reg >= 5) { - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->scratch_ages[header.scratch.reg] ++; @@ -743,21 +744,21 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, buf_idx *= 2; /* 8 bytes per buf */ if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) { - return DRM_ERR(EINVAL); + return -EINVAL; } if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) { - return DRM_ERR(EINVAL); + return -EINVAL; } if (h_pending == 0) { - return DRM_ERR(EINVAL); + return -EINVAL; } h_pending--; if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) { - return DRM_ERR(EINVAL); + return -EINVAL; } cmdbuf->buf += sizeof(buf_idx); @@ -777,14 +778,13 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, * commands on the DMA ring buffer. * Called by the ioctl handler function radeon_cp_cmdbuf. */ -int r300_do_cp_cmdbuf(drm_device_t *dev, - DRMFILE filp, - drm_file_t *filp_priv, +int r300_do_cp_cmdbuf(struct drm_device *dev, + struct drm_file *file_priv, drm_radeon_kcmd_buffer_t *cmdbuf) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf = NULL; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf = NULL; int emit_dispatch_age = 0; int ret = 0; @@ -877,15 +877,16 @@ int r300_do_cp_cmdbuf(drm_device_t *dev, if (idx < 0 || idx >= dma->buf_count) { DRM_ERROR("buffer index %d (of %d max)\n", idx, dma->buf_count - 1); - ret = DRM_ERR(EINVAL); + ret = -EINVAL; goto cleanup; } buf = dma->buflist[idx]; - if (buf->filp != filp || buf->pending) { + if (buf->file_priv != file_priv || buf->pending) { DRM_ERROR("bad buffer %p %p %d\n", - buf->filp, filp, buf->pending); - ret = DRM_ERR(EINVAL); + buf->file_priv, file_priv, + buf->pending); + ret = -EINVAL; goto cleanup; } @@ -922,7 +923,7 @@ int r300_do_cp_cmdbuf(drm_device_t *dev, DRM_ERROR("bad cmd_type %i at %p\n", header.header.cmd_type, cmdbuf->buf - sizeof(header)); - ret = DRM_ERR(EINVAL); + ret = -EINVAL; goto cleanup; } } diff --git a/shared-core/r300_reg.h b/shared-core/r300_reg.h index 0a31f0b9..e59919be 100644 --- a/shared-core/r300_reg.h +++ b/shared-core/r300_reg.h @@ -116,6 +116,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */ #define R300_VAP_OUTPUT_VTX_FMT_1 0x2094 + /* each of the following is 3 bits wide, specifies number + of components */ # define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0 # define R300_VAP_OUTPUT_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3 # define R300_VAP_OUTPUT_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6 @@ -299,6 +301,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_221C_NORMAL 0x00000000 # define R300_221C_CLEAR 0x0001C000 +/* These seem to be per-pixel and per-vertex X and Y clipping planes. The first + * plane is per-pixel and the second plane is per-vertex. + * + * This was determined by experimentation alone but I believe it is correct. + * + * These registers are called X_QUAD0_1_FL to X_QUAD0_4_FL by glxtest. + */ +#define R300_VAP_CLIP_X_0 0x2220 +#define R300_VAP_CLIP_X_1 0x2224 +#define R300_VAP_CLIP_Y_0 0x2228 +#define R300_VAP_CLIP_Y_1 0x2230 + /* gap */ /* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between @@ -322,13 +336,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * The meaning of the two UNKNOWN fields is obviously not known. However, * experiments so far have shown that both *must* point to an instruction * inside the vertex program, otherwise the GPU locks up. + * * fglrx usually sets CNTL_3_UNKNOWN to the end of the program and - * CNTL_1_UNKNOWN points to instruction where last write to position takes - * place. + * R300_PVS_CNTL_1_POS_END_SHIFT points to instruction where last write to + * position takes place. + * * Most likely this is used to ignore rest of the program in cases * where group of verts arent visible. For some reason this "section" * is sometimes accepted other instruction that have no relationship with - *position calculations. + * position calculations. */ #define R300_VAP_PVS_CNTL_1 0x22D0 # define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0 @@ -967,7 +983,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * first node is stored in NODE_2, the second node is stored in NODE_3. * * Offsets are relative to the master offset from PFS_CNTL_2. - * LAST_NODE is set for the last node, and only for the last node. */ #define R300_PFS_NODE_0 0x4610 #define R300_PFS_NODE_1 0x4614 @@ -981,7 +996,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12) # define R300_PFS_NODE_TEX_END_SHIFT 17 # define R300_PFS_NODE_TEX_END_MASK (31 << 17) -/*# define R300_PFS_NODE_LAST_NODE (1 << 22) */ # define R300_PFS_NODE_OUTPUT_COLOR (1 << 22) # define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23) @@ -1591,6 +1605,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_EB_UNK1_SHIFT 24 # define R300_EB_UNK1 (0x80<<24) # define R300_EB_UNK2 0x0810 +#define R300_PACKET3_3D_DRAW_VBUF_2 0x00003400 #define R300_PACKET3_3D_DRAW_INDX_2 0x00003600 /* END: Packet 3 commands */ diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index ec2e688b..06861381 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -36,7 +36,7 @@ #define RADEON_FIFO_DEBUG 0 -static int radeon_do_cleanup_cp(drm_device_t * dev); +static int radeon_do_cleanup_cp(struct drm_device * dev); /* CP microcode (from ATI) */ static const u32 R200_cp_microcode[][2] = { @@ -816,7 +816,7 @@ static const u32 R300_cp_microcode[][2] = { { 0000000000, 0000000000 }, }; -static int RADEON_READ_PLL(drm_device_t * dev, int addr) +static int RADEON_READ_PLL(struct drm_device * dev, int addr) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -889,7 +889,7 @@ static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv) DRM_ERROR("failed!\n"); radeon_status(dev_priv); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries) @@ -910,7 +910,7 @@ static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries) DRM_ERROR("failed!\n"); radeon_status(dev_priv); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) @@ -936,7 +936,7 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) DRM_ERROR("failed!\n"); radeon_status(dev_priv); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } /* ================================================================ @@ -1066,7 +1066,7 @@ static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv) /* Reset the engine. This will stop the CP if it is running. */ -static int radeon_do_engine_reset(drm_device_t * dev) +static int radeon_do_engine_reset(struct drm_device * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; @@ -1122,7 +1122,7 @@ static int radeon_do_engine_reset(drm_device_t * dev) return 0; } -static void radeon_cp_init_ring_buffer(drm_device_t * dev, +static void radeon_cp_init_ring_buffer(struct drm_device * dev, drm_radeon_private_t * dev_priv) { u32 ring_start, cur_read_ptr; @@ -1174,7 +1174,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, } else #endif { - drm_sg_mem_t *entry = dev->sg; + struct drm_sg_mem *entry = dev->sg; unsigned long tmp_ofs, page_ofs; tmp_ofs = dev_priv->ring_rptr->offset - @@ -1390,7 +1390,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) } } -static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) +static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -1400,7 +1400,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) @@ -1418,7 +1418,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) { DRM_ERROR("PCI GART memory not allocated!\n"); radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->usec_timeout = init->usec_timeout; @@ -1426,7 +1426,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { DRM_DEBUG("TIMEOUT problem!\n"); radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } /* Enable vblank on CRTC1 for older X servers @@ -1455,7 +1455,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } switch (init->fb_bpp) { @@ -1524,27 +1524,27 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) if (!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); if (!dev_priv->cp_ring) { DRM_ERROR("could not find cp ring region!\n"); radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); if (!dev_priv->ring_rptr) { DRM_ERROR("could not find ring read pointer!\n"); radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev->agp_buffer_token = init->buffers_offset; dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); if (!dev->agp_buffer_map) { DRM_ERROR("could not find dma buffer region!\n"); radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } if (init->gart_textures_offset) { @@ -1553,7 +1553,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) if (!dev_priv->gart_textures) { DRM_ERROR("could not find GART texture region!\n"); radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } } @@ -1571,7 +1571,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) !dev->agp_buffer_map->handle) { DRM_ERROR("could not find ioremap agp regions!\n"); radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } } else #endif @@ -1725,14 +1725,14 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) DRM_ERROR ("Cannot use PCI Express without GART in FB memory\n"); radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } } if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { DRM_ERROR("failed to init PCI GART!\n"); radeon_do_cleanup_cp(dev); - return DRM_ERR(ENOMEM); + return -ENOMEM; } /* Turn on PCI GART */ @@ -1750,7 +1750,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) return 0; } -static int radeon_do_cleanup_cp(drm_device_t * dev) +static int radeon_do_cleanup_cp(struct drm_device * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); @@ -1806,13 +1806,13 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) * * Charl P. Botha <http://cpbotha.net> */ -static int radeon_do_resume_cp(drm_device_t * dev) +static int radeon_do_resume_cp(struct drm_device * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; if (!dev_priv) { DRM_ERROR("Called with no initialization\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } DRM_DEBUG("Starting radeon_do_resume_cp()\n"); @@ -1838,38 +1838,33 @@ static int radeon_do_resume_cp(drm_device_t * dev) return 0; } -int radeon_cp_init(DRM_IOCTL_ARGS) +int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_radeon_init_t init; + drm_radeon_init_t *init = data; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_COPY_FROM_USER_IOCTL(init, (drm_radeon_init_t __user *) data, - sizeof(init)); - - if (init.func == RADEON_INIT_R300_CP) + if (init->func == RADEON_INIT_R300_CP) r300_init_reg_flags(); - switch (init.func) { + switch (init->func) { case RADEON_INIT_CP: case RADEON_INIT_R200_CP: case RADEON_INIT_R300_CP: - return radeon_do_init_cp(dev, &init); + return radeon_do_init_cp(dev, init); case RADEON_CLEANUP_CP: return radeon_do_cleanup_cp(dev); } - return DRM_ERR(EINVAL); + return -EINVAL; } -int radeon_cp_start(DRM_IOCTL_ARGS) +int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (dev_priv->cp_running) { DRM_DEBUG("%s while CP running\n", __FUNCTION__); @@ -1889,18 +1884,14 @@ int radeon_cp_start(DRM_IOCTL_ARGS) /* Stop the CP. The engine must have been idled before calling this * routine. */ -int radeon_cp_stop(DRM_IOCTL_ARGS) +int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_cp_stop_t stop; + drm_radeon_cp_stop_t *stop = data; int ret; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(stop, (drm_radeon_cp_stop_t __user *) data, - sizeof(stop)); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv->cp_running) return 0; @@ -1908,14 +1899,14 @@ int radeon_cp_stop(DRM_IOCTL_ARGS) /* Flush any pending CP commands. This ensures any outstanding * commands are exectuted by the engine before we turn it off. */ - if (stop.flush) { + if (stop->flush) { radeon_do_cp_flush(dev_priv); } /* If we fail to make the engine go idle, we return an error * code so that the DRM ioctl wrapper can try again. */ - if (stop.idle) { + if (stop->idle) { ret = radeon_do_cp_idle(dev_priv); if (ret) return ret; @@ -1933,7 +1924,7 @@ int radeon_cp_stop(DRM_IOCTL_ARGS) return 0; } -void radeon_do_release(drm_device_t * dev) +void radeon_do_release(struct drm_device * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; int i, ret; @@ -1983,17 +1974,16 @@ void radeon_do_release(drm_device_t * dev) /* Just reset the CP ring. Called as part of an X Server engine reset. */ -int radeon_cp_reset(DRM_IOCTL_ARGS) +int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_DEBUG("%s called before init done\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } radeon_do_cp_reset(dev_priv); @@ -2004,32 +1994,29 @@ int radeon_cp_reset(DRM_IOCTL_ARGS) return 0; } -int radeon_cp_idle(DRM_IOCTL_ARGS) +int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); return radeon_do_cp_idle(dev_priv); } /* Added by Charl P. Botha to call radeon_do_resume_cp(). */ -int radeon_cp_resume(DRM_IOCTL_ARGS) +int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; return radeon_do_resume_cp(dev); } -int radeon_engine_reset(DRM_IOCTL_ARGS) +int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); return radeon_do_engine_reset(dev); } @@ -2040,7 +2027,7 @@ int radeon_engine_reset(DRM_IOCTL_ARGS) /* KW: Deprecated to say the least: */ -int radeon_fullscreen(DRM_IOCTL_ARGS) +int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv) { return 0; } @@ -2066,12 +2053,12 @@ int radeon_fullscreen(DRM_IOCTL_ARGS) * they can't get the lock. */ -drm_buf_t *radeon_freelist_get(drm_device_t * dev) +struct drm_buf *radeon_freelist_get(struct drm_device * dev) { - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv; - drm_buf_t *buf; + struct drm_buf *buf; int i, t; int start; @@ -2086,8 +2073,9 @@ drm_buf_t *radeon_freelist_get(drm_device_t * dev) for (i = start; i < dma->buf_count; i++) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if (buf->filp == 0 || (buf->pending && - buf_priv->age <= done_age)) { + if (buf->file_priv == NULL || (buf->pending && + buf_priv->age <= + done_age)) { dev_priv->stats.requested_bufs++; buf->pending = 0; return buf; @@ -2106,12 +2094,12 @@ drm_buf_t *radeon_freelist_get(drm_device_t * dev) } #if 0 -drm_buf_t *radeon_freelist_get(drm_device_t * dev) +struct drm_buf *radeon_freelist_get(struct drm_device * dev) { - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv; - drm_buf_t *buf; + struct drm_buf *buf; int i, t; int start; u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); @@ -2126,8 +2114,9 @@ drm_buf_t *radeon_freelist_get(drm_device_t * dev) for (i = start; i < dma->buf_count; i++) { buf = dma->buflist[i]; buf_priv = buf->dev_private; - if (buf->filp == 0 || (buf->pending && - buf_priv->age <= done_age)) { + if (buf->file_priv == 0 || (buf->pending && + buf_priv->age <= + done_age)) { dev_priv->stats.requested_bufs++; buf->pending = 0; return buf; @@ -2140,15 +2129,15 @@ drm_buf_t *radeon_freelist_get(drm_device_t * dev) } #endif -void radeon_freelist_reset(drm_device_t * dev) +void radeon_freelist_reset(struct drm_device * dev) { - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; drm_radeon_private_t *dev_priv = dev->dev_private; int i; dev_priv->last_buf = 0; for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[i]; + struct drm_buf *buf = dma->buflist[i]; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; buf_priv->age = 0; } @@ -2187,70 +2176,65 @@ int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n) radeon_status(dev_priv); DRM_ERROR("failed!\n"); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } -static int radeon_cp_get_buffers(DRMFILE filp, drm_device_t * dev, - drm_dma_t * d) +static int radeon_cp_get_buffers(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_dma * d) { int i; - drm_buf_t *buf; + struct drm_buf *buf; for (i = d->granted_count; i < d->request_count; i++) { buf = radeon_freelist_get(dev); if (!buf) - return DRM_ERR(EBUSY); /* NOTE: broken client */ + return -EBUSY; /* NOTE: broken client */ - buf->filp = filp; + buf->file_priv = file_priv; if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, sizeof(buf->idx))) - return DRM_ERR(EFAULT); + return -EFAULT; if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, sizeof(buf->total))) - return DRM_ERR(EFAULT); + return -EFAULT; d->granted_count++; } return 0; } -int radeon_cp_buffers(DRM_IOCTL_ARGS) +int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; int ret = 0; - drm_dma_t __user *argp = (void __user *)data; - drm_dma_t d; + struct drm_dma *d = data; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(d, argp, sizeof(d)); + LOCK_TEST_WITH_RETURN(dev, file_priv); /* Please don't send us buffers. */ - if (d.send_count != 0) { + if (d->send_count != 0) { DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d.send_count); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, d->send_count); + return -EINVAL; } /* We'll send you buffers. */ - if (d.request_count < 0 || d.request_count > dma->buf_count) { + if (d->request_count < 0 || d->request_count > dma->buf_count) { DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d.request_count, dma->buf_count); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, d->request_count, dma->buf_count); + return -EINVAL; } - d.granted_count = 0; + d->granted_count = 0; - if (d.request_count) { - ret = radeon_cp_get_buffers(filp, dev, &d); + if (d->request_count) { + ret = radeon_cp_get_buffers(dev, file_priv, d); } - DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d)); - return ret; } @@ -2261,7 +2245,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; memset(dev_priv, 0, sizeof(drm_radeon_private_t)); dev->dev_private = (void *)dev_priv; diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index 6a57b804..b0ef702b 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -417,7 +417,7 @@ typedef struct { /* The current cliprects, or a subset thereof. */ - drm_clip_rect_t boxes[RADEON_NR_SAREA_CLIPRECTS]; + struct drm_clip_rect boxes[RADEON_NR_SAREA_CLIPRECTS]; unsigned int nbox; /* Counters for client-side throttling of rendering clients. @@ -426,7 +426,7 @@ typedef struct { unsigned int last_dispatch; unsigned int last_clear; - drm_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS + + struct drm_tex_region tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS + 1]; unsigned int tex_age[RADEON_NR_TEX_HEAPS]; int ctx_owner; @@ -604,7 +604,7 @@ typedef struct drm_radeon_cmd_buffer { int bufsz; char __user *buf; int nbox; - drm_clip_rect_t __user *boxes; + struct drm_clip_rect __user *boxes; } drm_radeon_cmd_buffer_t; typedef struct drm_radeon_tex_image { diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 418b6e78..a71b0bee 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -156,7 +156,7 @@ enum radeon_chip_flags { typedef struct drm_radeon_freelist { unsigned int age; - drm_buf_t *buf; + struct drm_buf *buf; struct drm_radeon_freelist *next; struct drm_radeon_freelist *prev; } drm_radeon_freelist_t; @@ -195,7 +195,7 @@ struct mem_block { struct mem_block *prev; int start; int size; - DRMFILE filp; /* 0: free, -1: heap, other: real files */ + struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ }; struct radeon_surface { @@ -210,7 +210,7 @@ struct radeon_virt_surface { u32 lower; u32 upper; u32 flags; - DRMFILE filp; + struct drm_file *file_priv; }; typedef struct drm_radeon_private { @@ -295,7 +295,7 @@ typedef struct drm_radeon_private { unsigned long pcigart_offset; unsigned int pcigart_offset_set; - drm_ati_pcigart_info gart_info; + struct ati_pcigart_info gart_info; u32 scratch_ages[5]; @@ -315,11 +315,11 @@ typedef struct drm_radeon_kcmd_buffer { int bufsz; char *buf; int nbox; - drm_clip_rect_t __user *boxes; + struct drm_clip_rect __user *boxes; } drm_radeon_kcmd_buffer_t; extern int radeon_no_wb; -extern drm_ioctl_desc_t radeon_ioctls[]; +extern struct drm_ioctl_desc radeon_ioctls[]; extern int radeon_max_ioctl; /* Check whether the given hardware address is inside the framebuffer or the @@ -338,59 +338,64 @@ static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv, } /* radeon_cp.c */ -extern int radeon_cp_init(DRM_IOCTL_ARGS); -extern int radeon_cp_start(DRM_IOCTL_ARGS); -extern int radeon_cp_stop(DRM_IOCTL_ARGS); -extern int radeon_cp_reset(DRM_IOCTL_ARGS); -extern int radeon_cp_idle(DRM_IOCTL_ARGS); -extern int radeon_cp_resume(DRM_IOCTL_ARGS); -extern int radeon_engine_reset(DRM_IOCTL_ARGS); -extern int radeon_fullscreen(DRM_IOCTL_ARGS); -extern int radeon_cp_buffers(DRM_IOCTL_ARGS); - -extern void radeon_freelist_reset(drm_device_t * dev); -extern drm_buf_t *radeon_freelist_get(drm_device_t * dev); +extern int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); + +extern void radeon_freelist_reset(struct drm_device * dev); +extern struct drm_buf *radeon_freelist_get(struct drm_device * dev); extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n); extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv); -extern int radeon_mem_alloc(DRM_IOCTL_ARGS); -extern int radeon_mem_free(DRM_IOCTL_ARGS); -extern int radeon_mem_init_heap(DRM_IOCTL_ARGS); +extern int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void radeon_mem_takedown(struct mem_block **heap); -extern void radeon_mem_release(DRMFILE filp, struct mem_block *heap); +extern void radeon_mem_release(struct drm_file *file_priv, + struct mem_block *heap); /* radeon_irq.c */ -extern int radeon_irq_emit(DRM_IOCTL_ARGS); -extern int radeon_irq_wait(DRM_IOCTL_ARGS); - -extern void radeon_do_release(drm_device_t * dev); -extern u32 radeon_get_vblank_counter(drm_device_t *dev, int crtc); -extern int radeon_enable_vblank(drm_device_t *dev, int crtc); -extern void radeon_disable_vblank(drm_device_t *dev, int crtc); +extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); + +extern void radeon_do_release(struct drm_device * dev); +extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc); +extern int radeon_enable_vblank(struct drm_device *dev, int crtc); +extern void radeon_disable_vblank(struct drm_device *dev, int crtc); +extern void radeon_do_release(struct drm_device * dev); extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); -extern void radeon_driver_irq_preinstall(drm_device_t * dev); -extern int radeon_driver_irq_postinstall(drm_device_t * dev); -extern void radeon_driver_irq_uninstall(drm_device_t * dev); -extern int radeon_vblank_crtc_get(drm_device_t *dev); -extern int radeon_vblank_crtc_set(drm_device_t *dev, int64_t value); +extern void radeon_driver_irq_preinstall(struct drm_device * dev); +extern int radeon_driver_irq_postinstall(struct drm_device * dev); +extern void radeon_driver_irq_uninstall(struct drm_device * dev); +extern int radeon_vblank_crtc_get(struct drm_device *dev); +extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); extern int radeon_driver_unload(struct drm_device *dev); extern int radeon_driver_firstopen(struct drm_device *dev); -extern void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp); -extern void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp); -extern void radeon_driver_lastclose(drm_device_t * dev); -extern int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv); +extern void radeon_driver_preclose(struct drm_device * dev, + struct drm_file *file_priv); +extern void radeon_driver_postclose(struct drm_device * dev, + struct drm_file *file_priv); +extern void radeon_driver_lastclose(struct drm_device * dev); +extern int radeon_driver_open(struct drm_device * dev, + struct drm_file * file_priv); extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); /* r300_cmdbuf.c */ extern void r300_init_reg_flags(void); -extern int r300_do_cp_cmdbuf(drm_device_t *dev, DRMFILE filp, - drm_file_t* filp_priv, +extern int r300_do_cp_cmdbuf(struct drm_device *dev, + struct drm_file *file_priv, drm_radeon_kcmd_buffer_t* cmdbuf); /* Flags for stats.boxes diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index 4ff8a5c3..6ba3c147 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -35,7 +35,7 @@ #include "radeon_drm.h" #include "radeon_drv.h" -static void radeon_irq_set_state(drm_device_t *dev, u32 mask, int state) +static void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -47,7 +47,7 @@ static void radeon_irq_set_state(drm_device_t *dev, u32 mask, int state) RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); } -int radeon_enable_vblank(drm_device_t *dev, int crtc) +int radeon_enable_vblank(struct drm_device *dev, int crtc) { switch (crtc) { case 0: @@ -59,13 +59,13 @@ int radeon_enable_vblank(drm_device_t *dev, int crtc) default: DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", crtc); - return DRM_ERR(EINVAL); + return EINVAL; } return 0; } -void radeon_disable_vblank(drm_device_t *dev, int crtc) +void radeon_disable_vblank(struct drm_device *dev, int crtc) { switch (crtc) { case 0: @@ -113,7 +113,7 @@ static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv) irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) { - drm_device_t *dev = (drm_device_t *) arg; + struct drm_device *dev = (struct drm_device *) arg; drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; u32 stat; @@ -140,7 +140,7 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_HANDLED; } -static int radeon_emit_irq(drm_device_t * dev) +static int radeon_emit_irq(struct drm_device * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; unsigned int ret; @@ -158,7 +158,7 @@ static int radeon_emit_irq(drm_device_t * dev) return ret; } -static int radeon_wait_irq(drm_device_t * dev, int swi_nr) +static int radeon_wait_irq(struct drm_device * dev, int swi_nr) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; @@ -175,47 +175,49 @@ static int radeon_wait_irq(drm_device_t * dev, int swi_nr) return ret; } -u32 radeon_get_vblank_counter(drm_device_t *dev, int crtc) +u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) { drm_radeon_private_t *dev_priv = dev->dev_private; u32 crtc_cnt_reg, crtc_status_reg; + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return -EINVAL; + } + if (crtc == 0) { crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME; crtc_status_reg = RADEON_CRTC_STATUS; } else if (crtc == 1) { crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME; crtc_status_reg = RADEON_CRTC2_STATUS; - } else - return 0; + } else { + return -EINVAL; + } return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1); } /* Needs the lock as it touches the ring. */ -int radeon_irq_emit(DRM_IOCTL_ARGS) +int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_irq_emit_t emit; + drm_radeon_irq_emit_t *emit = data; int result; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(emit, (drm_radeon_irq_emit_t __user *) data, - sizeof(emit)); - result = radeon_emit_irq(dev); - if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof(int))) { + if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { DRM_ERROR("copy_to_user\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } return 0; @@ -223,28 +225,22 @@ int radeon_irq_emit(DRM_IOCTL_ARGS) /* Doesn't need the hardware lock. */ -int radeon_irq_wait(DRM_IOCTL_ARGS) +int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_irq_wait_t irqwait; + drm_radeon_irq_wait_t *irqwait = data; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_radeon_irq_wait_t __user *) data, - sizeof(irqwait)); - - return radeon_wait_irq(dev, irqwait.irq_seq); + return radeon_wait_irq(dev, irqwait->irq_seq); } - - /* drm_dma.h hooks */ -void radeon_driver_irq_preinstall(drm_device_t * dev) +void radeon_driver_irq_preinstall(struct drm_device * dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; @@ -256,7 +252,7 @@ void radeon_driver_irq_preinstall(drm_device_t * dev) radeon_acknowledge_irqs(dev_priv); } -int radeon_driver_irq_postinstall(drm_device_t * dev) +int radeon_driver_irq_postinstall(struct drm_device * dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; @@ -276,7 +272,7 @@ int radeon_driver_irq_postinstall(drm_device_t * dev) return 0; } -void radeon_driver_irq_uninstall(drm_device_t * dev) +void radeon_driver_irq_uninstall(struct drm_device * dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; @@ -290,7 +286,7 @@ void radeon_driver_irq_uninstall(drm_device_t * dev) } -int radeon_vblank_crtc_get(drm_device_t *dev) +int radeon_vblank_crtc_get(struct drm_device *dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; u32 flag; @@ -307,12 +303,12 @@ int radeon_vblank_crtc_get(drm_device_t *dev) return value; } -int radeon_vblank_crtc_set(drm_device_t *dev, int64_t value) +int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->vblank_crtc = (unsigned int)value; return 0; diff --git a/shared-core/radeon_mem.c b/shared-core/radeon_mem.c index dbc91c9f..9947e940 100644 --- a/shared-core/radeon_mem.c +++ b/shared-core/radeon_mem.c @@ -39,7 +39,7 @@ */ static struct mem_block *split_block(struct mem_block *p, int start, int size, - DRMFILE filp) + struct drm_file *file_priv) { /* Maybe cut off the start of an existing block */ if (start > p->start) { @@ -49,7 +49,7 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, goto out; newblock->start = start; newblock->size = p->size - (start - p->start); - newblock->filp = NULL; + newblock->file_priv = NULL; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -66,7 +66,7 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, goto out; newblock->start = start + size; newblock->size = p->size - size; - newblock->filp = NULL; + newblock->file_priv = NULL; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; @@ -76,20 +76,20 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, out: /* Our block is in the middle */ - p->filp = filp; + p->file_priv = file_priv; return p; } static struct mem_block *alloc_block(struct mem_block *heap, int size, - int align2, DRMFILE filp) + int align2, struct drm_file *file_priv) { struct mem_block *p; int mask = (1 << align2) - 1; list_for_each(p, heap) { int start = (p->start + mask) & ~mask; - if (p->filp == 0 && start + size <= p->start + p->size) - return split_block(p, start, size, filp); + if (p->file_priv == 0 && start + size <= p->start + p->size) + return split_block(p, start, size, file_priv); } return NULL; @@ -108,12 +108,12 @@ static struct mem_block *find_block(struct mem_block *heap, int start) static void free_block(struct mem_block *p) { - p->filp = NULL; + p->file_priv = NULL; - /* Assumes a single contiguous range. Needs a special filp in + /* Assumes a single contiguous range. Needs a special file_priv in * 'heap' to stop it being subsumed. */ - if (p->next->filp == 0) { + if (p->next->file_priv == 0) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; @@ -121,7 +121,7 @@ static void free_block(struct mem_block *p) drm_free(q, sizeof(*q), DRM_MEM_BUFS); } - if (p->prev->filp == 0) { + if (p->prev->file_priv == 0) { struct mem_block *q = p->prev; q->size += p->size; q->next = p->next; @@ -137,28 +137,28 @@ static int init_heap(struct mem_block **heap, int start, int size) struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS); if (!blocks) - return DRM_ERR(ENOMEM); + return -ENOMEM; *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS); if (!*heap) { drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS); - return DRM_ERR(ENOMEM); + return -ENOMEM; } blocks->start = start; blocks->size = size; - blocks->filp = NULL; + blocks->file_priv = NULL; blocks->next = blocks->prev = *heap; memset(*heap, 0, sizeof(**heap)); - (*heap)->filp = (DRMFILE) - 1; + (*heap)->file_priv = (struct drm_file *) - 1; (*heap)->next = (*heap)->prev = blocks; return 0; } /* Free all blocks associated with the releasing file. */ -void radeon_mem_release(DRMFILE filp, struct mem_block *heap) +void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap) { struct mem_block *p; @@ -166,15 +166,15 @@ void radeon_mem_release(DRMFILE filp, struct mem_block *heap) return; list_for_each(p, heap) { - if (p->filp == filp) - p->filp = NULL; + if (p->file_priv == file_priv) + p->file_priv = NULL; } - /* Assumes a single contiguous range. Needs a special filp in + /* Assumes a single contiguous range. Needs a special file_priv in * 'heap' to stop it being subsumed. */ list_for_each(p, heap) { - while (p->filp == 0 && p->next->filp == 0) { + while (p->file_priv == 0 && p->next->file_priv == 0) { struct mem_block *q = p->next; p->size += q->size; p->next = q->next; @@ -217,98 +217,86 @@ static struct mem_block **get_heap(drm_radeon_private_t * dev_priv, int region) } } -int radeon_mem_alloc(DRM_IOCTL_ARGS) +int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_mem_alloc_t alloc; + drm_radeon_mem_alloc_t *alloc = data; struct mem_block *block, **heap; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(alloc, (drm_radeon_mem_alloc_t __user *) data, - sizeof(alloc)); - - heap = get_heap(dev_priv, alloc.region); + heap = get_heap(dev_priv, alloc->region); if (!heap || !*heap) - return DRM_ERR(EFAULT); + return -EFAULT; /* Make things easier on ourselves: all allocations at least * 4k aligned. */ - if (alloc.alignment < 12) - alloc.alignment = 12; + if (alloc->alignment < 12) + alloc->alignment = 12; - block = alloc_block(*heap, alloc.size, alloc.alignment, filp); + block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv); if (!block) - return DRM_ERR(ENOMEM); + return -ENOMEM; - if (DRM_COPY_TO_USER(alloc.region_offset, &block->start, sizeof(int))) { + if (DRM_COPY_TO_USER(alloc->region_offset, &block->start, + sizeof(int))) { DRM_ERROR("copy_to_user\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } return 0; } -int radeon_mem_free(DRM_IOCTL_ARGS) +int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_mem_free_t memfree; + drm_radeon_mem_free_t *memfree = data; struct mem_block *block, **heap; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data, - sizeof(memfree)); - - heap = get_heap(dev_priv, memfree.region); + heap = get_heap(dev_priv, memfree->region); if (!heap || !*heap) - return DRM_ERR(EFAULT); + return -EFAULT; - block = find_block(*heap, memfree.region_offset); + block = find_block(*heap, memfree->region_offset); if (!block) - return DRM_ERR(EFAULT); + return -EFAULT; - if (block->filp != filp) - return DRM_ERR(EPERM); + if (block->file_priv != file_priv) + return -EPERM; free_block(block); return 0; } -int radeon_mem_init_heap(DRM_IOCTL_ARGS) +int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_mem_init_heap_t initheap; + drm_radeon_mem_init_heap_t *initheap = data; struct mem_block **heap; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(initheap, - (drm_radeon_mem_init_heap_t __user *) data, - sizeof(initheap)); - - heap = get_heap(dev_priv, initheap.region); + heap = get_heap(dev_priv, initheap->region); if (!heap) - return DRM_ERR(EFAULT); + return -EFAULT; if (*heap) { DRM_ERROR("heap already initialized?"); - return DRM_ERR(EFAULT); + return -EFAULT; } - return init_heap(heap, initheap.start, initheap.size); + return init_heap(heap, initheap->start, initheap->size); } diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 8ccd0981..e3aadfb9 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -39,7 +39,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * dev_priv, - drm_file_t * filp_priv, + struct drm_file *file_priv, u32 * offset) { u64 off = *offset; @@ -71,7 +71,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * * magic offset we get from SETPARAM or calculated from fb_location */ if (off < (dev_priv->fb_size + dev_priv->gart_size)) { - radeon_priv = filp_priv->driver_priv; + radeon_priv = file_priv->driver_priv; off += radeon_priv->radeon_fb_delta; } @@ -85,29 +85,29 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * *offset = off; return 0; } - return DRM_ERR(EINVAL); + return -EINVAL; } static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * dev_priv, - drm_file_t * filp_priv, + struct drm_file *file_priv, int id, u32 *data) { switch (id) { case RADEON_EMIT_PP_MISC: - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &data[(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4])) { DRM_ERROR("Invalid depth buffer offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } break; case RADEON_EMIT_PP_CNTL: - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &data[(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4])) { DRM_ERROR("Invalid colour buffer offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } break; @@ -117,20 +117,20 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * case R200_EMIT_PP_TXOFFSET_3: case R200_EMIT_PP_TXOFFSET_4: case R200_EMIT_PP_TXOFFSET_5: - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &data[0])) { DRM_ERROR("Invalid R200 texture offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } break; case RADEON_EMIT_PP_TXFILTER_0: case RADEON_EMIT_PP_TXFILTER_1: case RADEON_EMIT_PP_TXFILTER_2: - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &data[(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4])) { DRM_ERROR("Invalid R100 texture offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } break; @@ -143,11 +143,11 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * int i; for (i = 0; i < 5; i++) { if (radeon_check_and_fixup_offset(dev_priv, - filp_priv, + file_priv, &data[i])) { DRM_ERROR ("Invalid R200 cubic texture offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } } break; @@ -159,11 +159,11 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * int i; for (i = 0; i < 5; i++) { if (radeon_check_and_fixup_offset(dev_priv, - filp_priv, + file_priv, &data[i])) { DRM_ERROR ("Invalid R100 cubic texture offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } } } @@ -256,7 +256,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * default: DRM_ERROR("Unknown state packet ID %d\n", id); - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; @@ -264,7 +264,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * dev_priv, - drm_file_t *filp_priv, + struct drm_file *file_priv, drm_radeon_kcmd_buffer_t * cmdbuf, unsigned int *cmdsz) @@ -277,12 +277,12 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * if ((cmd[0] & 0xc0000000) != RADEON_CP_PACKET3) { DRM_ERROR("Not a type 3 packet\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (4 * *cmdsz > cmdbuf->bufsz) { DRM_ERROR("Packet size larger than size of data provided\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } switch(cmd[0] & 0xff00) { @@ -307,7 +307,7 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * /* safe but r200 only */ if (dev_priv->microcode_version != UCODE_R200) { DRM_ERROR("Invalid 3d packet for r100-class chip\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } break; @@ -317,7 +317,7 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * if (count > 18) { /* 12 arrays max */ DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", count); - return DRM_ERR(EINVAL); + return -EINVAL; } /* carefully check packet contents */ @@ -326,22 +326,25 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * i = 2; while ((k < narrays) && (i < (count + 2))) { i++; /* skip attribute field */ - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) { + if (radeon_check_and_fixup_offset(dev_priv, file_priv, + &cmd[i])) { DRM_ERROR ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", k, i); - return DRM_ERR(EINVAL); + return -EINVAL; } k++; i++; if (k == narrays) break; /* have one more to process, they come in pairs */ - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) { + if (radeon_check_and_fixup_offset(dev_priv, + file_priv, &cmd[i])) + { DRM_ERROR ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", k, i); - return DRM_ERR(EINVAL); + return -EINVAL; } k++; i++; @@ -351,33 +354,33 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * DRM_ERROR ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", k, i, narrays, count + 1); - return DRM_ERR(EINVAL); + return -EINVAL; } break; case RADEON_3D_RNDR_GEN_INDX_PRIM: if (dev_priv->microcode_version != UCODE_R100) { DRM_ERROR("Invalid 3d packet for r200-class chip\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[1])) { + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[1])) { DRM_ERROR("Invalid rndr_gen_indx offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } break; case RADEON_CP_INDX_BUFFER: if (dev_priv->microcode_version != UCODE_R200) { DRM_ERROR("Invalid 3d packet for r100-class chip\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if ((cmd[1] & 0x8000ffff) != 0x80000810) { DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]); - return DRM_ERR(EINVAL); + return -EINVAL; } - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[2])) { + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[2])) { DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]); - return DRM_ERR(EINVAL); + return -EINVAL; } break; @@ -389,9 +392,9 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { offset = cmd[2] << 10; if (radeon_check_and_fixup_offset - (dev_priv, filp_priv, &offset)) { + (dev_priv, file_priv, &offset)) { DRM_ERROR("Invalid first packet offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } cmd[2] = (cmd[2] & 0xffc00000) | offset >> 10; } @@ -400,9 +403,9 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { offset = cmd[3] << 10; if (radeon_check_and_fixup_offset - (dev_priv, filp_priv, &offset)) { + (dev_priv, file_priv, &offset)) { DRM_ERROR("Invalid second packet offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10; } @@ -410,7 +413,7 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * default: DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00); - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; @@ -421,7 +424,7 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * */ static __inline__ void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv, - drm_clip_rect_t * box) + struct drm_clip_rect * box) { RING_LOCALS; @@ -439,7 +442,7 @@ static __inline__ void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv, /* Emit 1.1 state */ static int radeon_emit_state(drm_radeon_private_t * dev_priv, - drm_file_t * filp_priv, + struct drm_file *file_priv, drm_radeon_context_regs_t * ctx, drm_radeon_texture_regs_t * tex, unsigned int dirty) @@ -448,16 +451,16 @@ static int radeon_emit_state(drm_radeon_private_t * dev_priv, DRM_DEBUG("dirty=0x%08x\n", dirty); if (dirty & RADEON_UPLOAD_CONTEXT) { - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &ctx->rb3d_depthoffset)) { DRM_ERROR("Invalid depth buffer offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &ctx->rb3d_coloroffset)) { DRM_ERROR("Invalid depth buffer offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } BEGIN_RING(14); @@ -543,10 +546,10 @@ static int radeon_emit_state(drm_radeon_private_t * dev_priv, } if (dirty & RADEON_UPLOAD_TEX0) { - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex[0].pp_txoffset)) { DRM_ERROR("Invalid texture offset for unit 0\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } BEGIN_RING(9); @@ -563,10 +566,10 @@ static int radeon_emit_state(drm_radeon_private_t * dev_priv, } if (dirty & RADEON_UPLOAD_TEX1) { - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex[1].pp_txoffset)) { DRM_ERROR("Invalid texture offset for unit 1\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } BEGIN_RING(9); @@ -583,10 +586,10 @@ static int radeon_emit_state(drm_radeon_private_t * dev_priv, } if (dirty & RADEON_UPLOAD_TEX2) { - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex[2].pp_txoffset)) { DRM_ERROR("Invalid texture offset for unit 2\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } BEGIN_RING(9); @@ -608,7 +611,7 @@ static int radeon_emit_state(drm_radeon_private_t * dev_priv, /* Emit 1.2 state */ static int radeon_emit_state2(drm_radeon_private_t * dev_priv, - drm_file_t * filp_priv, + struct drm_file *file_priv, drm_radeon_state_t * state) { RING_LOCALS; @@ -621,7 +624,7 @@ static int radeon_emit_state2(drm_radeon_private_t * dev_priv, ADVANCE_RING(); } - return radeon_emit_state(dev_priv, filp_priv, &state->context, + return radeon_emit_state(dev_priv, file_priv, &state->context, state->tex, state->dirty); } @@ -844,7 +847,7 @@ static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv) * CP command dispatch functions */ -static void radeon_cp_dispatch_clear(drm_device_t * dev, +static void radeon_cp_dispatch_clear(struct drm_device * dev, drm_radeon_clear_t * clear, drm_radeon_clear_rect_t * depth_boxes) { @@ -852,7 +855,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; int nbox = sarea_priv->nbox; - drm_clip_rect_t *pbox = sarea_priv->boxes; + struct drm_clip_rect *pbox = sarea_priv->boxes; unsigned int flags = clear->flags; u32 rb3d_cntl = 0, rb3d_stencilrefmask = 0; int i; @@ -1335,12 +1338,12 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, ADVANCE_RING(); } -static void radeon_cp_dispatch_swap(drm_device_t * dev) +static void radeon_cp_dispatch_swap(struct drm_device * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; int nbox = sarea_priv->nbox; - drm_clip_rect_t *pbox = sarea_priv->boxes; + struct drm_clip_rect *pbox = sarea_priv->boxes; int i; RING_LOCALS; DRM_DEBUG("\n"); @@ -1412,10 +1415,10 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev) ADVANCE_RING(); } -static void radeon_cp_dispatch_flip(drm_device_t * dev) +static void radeon_cp_dispatch_flip(struct drm_device * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_sarea_t *sarea = (drm_sarea_t *) dev_priv->sarea->handle; + struct drm_sarea *sarea = (struct drm_sarea *) dev_priv->sarea->handle; int offset = (dev_priv->sarea_priv->pfCurrentPage == 1) ? dev_priv->front_offset : dev_priv->back_offset; RING_LOCALS; @@ -1491,8 +1494,8 @@ typedef struct { unsigned int vc_format; } drm_radeon_tcl_prim_t; -static void radeon_cp_dispatch_vertex(drm_device_t * dev, - drm_buf_t * buf, +static void radeon_cp_dispatch_vertex(struct drm_device * dev, + struct drm_buf * buf, drm_radeon_tcl_prim_t * prim) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -1537,7 +1540,7 @@ static void radeon_cp_dispatch_vertex(drm_device_t * dev, } while (i < nbox); } -static void radeon_cp_discard_buffer(drm_device_t * dev, drm_buf_t * buf) +static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_buf_priv_t *buf_priv = buf->dev_private; @@ -1554,8 +1557,8 @@ static void radeon_cp_discard_buffer(drm_device_t * dev, drm_buf_t * buf) buf->used = 0; } -static void radeon_cp_dispatch_indirect(drm_device_t * dev, - drm_buf_t * buf, int start, int end) +static void radeon_cp_dispatch_indirect(struct drm_device * dev, + struct drm_buf * buf, int start, int end) { drm_radeon_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -1588,8 +1591,8 @@ static void radeon_cp_dispatch_indirect(drm_device_t * dev, } } -static void radeon_cp_dispatch_indices(drm_device_t * dev, - drm_buf_t * elt_buf, +static void radeon_cp_dispatch_indices(struct drm_device * dev, + struct drm_buf * elt_buf, drm_radeon_tcl_prim_t * prim) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -1646,14 +1649,13 @@ static void radeon_cp_dispatch_indices(drm_device_t * dev, #define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE -static int radeon_cp_dispatch_texture(DRMFILE filp, - drm_device_t * dev, +static int radeon_cp_dispatch_texture(struct drm_device * dev, + struct drm_file *file_priv, drm_radeon_texture_t * tex, drm_radeon_tex_image_t * image) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_file_t *filp_priv; - drm_buf_t *buf; + struct drm_buf *buf; u32 format; u32 *buffer; const u8 __user *data; @@ -1664,11 +1666,9 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, u32 offset; RING_LOCALS; - DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - - if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &tex->offset)) { + if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) { DRM_ERROR("Invalid destination offset\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD; @@ -1711,11 +1711,11 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, break; default: DRM_ERROR("invalid texture format %d\n", tex->format); - return DRM_ERR(EINVAL); + return -EINVAL; } spitch = blit_width >> 6; if (spitch == 0 && image->height > 1) - return DRM_ERR(EINVAL); + return -EINVAL; texpitch = tex->pitch; if ((texpitch << 22) & RADEON_DST_TILE_MICRO) { @@ -1760,8 +1760,8 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, if (!buf) { DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n"); if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image))) - return DRM_ERR(EFAULT); - return DRM_ERR(EAGAIN); + return -EFAULT; + return -EAGAIN; } /* Dispatch the indirect buffer. @@ -1774,7 +1774,7 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, do { \ if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\ DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \ - return DRM_ERR(EFAULT); \ + return -EFAULT; \ } \ } while(0) @@ -1841,7 +1841,7 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, } #undef RADEON_COPY_MT - buf->filp = filp; + buf->file_priv = file_priv; buf->used = size; offset = dev_priv->gart_buffers_offset + buf->offset; BEGIN_RING(9); @@ -1861,6 +1861,7 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, OUT_RING((image->width << 16) | height); RADEON_WAIT_UNTIL_2D_IDLE(); ADVANCE_RING(); + COMMIT_RING(); radeon_cp_discard_buffer(dev, buf); @@ -1878,10 +1879,12 @@ static int radeon_cp_dispatch_texture(DRMFILE filp, RADEON_FLUSH_CACHE(); RADEON_WAIT_UNTIL_2D_IDLE(); ADVANCE_RING(); + COMMIT_RING(); + return 0; } -static void radeon_cp_dispatch_stipple(drm_device_t * dev, u32 * stipple) +static void radeon_cp_dispatch_stipple(struct drm_device * dev, u32 * stipple) { drm_radeon_private_t *dev_priv = dev->dev_private; int i; @@ -1929,7 +1932,8 @@ static void radeon_apply_surface_regs(int surf_index, * not always be available. */ static int alloc_surface(drm_radeon_surface_alloc_t *new, - drm_radeon_private_t *dev_priv, DRMFILE filp) + drm_radeon_private_t *dev_priv, + struct drm_file *file_priv) { struct radeon_virt_surface *s; int i; @@ -1959,7 +1963,7 @@ static int alloc_surface(drm_radeon_surface_alloc_t *new, /* find a virtual surface */ for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) - if (dev_priv->virt_surfaces[i].filp == 0) + if (dev_priv->virt_surfaces[i].file_priv == 0) break; if (i == 2 * RADEON_MAX_SURFACES) { return -1; @@ -1977,7 +1981,7 @@ static int alloc_surface(drm_radeon_surface_alloc_t *new, s->lower = new_lower; s->upper = new_upper; s->flags = new->flags; - s->filp = filp; + s->file_priv = file_priv; dev_priv->surfaces[i].refcount++; dev_priv->surfaces[i].lower = s->lower; radeon_apply_surface_regs(s->surface_index, dev_priv); @@ -1993,7 +1997,7 @@ static int alloc_surface(drm_radeon_surface_alloc_t *new, s->lower = new_lower; s->upper = new_upper; s->flags = new->flags; - s->filp = filp; + s->file_priv = file_priv; dev_priv->surfaces[i].refcount++; dev_priv->surfaces[i].upper = s->upper; radeon_apply_surface_regs(s->surface_index, dev_priv); @@ -2009,7 +2013,7 @@ static int alloc_surface(drm_radeon_surface_alloc_t *new, s->lower = new_lower; s->upper = new_upper; s->flags = new->flags; - s->filp = filp; + s->file_priv = file_priv; dev_priv->surfaces[i].refcount = 1; dev_priv->surfaces[i].lower = s->lower; dev_priv->surfaces[i].upper = s->upper; @@ -2023,7 +2027,8 @@ static int alloc_surface(drm_radeon_surface_alloc_t *new, return -1; } -static int free_surface(DRMFILE filp, drm_radeon_private_t * dev_priv, +static int free_surface(struct drm_file *file_priv, + drm_radeon_private_t * dev_priv, int lower) { struct radeon_virt_surface *s; @@ -2031,8 +2036,9 @@ static int free_surface(DRMFILE filp, drm_radeon_private_t * dev_priv, /* find the virtual surface */ for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) { s = &(dev_priv->virt_surfaces[i]); - if (s->filp) { - if ((lower == s->lower) && (filp == s->filp)) { + if (s->file_priv) { + if ((lower == s->lower) && (file_priv == s->file_priv)) + { if (dev_priv->surfaces[s->surface_index]. lower == s->lower) dev_priv->surfaces[s->surface_index]. @@ -2048,7 +2054,7 @@ static int free_surface(DRMFILE filp, drm_radeon_private_t * dev_priv, refcount == 0) dev_priv->surfaces[s->surface_index]. flags = 0; - s->filp = NULL; + s->file_priv = NULL; radeon_apply_surface_regs(s->surface_index, dev_priv); return 0; @@ -2058,13 +2064,13 @@ static int free_surface(DRMFILE filp, drm_radeon_private_t * dev_priv, return 1; } -static void radeon_surfaces_release(DRMFILE filp, +static void radeon_surfaces_release(struct drm_file *file_priv, drm_radeon_private_t * dev_priv) { int i; for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) { - if (dev_priv->virt_surfaces[i].filp == filp) - free_surface(filp, dev_priv, + if (dev_priv->virt_surfaces[i].file_priv == file_priv) + free_surface(file_priv, dev_priv, dev_priv->virt_surfaces[i].lower); } } @@ -2072,71 +2078,58 @@ static void radeon_surfaces_release(DRMFILE filp, /* ================================================================ * IOCTL functions */ -static int radeon_surface_alloc(DRM_IOCTL_ARGS) +static int radeon_surface_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_surface_alloc_t alloc; + drm_radeon_surface_alloc_t *alloc = data; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(alloc, - (drm_radeon_surface_alloc_t __user *) data, - sizeof(alloc)); - - if (alloc_surface(&alloc, dev_priv, filp) == -1) - return DRM_ERR(EINVAL); + if (alloc_surface(alloc, dev_priv, file_priv) == -1) + return -EINVAL; else return 0; } -static int radeon_surface_free(DRM_IOCTL_ARGS) +static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_surface_free_t memfree; + drm_radeon_surface_free_t *memfree = data; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_surface_free_t __user *) data, - sizeof(memfree)); - - if (free_surface(filp, dev_priv, memfree.address)) - return DRM_ERR(EINVAL); + if (free_surface(file_priv, dev_priv, memfree->address)) + return -EINVAL; else return 0; } -static int radeon_cp_clear(DRM_IOCTL_ARGS) +static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_radeon_clear_t clear; + drm_radeon_clear_t *clear = data; drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(clear, (drm_radeon_clear_t __user *) data, - sizeof(clear)); + LOCK_TEST_WITH_RETURN(dev, file_priv); RING_SPACE_TEST_WITH_RETURN(dev_priv); if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - if (DRM_COPY_FROM_USER(&depth_boxes, clear.depth_boxes, + if (DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes, sarea_priv->nbox * sizeof(depth_boxes[0]))) - return DRM_ERR(EFAULT); + return -EFAULT; - radeon_cp_dispatch_clear(dev, &clear, depth_boxes); + radeon_cp_dispatch_clear(dev, clear, depth_boxes); COMMIT_RING(); return 0; @@ -2144,7 +2137,7 @@ static int radeon_cp_clear(DRM_IOCTL_ARGS) /* Not sure why this isn't set all the time: */ -static int radeon_do_init_pageflip(drm_device_t * dev) +static int radeon_do_init_pageflip(struct drm_device * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -2172,13 +2165,12 @@ static int radeon_do_init_pageflip(drm_device_t * dev) /* Swapping and flipping are different operations, need different ioctls. * They can & should be intermixed to support multiple 3d windows. */ -static int radeon_cp_flip(DRM_IOCTL_ARGS) +static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); RING_SPACE_TEST_WITH_RETURN(dev_priv); @@ -2191,14 +2183,13 @@ static int radeon_cp_flip(DRM_IOCTL_ARGS) return 0; } -static int radeon_cp_swap(DRM_IOCTL_ARGS) +static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); RING_SPACE_TEST_WITH_RETURN(dev_priv); @@ -2212,71 +2203,64 @@ static int radeon_cp_swap(DRM_IOCTL_ARGS) return 0; } -static int radeon_cp_vertex(DRM_IOCTL_ARGS) +static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_file_t *filp_priv; drm_radeon_sarea_t *sarea_priv; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; - drm_radeon_vertex_t vertex; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; + drm_radeon_vertex_t *vertex = data; drm_radeon_tcl_prim_t prim; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } sarea_priv = dev_priv->sarea_priv; - DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - - DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, - sizeof(vertex)); - DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", - DRM_CURRENTPID, vertex.idx, vertex.count, vertex.discard); + DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard); - if (vertex.idx < 0 || vertex.idx >= dma->buf_count) { + if (vertex->idx < 0 || vertex->idx >= dma->buf_count) { DRM_ERROR("buffer index %d (of %d max)\n", - vertex.idx, dma->buf_count - 1); - return DRM_ERR(EINVAL); + vertex->idx, dma->buf_count - 1); + return -EINVAL; } - if (vertex.prim < 0 || vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) { - DRM_ERROR("buffer prim %d\n", vertex.prim); - return DRM_ERR(EINVAL); + if (vertex->prim < 0 || vertex->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) { + DRM_ERROR("buffer prim %d\n", vertex->prim); + return -EINVAL; } RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); - buf = dma->buflist[vertex.idx]; + buf = dma->buflist[vertex->idx]; - if (buf->filp != filp) { + if (buf->file_priv != file_priv) { DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, buf->file_priv); + return -EINVAL; } if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", vertex.idx); - return DRM_ERR(EINVAL); + DRM_ERROR("sending pending buffer %d\n", vertex->idx); + return -EINVAL; } /* Build up a prim_t record: */ - if (vertex.count) { - buf->used = vertex.count; /* not used? */ + if (vertex->count) { + buf->used = vertex->count; /* not used? */ if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) { - if (radeon_emit_state(dev_priv, filp_priv, + if (radeon_emit_state(dev_priv, file_priv, &sarea_priv->context_state, sarea_priv->tex_state, sarea_priv->dirty)) { DRM_ERROR("radeon_emit_state failed\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | @@ -2286,15 +2270,15 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS) } prim.start = 0; - prim.finish = vertex.count; /* unused */ - prim.prim = vertex.prim; - prim.numverts = vertex.count; + prim.finish = vertex->count; /* unused */ + prim.prim = vertex->prim; + prim.numverts = vertex->count; prim.vc_format = dev_priv->sarea_priv->vc_format; radeon_cp_dispatch_vertex(dev, buf, &prim); } - if (vertex.discard) { + if (vertex->discard) { radeon_cp_discard_buffer(dev, buf); } @@ -2302,80 +2286,74 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS) return 0; } -static int radeon_cp_indices(DRM_IOCTL_ARGS) +static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_file_t *filp_priv; drm_radeon_sarea_t *sarea_priv; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; - drm_radeon_indices_t elts; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; + drm_radeon_indices_t *elts = data; drm_radeon_tcl_prim_t prim; int count; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } sarea_priv = dev_priv->sarea_priv; - DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - - DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data, - sizeof(elts)); - DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n", - DRM_CURRENTPID, elts.idx, elts.start, elts.end, elts.discard); + DRM_CURRENTPID, elts->idx, elts->start, elts->end, + elts->discard); - if (elts.idx < 0 || elts.idx >= dma->buf_count) { + if (elts->idx < 0 || elts->idx >= dma->buf_count) { DRM_ERROR("buffer index %d (of %d max)\n", - elts.idx, dma->buf_count - 1); - return DRM_ERR(EINVAL); + elts->idx, dma->buf_count - 1); + return -EINVAL; } - if (elts.prim < 0 || elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) { - DRM_ERROR("buffer prim %d\n", elts.prim); - return DRM_ERR(EINVAL); + if (elts->prim < 0 || elts->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) { + DRM_ERROR("buffer prim %d\n", elts->prim); + return -EINVAL; } RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); - buf = dma->buflist[elts.idx]; + buf = dma->buflist[elts->idx]; - if (buf->filp != filp) { + if (buf->file_priv != file_priv) { DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, buf->file_priv); + return -EINVAL; } if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", elts.idx); - return DRM_ERR(EINVAL); + DRM_ERROR("sending pending buffer %d\n", elts->idx); + return -EINVAL; } - count = (elts.end - elts.start) / sizeof(u16); - elts.start -= RADEON_INDEX_PRIM_OFFSET; + count = (elts->end - elts->start) / sizeof(u16); + elts->start -= RADEON_INDEX_PRIM_OFFSET; - if (elts.start & 0x7) { - DRM_ERROR("misaligned buffer 0x%x\n", elts.start); - return DRM_ERR(EINVAL); + if (elts->start & 0x7) { + DRM_ERROR("misaligned buffer 0x%x\n", elts->start); + return -EINVAL; } - if (elts.start < buf->used) { - DRM_ERROR("no header 0x%x - 0x%x\n", elts.start, buf->used); - return DRM_ERR(EINVAL); + if (elts->start < buf->used) { + DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used); + return -EINVAL; } - buf->used = elts.end; + buf->used = elts->end; if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) { - if (radeon_emit_state(dev_priv, filp_priv, + if (radeon_emit_state(dev_priv, file_priv, &sarea_priv->context_state, sarea_priv->tex_state, sarea_priv->dirty)) { DRM_ERROR("radeon_emit_state failed\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | @@ -2386,15 +2364,15 @@ static int radeon_cp_indices(DRM_IOCTL_ARGS) /* Build up a prim_t record: */ - prim.start = elts.start; - prim.finish = elts.end; - prim.prim = elts.prim; + prim.start = elts->start; + prim.finish = elts->end; + prim.prim = elts->prim; prim.offset = 0; /* offset from start of dma buffers */ prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ prim.vc_format = dev_priv->sarea_priv->vc_format; radeon_cp_dispatch_indices(dev, buf, &prim); - if (elts.discard) { + if (elts->discard) { radeon_cp_discard_buffer(dev, buf); } @@ -2402,52 +2380,43 @@ static int radeon_cp_indices(DRM_IOCTL_ARGS) return 0; } -static int radeon_cp_texture(DRM_IOCTL_ARGS) +static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_texture_t tex; + drm_radeon_texture_t *tex = data; drm_radeon_tex_image_t image; int ret; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(tex, (drm_radeon_texture_t __user *) data, - sizeof(tex)); + LOCK_TEST_WITH_RETURN(dev, file_priv); - if (tex.image == NULL) { + if (tex->image == NULL) { DRM_ERROR("null texture image!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (DRM_COPY_FROM_USER(&image, - (drm_radeon_tex_image_t __user *) tex.image, + (drm_radeon_tex_image_t __user *) tex->image, sizeof(image))) - return DRM_ERR(EFAULT); + return -EFAULT; RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); - ret = radeon_cp_dispatch_texture(filp, dev, &tex, &image); + ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image); - COMMIT_RING(); return ret; } -static int radeon_cp_stipple(DRM_IOCTL_ARGS) +static int radeon_cp_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_stipple_t stipple; + drm_radeon_stipple_t *stipple = data; u32 mask[32]; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(stipple, (drm_radeon_stipple_t __user *) data, - sizeof(stipple)); + LOCK_TEST_WITH_RETURN(dev, file_priv); - if (DRM_COPY_FROM_USER(&mask, stipple.mask, 32 * sizeof(u32))) - return DRM_ERR(EFAULT); + if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32))) + return -EFAULT; RING_SPACE_TEST_WITH_RETURN(dev_priv); @@ -2457,57 +2426,53 @@ static int radeon_cp_stipple(DRM_IOCTL_ARGS) return 0; } -static int radeon_cp_indirect(DRM_IOCTL_ARGS) +static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; - drm_radeon_indirect_t indirect; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; + drm_radeon_indirect_t *indirect = data; RING_LOCALS; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(indirect, - (drm_radeon_indirect_t __user *) data, - sizeof(indirect)); - DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n", - indirect.idx, indirect.start, indirect.end, indirect.discard); + indirect->idx, indirect->start, indirect->end, + indirect->discard); - if (indirect.idx < 0 || indirect.idx >= dma->buf_count) { + if (indirect->idx < 0 || indirect->idx >= dma->buf_count) { DRM_ERROR("buffer index %d (of %d max)\n", - indirect.idx, dma->buf_count - 1); - return DRM_ERR(EINVAL); + indirect->idx, dma->buf_count - 1); + return -EINVAL; } - buf = dma->buflist[indirect.idx]; + buf = dma->buflist[indirect->idx]; - if (buf->filp != filp) { + if (buf->file_priv != file_priv) { DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, buf->file_priv); + return -EINVAL; } if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", indirect.idx); - return DRM_ERR(EINVAL); + DRM_ERROR("sending pending buffer %d\n", indirect->idx); + return -EINVAL; } - if (indirect.start < buf->used) { + if (indirect->start < buf->used) { DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n", - indirect.start, buf->used); - return DRM_ERR(EINVAL); + indirect->start, buf->used); + return -EINVAL; } RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); - buf->used = indirect.end; + buf->used = indirect->end; /* Wait for the 3D stream to idle before the indirect buffer * containing 2D acceleration commands is processed. @@ -2522,8 +2487,8 @@ static int radeon_cp_indirect(DRM_IOCTL_ARGS) * X server. This is insecure and is thus only available to * privileged clients. */ - radeon_cp_dispatch_indirect(dev, buf, indirect.start, indirect.end); - if (indirect.discard) { + radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); + if (indirect->discard) { radeon_cp_discard_buffer(dev, buf); } @@ -2531,78 +2496,71 @@ static int radeon_cp_indirect(DRM_IOCTL_ARGS) return 0; } -static int radeon_cp_vertex2(DRM_IOCTL_ARGS) +static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_file_t *filp_priv; drm_radeon_sarea_t *sarea_priv; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; - drm_radeon_vertex2_t vertex; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; + drm_radeon_vertex2_t *vertex = data; int i; unsigned char laststate; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } sarea_priv = dev_priv->sarea_priv; - DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - - DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data, - sizeof(vertex)); - DRM_DEBUG("pid=%d index=%d discard=%d\n", - DRM_CURRENTPID, vertex.idx, vertex.discard); + DRM_CURRENTPID, vertex->idx, vertex->discard); - if (vertex.idx < 0 || vertex.idx >= dma->buf_count) { + if (vertex->idx < 0 || vertex->idx >= dma->buf_count) { DRM_ERROR("buffer index %d (of %d max)\n", - vertex.idx, dma->buf_count - 1); - return DRM_ERR(EINVAL); + vertex->idx, dma->buf_count - 1); + return -EINVAL; } RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); - buf = dma->buflist[vertex.idx]; + buf = dma->buflist[vertex->idx]; - if (buf->filp != filp) { + if (buf->file_priv != file_priv) { DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->filp); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, buf->file_priv); + return -EINVAL; } if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", vertex.idx); - return DRM_ERR(EINVAL); + DRM_ERROR("sending pending buffer %d\n", vertex->idx); + return -EINVAL; } if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) - return DRM_ERR(EINVAL); + return -EINVAL; - for (laststate = 0xff, i = 0; i < vertex.nr_prims; i++) { + for (laststate = 0xff, i = 0; i < vertex->nr_prims; i++) { drm_radeon_prim_t prim; drm_radeon_tcl_prim_t tclprim; - if (DRM_COPY_FROM_USER(&prim, &vertex.prim[i], sizeof(prim))) - return DRM_ERR(EFAULT); + if (DRM_COPY_FROM_USER(&prim, &vertex->prim[i], sizeof(prim))) + return -EFAULT; if (prim.stateidx != laststate) { drm_radeon_state_t state; if (DRM_COPY_FROM_USER(&state, - &vertex.state[prim.stateidx], + &vertex->state[prim.stateidx], sizeof(state))) - return DRM_ERR(EFAULT); + return -EFAULT; - if (radeon_emit_state2(dev_priv, filp_priv, &state)) { + if (radeon_emit_state2(dev_priv, file_priv, &state)) { DRM_ERROR("radeon_emit_state2 failed\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } laststate = prim.stateidx; @@ -2629,7 +2587,7 @@ static int radeon_cp_vertex2(DRM_IOCTL_ARGS) sarea_priv->nbox = 0; } - if (vertex.discard) { + if (vertex->discard) { radeon_cp_discard_buffer(dev, buf); } @@ -2638,7 +2596,7 @@ static int radeon_cp_vertex2(DRM_IOCTL_ARGS) } static int radeon_emit_packets(drm_radeon_private_t * dev_priv, - drm_file_t * filp_priv, + struct drm_file *file_priv, drm_radeon_cmd_header_t header, drm_radeon_kcmd_buffer_t *cmdbuf) { @@ -2648,19 +2606,19 @@ static int radeon_emit_packets(drm_radeon_private_t * dev_priv, RING_LOCALS; if (id >= RADEON_MAX_STATE_PACKETS) - return DRM_ERR(EINVAL); + return -EINVAL; sz = packet[id].len; reg = packet[id].start; if (sz * sizeof(int) > cmdbuf->bufsz) { DRM_ERROR("Packet size provided larger than data provided\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } - if (radeon_check_and_fixup_packets(dev_priv, filp_priv, id, data)) { + if (radeon_check_and_fixup_packets(dev_priv, file_priv, id, data)) { DRM_ERROR("Packet verification failed\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } BEGIN_RING(sz + 1); @@ -2748,7 +2706,7 @@ static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv, if (!sz) return 0; if (sz * 4 > cmdbuf->bufsz) - return DRM_ERR(EINVAL); + return -EINVAL; BEGIN_RING(5 + sz); OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); @@ -2763,8 +2721,8 @@ static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv, return 0; } -static int radeon_emit_packet3(drm_device_t * dev, - drm_file_t * filp_priv, +static int radeon_emit_packet3(struct drm_device * dev, + struct drm_file *file_priv, drm_radeon_kcmd_buffer_t *cmdbuf) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2774,7 +2732,7 @@ static int radeon_emit_packet3(drm_device_t * dev, DRM_DEBUG("\n"); - if ((ret = radeon_check_and_fixup_packet3(dev_priv, filp_priv, + if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv, cmdbuf, &cmdsz))) { DRM_ERROR("Packet verification failed\n"); return ret; @@ -2789,22 +2747,22 @@ static int radeon_emit_packet3(drm_device_t * dev, return 0; } -static int radeon_emit_packet3_cliprect(drm_device_t *dev, - drm_file_t *filp_priv, +static int radeon_emit_packet3_cliprect(struct drm_device *dev, + struct drm_file *file_priv, drm_radeon_kcmd_buffer_t *cmdbuf, int orig_nbox) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_clip_rect_t box; + struct drm_clip_rect box; unsigned int cmdsz; int ret; - drm_clip_rect_t __user *boxes = cmdbuf->boxes; + struct drm_clip_rect __user *boxes = cmdbuf->boxes; int i = 0; RING_LOCALS; DRM_DEBUG("\n"); - if ((ret = radeon_check_and_fixup_packet3(dev_priv, filp_priv, + if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv, cmdbuf, &cmdsz))) { DRM_ERROR("Packet verification failed\n"); return ret; @@ -2816,7 +2774,7 @@ static int radeon_emit_packet3_cliprect(drm_device_t *dev, do { if (i < cmdbuf->nbox) { if (DRM_COPY_FROM_USER(&box, &boxes[i], sizeof(box))) - return DRM_ERR(EFAULT); + return -EFAULT; /* FIXME The second and subsequent times round * this loop, send a WAIT_UNTIL_3D_IDLE before * calling emit_clip_rect(). This fixes a @@ -2851,7 +2809,7 @@ static int radeon_emit_packet3_cliprect(drm_device_t *dev, return 0; } -static int radeon_emit_wait(drm_device_t * dev, int flags) +static int radeon_emit_wait(struct drm_device * dev, int flags) { drm_radeon_private_t *dev_priv = dev->dev_private; RING_LOCALS; @@ -2874,67 +2832,59 @@ static int radeon_emit_wait(drm_device_t * dev, int flags) ADVANCE_RING(); break; default: - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; } -static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) +static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_file_t *filp_priv; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf = NULL; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf = NULL; int idx; - drm_radeon_kcmd_buffer_t cmdbuf; + drm_radeon_kcmd_buffer_t *cmdbuf = data; drm_radeon_cmd_header_t header; int orig_nbox, orig_bufsz; char *kbuf = NULL; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - - DRM_COPY_FROM_USER_IOCTL(cmdbuf, - (drm_radeon_kcmd_buffer_t __user *) data, - sizeof(cmdbuf)); - RING_SPACE_TEST_WITH_RETURN(dev_priv); VB_AGE_TEST_WITH_RETURN(dev_priv); - if (cmdbuf.bufsz > 64 * 1024 || cmdbuf.bufsz < 0) { - return DRM_ERR(EINVAL); + if (cmdbuf->bufsz > 64 * 1024 || cmdbuf->bufsz < 0) { + return -EINVAL; } /* Allocate an in-kernel area and copy in the cmdbuf. Do this to avoid * races between checking values and using those values in other code, * and simply to avoid a lot of function calls to copy in data. */ - orig_bufsz = cmdbuf.bufsz; + orig_bufsz = cmdbuf->bufsz; if (orig_bufsz != 0) { - kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER); + kbuf = drm_alloc(cmdbuf->bufsz, DRM_MEM_DRIVER); if (kbuf == NULL) - return DRM_ERR(ENOMEM); - if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf, - cmdbuf.bufsz)) { + return -ENOMEM; + if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf->buf, + cmdbuf->bufsz)) { drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); - return DRM_ERR(EFAULT); + return -EFAULT; } - cmdbuf.buf = kbuf; + cmdbuf->buf = kbuf; } - orig_nbox = cmdbuf.nbox; + orig_nbox = cmdbuf->nbox; if (dev_priv->microcode_version == UCODE_R300) { int temp; - temp = r300_do_cp_cmdbuf(dev, filp, filp_priv, &cmdbuf); + temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); if (orig_bufsz != 0) drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); @@ -2943,17 +2893,17 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) } /* microcode_version != r300 */ - while (cmdbuf.bufsz >= sizeof(header)) { + while (cmdbuf->bufsz >= sizeof(header)) { - header.i = *(int *)cmdbuf.buf; - cmdbuf.buf += sizeof(header); - cmdbuf.bufsz -= sizeof(header); + header.i = *(int *)cmdbuf->buf; + cmdbuf->buf += sizeof(header); + cmdbuf->bufsz -= sizeof(header); switch (header.header.cmd_type) { case RADEON_CMD_PACKET: DRM_DEBUG("RADEON_CMD_PACKET\n"); if (radeon_emit_packets - (dev_priv, filp_priv, header, &cmdbuf)) { + (dev_priv, file_priv, header, cmdbuf)) { DRM_ERROR("radeon_emit_packets failed\n"); goto err; } @@ -2961,7 +2911,7 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) case RADEON_CMD_SCALARS: DRM_DEBUG("RADEON_CMD_SCALARS\n"); - if (radeon_emit_scalars(dev_priv, header, &cmdbuf)) { + if (radeon_emit_scalars(dev_priv, header, cmdbuf)) { DRM_ERROR("radeon_emit_scalars failed\n"); goto err; } @@ -2969,7 +2919,7 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) case RADEON_CMD_VECTORS: DRM_DEBUG("RADEON_CMD_VECTORS\n"); - if (radeon_emit_vectors(dev_priv, header, &cmdbuf)) { + if (radeon_emit_vectors(dev_priv, header, cmdbuf)) { DRM_ERROR("radeon_emit_vectors failed\n"); goto err; } @@ -2985,9 +2935,10 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) } buf = dma->buflist[idx]; - if (buf->filp != filp || buf->pending) { + if (buf->file_priv != file_priv || buf->pending) { DRM_ERROR("bad buffer %p %p %d\n", - buf->filp, filp, buf->pending); + buf->file_priv, file_priv, + buf->pending); goto err; } @@ -2996,7 +2947,7 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) case RADEON_CMD_PACKET3: DRM_DEBUG("RADEON_CMD_PACKET3\n"); - if (radeon_emit_packet3(dev, filp_priv, &cmdbuf)) { + if (radeon_emit_packet3(dev, file_priv, cmdbuf)) { DRM_ERROR("radeon_emit_packet3 failed\n"); goto err; } @@ -3005,7 +2956,7 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) case RADEON_CMD_PACKET3_CLIP: DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); if (radeon_emit_packet3_cliprect - (dev, filp_priv, &cmdbuf, orig_nbox)) { + (dev, file_priv, cmdbuf, orig_nbox)) { DRM_ERROR("radeon_emit_packet3_clip failed\n"); goto err; } @@ -3013,7 +2964,7 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) case RADEON_CMD_SCALARS2: DRM_DEBUG("RADEON_CMD_SCALARS2\n"); - if (radeon_emit_scalars2(dev_priv, header, &cmdbuf)) { + if (radeon_emit_scalars2(dev_priv, header, cmdbuf)) { DRM_ERROR("radeon_emit_scalars2 failed\n"); goto err; } @@ -3028,7 +2979,7 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) break; case RADEON_CMD_VECLINEAR: DRM_DEBUG("RADEON_CMD_VECLINEAR\n"); - if (radeon_emit_veclinear(dev_priv, header, &cmdbuf)) { + if (radeon_emit_veclinear(dev_priv, header, cmdbuf)) { DRM_ERROR("radeon_emit_veclinear failed\n"); goto err; } @@ -3037,7 +2988,7 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) default: DRM_ERROR("bad cmd_type %d at %p\n", header.header.cmd_type, - cmdbuf.buf - sizeof(header)); + cmdbuf->buf - sizeof(header)); goto err; } } @@ -3052,27 +3003,23 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) err: if (orig_bufsz != 0) drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); - return DRM_ERR(EINVAL); + return -EINVAL; } -static int radeon_cp_getparam(DRM_IOCTL_ARGS) +static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_getparam_t param; + drm_radeon_getparam_t *param = data; int value; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data, - sizeof(param)); - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - switch (param.param) { + switch (param->param) { case RADEON_PARAM_GART_BUFFER_OFFSET: value = dev_priv->gart_buffers_offset; break; @@ -3119,7 +3066,7 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) break; case RADEON_PARAM_SCRATCH_OFFSET: if (!dev_priv->writeback_works) - return DRM_ERR(EINVAL); + return -EINVAL; value = RADEON_SCRATCH_REG_OFFSET; break; @@ -3135,48 +3082,42 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) value = radeon_vblank_crtc_get(dev); break; default: - DRM_DEBUG( "Invalid parameter %d\n", param.param ); - return DRM_ERR(EINVAL); + DRM_DEBUG( "Invalid parameter %d\n", param->param ); + return -EINVAL; } - if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) { + if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { DRM_ERROR("copy_to_user\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } return 0; } -static int radeon_cp_setparam(DRM_IOCTL_ARGS) +static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; - drm_file_t *filp_priv; - drm_radeon_setparam_t sp; + drm_radeon_setparam_t *sp = data; struct drm_radeon_driver_file_fields *radeon_priv; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); - - DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data, - sizeof(sp)); - - switch (sp.param) { + switch (sp->param) { case RADEON_SETPARAM_FB_LOCATION: - radeon_priv = filp_priv->driver_priv; - radeon_priv->radeon_fb_delta = dev_priv->fb_location - sp.value; + radeon_priv = file_priv->driver_priv; + radeon_priv->radeon_fb_delta = dev_priv->fb_location - + sp->value; break; case RADEON_SETPARAM_SWITCH_TILING: - if (sp.value == 0) { + if (sp->value == 0) { DRM_DEBUG("color tiling disabled\n"); dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO; dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO; dev_priv->sarea_priv->tiling_enabled = 0; - } else if (sp.value == 1) { + } else if (sp->value == 1) { DRM_DEBUG("color tiling enabled\n"); dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO; dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO; @@ -3184,23 +3125,23 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) } break; case RADEON_SETPARAM_PCIGART_LOCATION: - dev_priv->pcigart_offset = sp.value; + dev_priv->pcigart_offset = sp->value; dev_priv->pcigart_offset_set = 1; break; case RADEON_SETPARAM_NEW_MEMMAP: - dev_priv->new_memmap = sp.value; + dev_priv->new_memmap = sp->value; break; case RADEON_SETPARAM_PCIGART_TABLE_SIZE: - dev_priv->gart_info.table_size = sp.value; + dev_priv->gart_info.table_size = sp->value; if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE) dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; break; case RADEON_SETPARAM_VBLANK_CRTC: - return radeon_vblank_crtc_set(dev, sp.value); + return radeon_vblank_crtc_set(dev, sp->value); break; default: - DRM_DEBUG("Invalid parameter %d\n", sp.param); - return DRM_ERR(EINVAL); + DRM_DEBUG("Invalid parameter %d\n", sp->param); + return -EINVAL; } return 0; @@ -3213,18 +3154,19 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) * * DRM infrastructure takes care of reclaiming dma buffers. */ -void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp) +void radeon_driver_preclose(struct drm_device * dev, + struct drm_file *file_priv) { if (dev->dev_private) { drm_radeon_private_t *dev_priv = dev->dev_private; dev_priv->page_flipping = 0; - radeon_mem_release(filp, dev_priv->gart_heap); - radeon_mem_release(filp, dev_priv->fb_heap); - radeon_surfaces_release(filp, dev_priv); + radeon_mem_release(file_priv, dev_priv->gart_heap); + radeon_mem_release(file_priv, dev_priv->fb_heap); + radeon_surfaces_release(file_priv, dev_priv); } } -void radeon_driver_lastclose(drm_device_t * dev) +void radeon_driver_lastclose(struct drm_device * dev) { if (dev->dev_private) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -3237,7 +3179,7 @@ void radeon_driver_lastclose(drm_device_t * dev) radeon_do_release(dev); } -int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv) +int radeon_driver_open(struct drm_device * dev, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; struct drm_radeon_driver_file_fields *radeon_priv; @@ -3250,7 +3192,7 @@ int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv) if (!radeon_priv) return -ENOMEM; - filp_priv->driver_priv = radeon_priv; + file_priv->driver_priv = radeon_priv; if (dev_priv) radeon_priv->radeon_fb_delta = dev_priv->fb_location; @@ -3259,42 +3201,42 @@ int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv) return 0; } -void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp_priv) +void radeon_driver_postclose(struct drm_device * dev, struct drm_file *file_priv) { struct drm_radeon_driver_file_fields *radeon_priv = - filp_priv->driver_priv; + file_priv->driver_priv; drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES); } -drm_ioctl_desc_t radeon_ioctls[] = { - [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)] = {radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_CP_START)] = {radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)] = {radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)] = {radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)] = {radeon_cp_idle, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)] = {radeon_cp_resume, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_RESET)] = {radeon_engine_reset, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = {radeon_fullscreen, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_SWAP)] = {radeon_cp_swap, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_CLEAR)] = {radeon_cp_clear, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_VERTEX)] = {radeon_cp_vertex, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_INDICES)] = {radeon_cp_indices, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)] = {radeon_cp_texture, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)] = {radeon_cp_stipple, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)] = {radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)] = {radeon_cp_vertex2, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)] = {radeon_cp_cmdbuf, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)] = {radeon_cp_getparam, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_FLIP)] = {radeon_cp_flip, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_ALLOC)] = {radeon_mem_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_FREE)] = {radeon_mem_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)] = {radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)] = {radeon_irq_emit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)] = {radeon_irq_wait, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)] = {radeon_cp_setparam, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_SURF_ALLOC)] = {radeon_surface_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_RADEON_SURF_FREE)] = {radeon_surface_free, DRM_AUTH} +struct drm_ioctl_desc radeon_ioctls[] = { + DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH) }; int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); diff --git a/shared-core/savage_bci.c b/shared-core/savage_bci.c index 9a3ae1f1..32ac5ac2 100644 --- a/shared-core/savage_bci.c +++ b/shared-core/savage_bci.c @@ -32,7 +32,7 @@ #define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */ #define SAVAGE_FREELIST_DEBUG 0 -static int savage_do_cleanup_bci(drm_device_t *dev); +static int savage_do_cleanup_bci(struct drm_device *dev); static int savage_bci_wait_fifo_shadow(drm_savage_private_t *dev_priv, unsigned int n) @@ -60,7 +60,7 @@ savage_bci_wait_fifo_shadow(drm_savage_private_t *dev_priv, unsigned int n) DRM_ERROR("failed!\n"); DRM_INFO(" status=0x%08x, threshold=0x%08x\n", status, threshold); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } static int @@ -81,7 +81,7 @@ savage_bci_wait_fifo_s3d(drm_savage_private_t *dev_priv, unsigned int n) DRM_ERROR("failed!\n"); DRM_INFO(" status=0x%08x\n", status); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } static int @@ -102,7 +102,7 @@ savage_bci_wait_fifo_s4(drm_savage_private_t *dev_priv, unsigned int n) DRM_ERROR("failed!\n"); DRM_INFO(" status=0x%08x\n", status); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } /* @@ -136,7 +136,7 @@ savage_bci_wait_event_shadow(drm_savage_private_t *dev_priv, uint16_t e) DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } static int @@ -158,7 +158,7 @@ savage_bci_wait_event_reg(drm_savage_private_t *dev_priv, uint16_t e) DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e); #endif - return DRM_ERR(EBUSY); + return -EBUSY; } uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv, @@ -203,11 +203,11 @@ uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv, /* * Freelist management */ -static int savage_freelist_init(drm_device_t *dev) +static int savage_freelist_init(struct drm_device *dev) { drm_savage_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *buf; drm_savage_buf_priv_t *entry; int i; DRM_DEBUG("count=%d\n", dma->buf_count); @@ -236,7 +236,7 @@ static int savage_freelist_init(drm_device_t *dev) return 0; } -static drm_buf_t *savage_freelist_get(drm_device_t *dev) +static struct drm_buf *savage_freelist_get(struct drm_device *dev) { drm_savage_private_t *dev_priv = dev->dev_private; drm_savage_buf_priv_t *tail = dev_priv->tail.prev; @@ -269,7 +269,7 @@ static drm_buf_t *savage_freelist_get(drm_device_t *dev) return NULL; } -void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf) +void savage_freelist_put(struct drm_device *dev, struct drm_buf *buf) { drm_savage_private_t *dev_priv = dev->dev_private; drm_savage_buf_priv_t *entry = buf->dev_private, *prev, *next; @@ -301,7 +301,7 @@ static int savage_dma_init(drm_savage_private_t *dev_priv) dev_priv->dma_pages = drm_alloc(sizeof(drm_savage_dma_page_t) * dev_priv->nr_dma_pages, DRM_MEM_DRIVER); if (dev_priv->dma_pages == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; for (i = 0; i < dev_priv->nr_dma_pages; ++i) { SET_AGE(&dev_priv->dma_pages[i].age, 0, 0); @@ -535,13 +535,13 @@ static void savage_fake_dma_flush(drm_savage_private_t *dev_priv) dev_priv->first_dma_page = dev_priv->current_dma_page = 0; } -int savage_driver_load(drm_device_t *dev, unsigned long chipset) +int savage_driver_load(struct drm_device *dev, unsigned long chipset) { drm_savage_private_t *dev_priv; dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; memset(dev_priv, 0, sizeof(drm_savage_private_t)); dev->dev_private = (void *)dev_priv; @@ -557,7 +557,7 @@ int savage_driver_load(drm_device_t *dev, unsigned long chipset) * in drm_addmap. Therefore we add them manually before the maps are * initialized, and tear them down on last close. */ -int savage_driver_firstopen(drm_device_t *dev) +int savage_driver_firstopen(struct drm_device *dev) { drm_savage_private_t *dev_priv = dev->dev_private; unsigned long mmio_base, fb_base, fb_size, aperture_base; @@ -654,7 +654,7 @@ int savage_driver_firstopen(drm_device_t *dev) /* * Delete MTRRs and free device-private data. */ -void savage_driver_lastclose(drm_device_t *dev) +void savage_driver_lastclose(struct drm_device *dev) { drm_savage_private_t *dev_priv = dev->dev_private; int i; @@ -666,7 +666,7 @@ void savage_driver_lastclose(drm_device_t *dev) dev_priv->mtrr[i].size, DRM_MTRR_WC); } -int savage_driver_unload(drm_device_t *dev) +int savage_driver_unload(struct drm_device *dev) { drm_savage_private_t *dev_priv = dev->dev_private; @@ -675,22 +675,22 @@ int savage_driver_unload(drm_device_t *dev) return 0; } -static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) +static int savage_do_init_bci(struct drm_device *dev, drm_savage_init_t *init) { drm_savage_private_t *dev_priv = dev->dev_private; if (init->fb_bpp != 16 && init->fb_bpp != 32) { DRM_ERROR("invalid frame buffer bpp %d!\n", init->fb_bpp); - return DRM_ERR(EINVAL); + return -EINVAL; } if (init->depth_bpp != 16 && init->depth_bpp != 32) { DRM_ERROR("invalid depth buffer bpp %d!\n", init->fb_bpp); - return DRM_ERR(EINVAL); + return -EINVAL; } if (init->dma_type != SAVAGE_DMA_AGP && init->dma_type != SAVAGE_DMA_PCI) { DRM_ERROR("invalid dma memory type %d!\n", init->dma_type); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->cob_size = init->cob_size; @@ -714,14 +714,14 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) if (!dev_priv->sarea) { DRM_ERROR("could not find sarea!\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } if (init->status_offset != 0) { dev_priv->status = drm_core_findmap(dev, init->status_offset); if (!dev_priv->status) { DRM_ERROR("could not find shadow status region!\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } } else { dev_priv->status = NULL; @@ -733,13 +733,13 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) if (!dev->agp_buffer_map) { DRM_ERROR("could not find DMA buffer region!\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } drm_core_ioremap(dev->agp_buffer_map, dev); if (!dev->agp_buffer_map) { DRM_ERROR("failed to ioremap DMA buffer region!\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(ENOMEM); + return -ENOMEM; } } if (init->agp_textures_offset) { @@ -748,7 +748,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) if (!dev_priv->agp_textures) { DRM_ERROR("could not find agp texture region!\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } } else { dev_priv->agp_textures = NULL; @@ -759,39 +759,39 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) DRM_ERROR("command DMA not supported on " "Savage3D/MX/IX.\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } if (dev->dma && dev->dma->buflist) { DRM_ERROR("command and vertex DMA not supported " "at the same time.\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->cmd_dma = drm_core_findmap(dev, init->cmd_dma_offset); if (!dev_priv->cmd_dma) { DRM_ERROR("could not find command DMA region!\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } if (dev_priv->dma_type == SAVAGE_DMA_AGP) { if (dev_priv->cmd_dma->type != _DRM_AGP) { DRM_ERROR("AGP command DMA region is not a " "_DRM_AGP map!\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } drm_core_ioremap(dev_priv->cmd_dma, dev); if (!dev_priv->cmd_dma->handle) { DRM_ERROR("failed to ioremap command " "DMA region!\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(ENOMEM); + return -ENOMEM; } } else if (dev_priv->cmd_dma->type != _DRM_CONSISTENT) { DRM_ERROR("PCI command DMA region is not a " "_DRM_CONSISTENT map!\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(EINVAL); + return -EINVAL; } } else { dev_priv->cmd_dma = NULL; @@ -808,7 +808,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) if (!dev_priv->fake_dma.handle) { DRM_ERROR("could not allocate faked DMA buffer!\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(ENOMEM); + return -ENOMEM; } dev_priv->cmd_dma = &dev_priv->fake_dma; dev_priv->dma_flush = savage_fake_dma_flush; @@ -885,19 +885,19 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init) if (savage_freelist_init(dev) < 0) { DRM_ERROR("could not initialize freelist\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(ENOMEM); + return -ENOMEM; } if (savage_dma_init(dev_priv) < 0) { DRM_ERROR("could not initialize command DMA\n"); savage_do_cleanup_bci(dev); - return DRM_ERR(ENOMEM); + return -ENOMEM; } return 0; } -static int savage_do_cleanup_bci(drm_device_t *dev) +static int savage_do_cleanup_bci(struct drm_device *dev) { drm_savage_private_t *dev_priv = dev->dev_private; @@ -927,59 +927,46 @@ static int savage_do_cleanup_bci(drm_device_t *dev) return 0; } -static int savage_bci_init(DRM_IOCTL_ARGS) +static int savage_bci_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_savage_init_t init; + drm_savage_init_t *init = data; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_COPY_FROM_USER_IOCTL(init, (drm_savage_init_t __user *)data, - sizeof(init)); - - switch (init.func) { + switch (init->func) { case SAVAGE_INIT_BCI: - return savage_do_init_bci(dev, &init); + return savage_do_init_bci(dev, init); case SAVAGE_CLEANUP_BCI: return savage_do_cleanup_bci(dev); } - return DRM_ERR(EINVAL); + return -EINVAL; } -static int savage_bci_event_emit(DRM_IOCTL_ARGS) +static int savage_bci_event_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_savage_private_t *dev_priv = dev->dev_private; - drm_savage_event_emit_t event; + drm_savage_event_emit_t *event = data; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_emit_t __user *)data, - sizeof(event)); + event->count = savage_bci_emit_event(dev_priv, event->flags); + event->count |= dev_priv->event_wrap << 16; - event.count = savage_bci_emit_event(dev_priv, event.flags); - event.count |= dev_priv->event_wrap << 16; - DRM_COPY_TO_USER_IOCTL((drm_savage_event_emit_t __user *)data, - event, sizeof(event)); return 0; } -static int savage_bci_event_wait(DRM_IOCTL_ARGS) +static int savage_bci_event_wait(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_savage_private_t *dev_priv = dev->dev_private; - drm_savage_event_wait_t event; + drm_savage_event_wait_t *event = data; unsigned int event_e, hw_e; unsigned int event_w, hw_w; DRM_DEBUG("\n"); - DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *)data, - sizeof(event)); - UPDATE_EVENT_COUNTER(); if (dev_priv->status_ptr) hw_e = dev_priv->status_ptr[1] & 0xffff; @@ -989,8 +976,8 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS) if (hw_e > dev_priv->event_counter) hw_w--; /* hardware hasn't passed the last wrap yet */ - event_e = event.count & 0xffff; - event_w = event.count >> 16; + event_e = event->count & 0xffff; + event_w = event->count >> 16; /* Don't need to wait if * - event counter wrapped since the event was emitted or @@ -1006,71 +993,68 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS) * DMA buffer management */ -static int savage_bci_get_buffers(DRMFILE filp, drm_device_t *dev, drm_dma_t *d) +static int savage_bci_get_buffers(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_dma *d) { - drm_buf_t *buf; + struct drm_buf *buf; int i; for (i = d->granted_count; i < d->request_count; i++) { buf = savage_freelist_get(dev); if (!buf) - return DRM_ERR(EAGAIN); + return -EAGAIN; - buf->filp = filp; + buf->file_priv = file_priv; if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, sizeof(buf->idx))) - return DRM_ERR(EFAULT); + return -EFAULT; if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, sizeof(buf->total))) - return DRM_ERR(EFAULT); + return -EFAULT; d->granted_count++; } return 0; } -int savage_bci_buffers(DRM_IOCTL_ARGS) +int savage_bci_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_device_dma_t *dma = dev->dma; - drm_dma_t d; + struct drm_device_dma *dma = dev->dma; + struct drm_dma *d = data; int ret = 0; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t __user *)data, sizeof(d)); + LOCK_TEST_WITH_RETURN(dev, file_priv); /* Please don't send us buffers. */ - if (d.send_count != 0) { + if (d->send_count != 0) { DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d.send_count); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, d->send_count); + return -EINVAL; } /* We'll send you buffers. */ - if (d.request_count < 0 || d.request_count > dma->buf_count) { + if (d->request_count < 0 || d->request_count > dma->buf_count) { DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d.request_count, dma->buf_count); - return DRM_ERR(EINVAL); + DRM_CURRENTPID, d->request_count, dma->buf_count); + return -EINVAL; } - d.granted_count = 0; + d->granted_count = 0; - if (d.request_count) { - ret = savage_bci_get_buffers(filp, dev, &d); + if (d->request_count) { + ret = savage_bci_get_buffers(dev, file_priv, d); } - DRM_COPY_TO_USER_IOCTL((drm_dma_t __user *)data, d, sizeof(d)); - return ret; } -void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) +void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) { - drm_device_dma_t *dma = dev->dma; + struct drm_device_dma *dma = dev->dma; drm_savage_private_t *dev_priv = dev->dev_private; int i; @@ -1084,10 +1068,10 @@ void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) /*i830_flush_queue(dev);*/ for (i = 0; i < dma->buf_count; i++) { - drm_buf_t *buf = dma->buflist[i]; + struct drm_buf *buf = dma->buflist[i]; drm_savage_buf_priv_t *buf_priv = buf->dev_private; - if (buf->filp == filp && buf_priv && + if (buf->file_priv == file_priv && buf_priv && buf_priv->next == NULL && buf_priv->prev == NULL) { uint16_t event; DRM_DEBUG("reclaimed from client\n"); @@ -1097,14 +1081,14 @@ void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) } } - drm_core_reclaim_buffers(dev, filp); + drm_core_reclaim_buffers(dev, file_priv); } -drm_ioctl_desc_t savage_ioctls[] = { - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_EMIT)] = {savage_bci_event_emit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SAVAGE_BCI_EVENT_WAIT)] = {savage_bci_event_wait, DRM_AUTH}, +struct drm_ioctl_desc savage_ioctls[] = { + DRM_IOCTL_DEF(DRM_SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), + DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), + DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), }; int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); diff --git a/shared-core/savage_drm.h b/shared-core/savage_drm.h index 6526c9aa..b960d557 100644 --- a/shared-core/savage_drm.h +++ b/shared-core/savage_drm.h @@ -47,7 +47,7 @@ typedef struct _drm_savage_sarea { /* LRU lists for texture memory in agp space and on the card. */ - drm_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS+1]; + struct drm_tex_region texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS+1]; unsigned int texAge[SAVAGE_NR_TEX_HEAPS]; /* Mechanism to validate card state. @@ -112,7 +112,7 @@ typedef struct drm_savage_cmdbuf { unsigned int vb_size; /* size of client vertex buffer in bytes */ unsigned int vb_stride; /* stride of vertices in 32bit words */ /* boxes in client's address space */ - drm_clip_rect_t __user *box_addr; + struct drm_clip_rect __user *box_addr; unsigned int nbox; /* number of clipping boxes */ } drm_savage_cmdbuf_t; diff --git a/shared-core/savage_drv.h b/shared-core/savage_drv.h index 88c571e1..d86bac04 100644 --- a/shared-core/savage_drv.h +++ b/shared-core/savage_drv.h @@ -58,7 +58,7 @@ typedef struct drm_savage_buf_priv { struct drm_savage_buf_priv *next; struct drm_savage_buf_priv *prev; drm_savage_age_t age; - drm_buf_t *buf; + struct drm_buf *buf; } drm_savage_buf_priv_t; typedef struct drm_savage_dma_page { @@ -104,7 +104,7 @@ enum savage_family { S3_LAST }; -extern drm_ioctl_desc_t savage_ioctls[]; +extern struct drm_ioctl_desc savage_ioctls[]; extern int savage_max_ioctl; #define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) @@ -192,33 +192,34 @@ typedef struct drm_savage_private { /* Err, there is a macro wait_event in include/linux/wait.h. * Avoid unwanted macro expansion. */ void (*emit_clip_rect)(struct drm_savage_private *dev_priv, - const drm_clip_rect_t *pbox); + const struct drm_clip_rect *pbox); void (*dma_flush)(struct drm_savage_private *dev_priv); } drm_savage_private_t; /* ioctls */ -extern int savage_bci_cmdbuf(DRM_IOCTL_ARGS); -extern int savage_bci_buffers(DRM_IOCTL_ARGS); +extern int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int savage_bci_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); /* BCI functions */ extern uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv, unsigned int flags); -extern void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf); +extern void savage_freelist_put(struct drm_device *dev, struct drm_buf *buf); extern void savage_dma_reset(drm_savage_private_t *dev_priv); extern void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page); extern uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n); -extern int savage_driver_load(drm_device_t *dev, unsigned long chipset); -extern int savage_driver_firstopen(drm_device_t *dev); -extern void savage_driver_lastclose(drm_device_t *dev); -extern int savage_driver_unload(drm_device_t *dev); -extern void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp); +extern int savage_driver_load(struct drm_device *dev, unsigned long chipset); +extern int savage_driver_firstopen(struct drm_device *dev); +extern void savage_driver_lastclose(struct drm_device *dev); +extern int savage_driver_unload(struct drm_device *dev); +extern void savage_reclaim_buffers(struct drm_device *dev, + struct drm_file *file_priv); /* state functions */ extern void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv, - const drm_clip_rect_t *pbox); + const struct drm_clip_rect *pbox); extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, - const drm_clip_rect_t *pbox); + const struct drm_clip_rect *pbox); #define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */ #define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */ diff --git a/shared-core/savage_state.c b/shared-core/savage_state.c index acc98f89..dd593340 100644 --- a/shared-core/savage_state.c +++ b/shared-core/savage_state.c @@ -27,7 +27,7 @@ #include "savage_drv.h" void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv, - const drm_clip_rect_t *pbox) + const struct drm_clip_rect *pbox) { uint32_t scstart = dev_priv->state.s3d.new_scstart; uint32_t scend = dev_priv->state.s3d.new_scend; @@ -53,7 +53,7 @@ void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv, } void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, - const drm_clip_rect_t *pbox) + const struct drm_clip_rect *pbox) { uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0; uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1; @@ -83,7 +83,7 @@ static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit, { if ((addr & 6) != 2) { /* reserved bits */ DRM_ERROR("bad texAddr%d %08x (reserved bits)\n", unit, addr); - return DRM_ERR(EINVAL); + return -EINVAL; } if (!(addr & 1)) { /* local */ addr &= ~7; @@ -92,13 +92,13 @@ static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit, DRM_ERROR ("bad texAddr%d %08x (local addr out of range)\n", unit, addr); - return DRM_ERR(EINVAL); + return -EINVAL; } } else { /* AGP */ if (!dev_priv->agp_textures) { DRM_ERROR("bad texAddr%d %08x (AGP not available)\n", unit, addr); - return DRM_ERR(EINVAL); + return -EINVAL; } addr &= ~7; if (addr < dev_priv->agp_textures->offset || @@ -107,7 +107,7 @@ static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit, DRM_ERROR ("bad texAddr%d %08x (AGP addr out of range)\n", unit, addr); - return DRM_ERR(EINVAL); + return -EINVAL; } } return 0; @@ -132,7 +132,7 @@ static int savage_verify_state_s3d(drm_savage_private_t *dev_priv, start+count-1 > SAVAGE_DESTTEXRWWATERMARK_S3D) { DRM_ERROR("invalid register range (0x%04x-0x%04x)\n", start, start+count-1); - return DRM_ERR(EINVAL); + return -EINVAL; } SAVE_STATE_MASK(SAVAGE_SCSTART_S3D, s3d.new_scstart, @@ -164,7 +164,7 @@ static int savage_verify_state_s4(drm_savage_private_t *dev_priv, start+count-1 > SAVAGE_TEXBLENDCOLOR_S4) { DRM_ERROR("invalid register range (0x%04x-0x%04x)\n", start, start+count-1); - return DRM_ERR(EINVAL); + return -EINVAL; } SAVE_STATE_MASK(SAVAGE_DRAWCTRL0_S4, s4.new_drawctrl0, @@ -275,7 +275,7 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv, static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, const drm_savage_cmd_header_t *cmd_header, - const drm_buf_t *dmabuf) + const struct drm_buf *dmabuf) { unsigned char reorder = 0; unsigned int prim = cmd_header->prim.prim; @@ -287,7 +287,7 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, if (!dmabuf) { DRM_ERROR("called without dma buffers!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (!n) @@ -301,7 +301,7 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, if (n % 3 != 0) { DRM_ERROR("wrong number of vertices %u in TRILIST\n", n); - return DRM_ERR(EINVAL); + return -EINVAL; } break; case SAVAGE_PRIM_TRISTRIP: @@ -310,18 +310,18 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, DRM_ERROR ("wrong number of vertices %u in TRIFAN/STRIP\n", n); - return DRM_ERR(EINVAL); + return -EINVAL; } break; default: DRM_ERROR("invalid primitive type %u\n", prim); - return DRM_ERR(EINVAL); + return -EINVAL; } if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { if (skip != 0) { DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return DRM_ERR(EINVAL); + return -EINVAL; } } else { unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) - @@ -329,18 +329,18 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv, (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1); if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) { DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return DRM_ERR(EINVAL); + return -EINVAL; } if (reorder) { DRM_ERROR("TRILIST_201 used on Savage4 hardware\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } } if (start + n > dmabuf->total/32) { DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n", start, start + n - 1, dmabuf->total/32); - return DRM_ERR(EINVAL); + return -EINVAL; } /* Vertex DMA doesn't work with command DMA at the same time, @@ -438,7 +438,7 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv, if (n % 3 != 0) { DRM_ERROR("wrong number of vertices %u in TRILIST\n", n); - return DRM_ERR(EINVAL); + return -EINVAL; } break; case SAVAGE_PRIM_TRISTRIP: @@ -447,24 +447,24 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv, DRM_ERROR ("wrong number of vertices %u in TRIFAN/STRIP\n", n); - return DRM_ERR(EINVAL); + return -EINVAL; } break; default: DRM_ERROR("invalid primitive type %u\n", prim); - return DRM_ERR(EINVAL); + return -EINVAL; } if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { if (skip > SAVAGE_SKIP_ALL_S3D) { DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return DRM_ERR(EINVAL); + return -EINVAL; } vtx_size = 8; /* full vertex */ } else { if (skip > SAVAGE_SKIP_ALL_S4) { DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return DRM_ERR(EINVAL); + return -EINVAL; } vtx_size = 10; /* full vertex */ } @@ -476,13 +476,13 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv, if (vtx_size > vb_stride) { DRM_ERROR("vertex size greater than vb stride (%u > %u)\n", vtx_size, vb_stride); - return DRM_ERR(EINVAL); + return -EINVAL; } if (start + n > vb_size / (vb_stride*4)) { DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n", start, start + n - 1, vb_size / (vb_stride*4)); - return DRM_ERR(EINVAL); + return -EINVAL; } prim <<= 25; @@ -534,7 +534,7 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv, static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, const drm_savage_cmd_header_t *cmd_header, const uint16_t *idx, - const drm_buf_t *dmabuf) + const struct drm_buf *dmabuf) { unsigned char reorder = 0; unsigned int prim = cmd_header->idx.prim; @@ -545,7 +545,7 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, if (!dmabuf) { DRM_ERROR("called without dma buffers!\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } if (!n) @@ -558,7 +558,7 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, case SAVAGE_PRIM_TRILIST: if (n % 3 != 0) { DRM_ERROR("wrong number of indices %u in TRILIST\n", n); - return DRM_ERR(EINVAL); + return -EINVAL; } break; case SAVAGE_PRIM_TRISTRIP: @@ -566,18 +566,18 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, if (n < 3) { DRM_ERROR ("wrong number of indices %u in TRIFAN/STRIP\n", n); - return DRM_ERR(EINVAL); + return -EINVAL; } break; default: DRM_ERROR("invalid primitive type %u\n", prim); - return DRM_ERR(EINVAL); + return -EINVAL; } if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { if (skip != 0) { DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return DRM_ERR(EINVAL); + return -EINVAL; } } else { unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) - @@ -585,11 +585,11 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1); if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) { DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return DRM_ERR(EINVAL); + return -EINVAL; } if (reorder) { DRM_ERROR("TRILIST_201 used on Savage4 hardware\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } } @@ -626,7 +626,7 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv, if (idx[i] > dmabuf->total/32) { DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", i, idx[i], dmabuf->total/32); - return DRM_ERR(EINVAL); + return -EINVAL; } } @@ -696,7 +696,7 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv, case SAVAGE_PRIM_TRILIST: if (n % 3 != 0) { DRM_ERROR("wrong number of indices %u in TRILIST\n", n); - return DRM_ERR(EINVAL); + return -EINVAL; } break; case SAVAGE_PRIM_TRISTRIP: @@ -704,24 +704,24 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv, if (n < 3) { DRM_ERROR ("wrong number of indices %u in TRIFAN/STRIP\n", n); - return DRM_ERR(EINVAL); + return -EINVAL; } break; default: DRM_ERROR("invalid primitive type %u\n", prim); - return DRM_ERR(EINVAL); + return -EINVAL; } if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { if (skip > SAVAGE_SKIP_ALL_S3D) { DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return DRM_ERR(EINVAL); + return -EINVAL; } vtx_size = 8; /* full vertex */ } else { if (skip > SAVAGE_SKIP_ALL_S4) { DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return DRM_ERR(EINVAL); + return -EINVAL; } vtx_size = 10; /* full vertex */ } @@ -733,7 +733,7 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv, if (vtx_size > vb_stride) { DRM_ERROR("vertex size greater than vb stride (%u > %u)\n", vtx_size, vb_stride); - return DRM_ERR(EINVAL); + return -EINVAL; } prim <<= 25; @@ -746,7 +746,7 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv, if (idx[i] > vb_size / (vb_stride*4)) { DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", i, idx[i], vb_size / (vb_stride*4)); - return DRM_ERR(EINVAL); + return -EINVAL; } } @@ -790,7 +790,7 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv, const drm_savage_cmd_header_t *cmd_header, const drm_savage_cmd_header_t *data, unsigned int nbox, - const drm_clip_rect_t *boxes) + const struct drm_clip_rect *boxes) { unsigned int flags = cmd_header->clear0.flags; unsigned int clear_cmd; @@ -860,7 +860,7 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv, } static int savage_dispatch_swap(drm_savage_private_t *dev_priv, - unsigned int nbox, const drm_clip_rect_t *boxes) + unsigned int nbox, const struct drm_clip_rect *boxes) { unsigned int swap_cmd; unsigned int i; @@ -891,11 +891,11 @@ static int savage_dispatch_swap(drm_savage_private_t *dev_priv, static int savage_dispatch_draw(drm_savage_private_t *dev_priv, const drm_savage_cmd_header_t *start, const drm_savage_cmd_header_t *end, - const drm_buf_t *dmabuf, + const struct drm_buf *dmabuf, const unsigned int *vtxbuf, unsigned int vb_size, unsigned int vb_stride, unsigned int nbox, - const drm_clip_rect_t *boxes) + const struct drm_clip_rect *boxes) { unsigned int i, j; int ret; @@ -941,7 +941,7 @@ static int savage_dispatch_draw(drm_savage_private_t *dev_priv, DRM_ERROR("IMPLEMENTATION ERROR: " "non-drawing-command %d\n", cmd_header.cmd.cmd); - return DRM_ERR(EINVAL); + return -EINVAL; } if (ret != 0) @@ -952,35 +952,31 @@ static int savage_dispatch_draw(drm_savage_private_t *dev_priv, return 0; } -int savage_bci_cmdbuf(DRM_IOCTL_ARGS) +int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_savage_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_buf_t *dmabuf; - drm_savage_cmdbuf_t cmdbuf; + struct drm_device_dma *dma = dev->dma; + struct drm_buf *dmabuf; + drm_savage_cmdbuf_t *cmdbuf = data; drm_savage_cmd_header_t *kcmd_addr = NULL; drm_savage_cmd_header_t *first_draw_cmd; unsigned int *kvb_addr = NULL; - drm_clip_rect_t *kbox_addr = NULL; + struct drm_clip_rect *kbox_addr = NULL; unsigned int i, j; int ret = 0; DRM_DEBUG("\n"); - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_savage_cmdbuf_t __user *)data, - sizeof(cmdbuf)); + LOCK_TEST_WITH_RETURN(dev, file_priv); if (dma && dma->buflist) { - if (cmdbuf.dma_idx > dma->buf_count) { + if (cmdbuf->dma_idx > dma->buf_count) { DRM_ERROR ("vertex buffer index %u out of range (0-%u)\n", - cmdbuf.dma_idx, dma->buf_count-1); - return DRM_ERR(EINVAL); + cmdbuf->dma_idx, dma->buf_count-1); + return -EINVAL; } - dmabuf = dma->buflist[cmdbuf.dma_idx]; + dmabuf = dma->buflist[cmdbuf->dma_idx]; } else { dmabuf = NULL; } @@ -990,47 +986,49 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) * COPY_FROM_USER_UNCHECKED when done in other drivers, and is correct * for locking on FreeBSD. */ - if (cmdbuf.size) { - kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER); + if (cmdbuf->size) { + kcmd_addr = drm_alloc(cmdbuf->size * 8, DRM_MEM_DRIVER); if (kcmd_addr == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; - if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr, - cmdbuf.size * 8)) + if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf->cmd_addr, + cmdbuf->size * 8)) { - drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER); - return DRM_ERR(EFAULT); + drm_free(kcmd_addr, cmdbuf->size * 8, DRM_MEM_DRIVER); + return -EFAULT; } - cmdbuf.cmd_addr = kcmd_addr; + cmdbuf->cmd_addr = kcmd_addr; } - if (cmdbuf.vb_size) { - kvb_addr = drm_alloc(cmdbuf.vb_size, DRM_MEM_DRIVER); + if (cmdbuf->vb_size) { + kvb_addr = drm_alloc(cmdbuf->vb_size, DRM_MEM_DRIVER); if (kvb_addr == NULL) { - ret = DRM_ERR(ENOMEM); + ret = -ENOMEM; goto done; } - if (DRM_COPY_FROM_USER(kvb_addr, cmdbuf.vb_addr, - cmdbuf.vb_size)) { - ret = DRM_ERR(EFAULT); + if (DRM_COPY_FROM_USER(kvb_addr, cmdbuf->vb_addr, + cmdbuf->vb_size)) { + ret = -EFAULT; goto done; } - cmdbuf.vb_addr = kvb_addr; + cmdbuf->vb_addr = kvb_addr; } - if (cmdbuf.nbox) { - kbox_addr = drm_alloc(cmdbuf.nbox * sizeof(drm_clip_rect_t), - DRM_MEM_DRIVER); + if (cmdbuf->nbox) { + kbox_addr = drm_alloc(cmdbuf->nbox * + sizeof(struct drm_clip_rect), + DRM_MEM_DRIVER); if (kbox_addr == NULL) { - ret = DRM_ERR(ENOMEM); + ret = -ENOMEM; goto done; } - if (DRM_COPY_FROM_USER(kbox_addr, cmdbuf.box_addr, - cmdbuf.nbox * sizeof(drm_clip_rect_t))) { - ret = DRM_ERR(EFAULT); + if (DRM_COPY_FROM_USER(kbox_addr, cmdbuf->box_addr, + cmdbuf->nbox * + sizeof(struct drm_clip_rect))) { + ret = -EFAULT; goto done; } - cmdbuf.box_addr = kbox_addr; + cmdbuf->box_addr = kbox_addr; } /* Make sure writes to DMA buffers are finished before sending @@ -1043,10 +1041,10 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) i = 0; first_draw_cmd = NULL; - while (i < cmdbuf.size) { + while (i < cmdbuf->size) { drm_savage_cmd_header_t cmd_header; - cmd_header = *(drm_savage_cmd_header_t *)cmdbuf.cmd_addr; - cmdbuf.cmd_addr++; + cmd_header = *(drm_savage_cmd_header_t *)cmdbuf->cmd_addr; + cmdbuf->cmd_addr++; i++; /* Group drawing commands with same state to minimize @@ -1056,28 +1054,29 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) case SAVAGE_CMD_DMA_IDX: case SAVAGE_CMD_VB_IDX: j = (cmd_header.idx.count + 3) / 4; - if (i + j > cmdbuf.size) { + if (i + j > cmdbuf->size) { DRM_ERROR("indexed drawing command extends " "beyond end of command buffer\n"); DMA_FLUSH(); - return DRM_ERR(EINVAL); + return -EINVAL; } /* fall through */ case SAVAGE_CMD_DMA_PRIM: case SAVAGE_CMD_VB_PRIM: if (!first_draw_cmd) - first_draw_cmd = cmdbuf.cmd_addr-1; - cmdbuf.cmd_addr += j; + first_draw_cmd = cmdbuf->cmd_addr-1; + cmdbuf->cmd_addr += j; i += j; break; default: if (first_draw_cmd) { ret = savage_dispatch_draw ( dev_priv, first_draw_cmd, - cmdbuf.cmd_addr-1, - dmabuf, cmdbuf.vb_addr, cmdbuf.vb_size, - cmdbuf.vb_stride, - cmdbuf.nbox, cmdbuf.box_addr); + cmdbuf->cmd_addr-1, + dmabuf, cmdbuf->vb_addr, + cmdbuf->vb_size, + cmdbuf->vb_stride, + cmdbuf->nbox, cmdbuf->box_addr); if (ret != 0) return ret; first_draw_cmd = NULL; @@ -1089,40 +1088,42 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) switch (cmd_header.cmd.cmd) { case SAVAGE_CMD_STATE: j = (cmd_header.state.count + 1) / 2; - if (i + j > cmdbuf.size) { + if (i + j > cmdbuf->size) { DRM_ERROR("command SAVAGE_CMD_STATE extends " "beyond end of command buffer\n"); DMA_FLUSH(); - ret = DRM_ERR(EINVAL); + ret = -EINVAL; goto done; } ret = savage_dispatch_state(dev_priv, &cmd_header, - (const uint32_t *)cmdbuf.cmd_addr); - cmdbuf.cmd_addr += j; + (const uint32_t *)cmdbuf->cmd_addr); + cmdbuf->cmd_addr += j; i += j; break; case SAVAGE_CMD_CLEAR: - if (i + 1 > cmdbuf.size) { + if (i + 1 > cmdbuf->size) { DRM_ERROR("command SAVAGE_CMD_CLEAR extends " "beyond end of command buffer\n"); DMA_FLUSH(); - ret = DRM_ERR(EINVAL); + ret = -EINVAL; goto done; } ret = savage_dispatch_clear(dev_priv, &cmd_header, - cmdbuf.cmd_addr, - cmdbuf.nbox, cmdbuf.box_addr); - cmdbuf.cmd_addr++; + cmdbuf->cmd_addr, + cmdbuf->nbox, + cmdbuf->box_addr); + cmdbuf->cmd_addr++; i++; break; case SAVAGE_CMD_SWAP: - ret = savage_dispatch_swap(dev_priv, cmdbuf.nbox, - cmdbuf.box_addr); + ret = savage_dispatch_swap(dev_priv, cmdbuf->nbox, + cmdbuf->box_addr); break; default: - DRM_ERROR("invalid command 0x%x\n", cmd_header.cmd.cmd); + DRM_ERROR("invalid command 0x%x\n", + cmd_header.cmd.cmd); DMA_FLUSH(); - ret = DRM_ERR(EINVAL); + ret = -EINVAL; goto done; } @@ -1134,9 +1135,9 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) if (first_draw_cmd) { ret = savage_dispatch_draw ( - dev_priv, first_draw_cmd, cmdbuf.cmd_addr, dmabuf, - cmdbuf.vb_addr, cmdbuf.vb_size, cmdbuf.vb_stride, - cmdbuf.nbox, cmdbuf.box_addr); + dev_priv, first_draw_cmd, cmdbuf->cmd_addr, dmabuf, + cmdbuf->vb_addr, cmdbuf->vb_size, cmdbuf->vb_stride, + cmdbuf->nbox, cmdbuf->box_addr); if (ret != 0) { DMA_FLUSH(); goto done; @@ -1145,7 +1146,7 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) DMA_FLUSH(); - if (dmabuf && cmdbuf.discard) { + if (dmabuf && cmdbuf->discard) { drm_savage_buf_priv_t *buf_priv = dmabuf->dev_private; uint16_t event; event = savage_bci_emit_event(dev_priv, SAVAGE_WAIT_3D); @@ -1155,9 +1156,9 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS) done: /* If we didn't need to allocate them, these'll be NULL */ - drm_free(kcmd_addr, cmdbuf.size * 8, DRM_MEM_DRIVER); - drm_free(kvb_addr, cmdbuf.vb_size, DRM_MEM_DRIVER); - drm_free(kbox_addr, cmdbuf.nbox * sizeof(drm_clip_rect_t), + drm_free(kcmd_addr, cmdbuf->size * 8, DRM_MEM_DRIVER); + drm_free(kvb_addr, cmdbuf->vb_size, DRM_MEM_DRIVER); + drm_free(kbox_addr, cmdbuf->nbox * sizeof(struct drm_clip_rect), DRM_MEM_DRIVER); return ret; diff --git a/shared-core/sis_drv.h b/shared-core/sis_drv.h index 006d148c..a4a88fe1 100644 --- a/shared-core/sis_drv.h +++ b/shared-core/sis_drv.h @@ -33,11 +33,11 @@ #define DRIVER_AUTHOR "SIS, Tungsten Graphics" #define DRIVER_NAME "sis" -#define DRIVER_DESC "SIS 300/630/540" -#define DRIVER_DATE "20060619" +#define DRIVER_DESC "SIS 300/630/540 and XGI V3XE/V5/V8" +#define DRIVER_DATE "20070626" #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 1 +#define DRIVER_MINOR 3 +#define DRIVER_PATCHLEVEL 0 enum sis_family { SIS_OTHER = 0, @@ -58,7 +58,7 @@ enum sis_family { typedef struct drm_sis_private { drm_local_map_t *mmio; unsigned int idle_fault; - drm_sman_t sman; + struct drm_sman sman; unsigned int chipset; int vram_initialized; int agp_initialized; @@ -66,9 +66,10 @@ typedef struct drm_sis_private { unsigned long agp_offset; } drm_sis_private_t; -extern int sis_idle(drm_device_t *dev); -extern void sis_reclaim_buffers_locked(drm_device_t *dev, struct file *filp); -extern void sis_lastclose(drm_device_t *dev); +extern int sis_idle(struct drm_device *dev); +extern void sis_reclaim_buffers_locked(struct drm_device *dev, + struct drm_file *file_priv); +extern void sis_lastclose(struct drm_device *dev); #else #include "sis_ds.h" @@ -78,14 +79,14 @@ typedef struct drm_sis_private { memHeap_t *FBHeap; } drm_sis_private_t; -extern int sis_init_context(drm_device_t * dev, int context); -extern int sis_final_context(drm_device_t * dev, int context); +extern int sis_init_context(struct drm_device * dev, int context); +extern int sis_final_context(struct drm_device * dev, int context); #endif -extern drm_ioctl_desc_t sis_ioctls[]; +extern struct drm_ioctl_desc sis_ioctls[]; extern int sis_max_ioctl; #endif diff --git a/shared-core/sis_mm.c b/shared-core/sis_mm.c index 6d074d6f..e11939fa 100644 --- a/shared-core/sis_mm.c +++ b/shared-core/sis_mm.c @@ -81,59 +81,52 @@ static int del_alloc_set(int context, int type, unsigned int val) /* fb management via fb device */ #if defined(__linux__) && defined(CONFIG_FB_SIS) -static int sis_fb_init(DRM_IOCTL_ARGS) +static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { return 0; } -static int sis_fb_alloc(DRM_IOCTL_ARGS) +static int sis_fb_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_sis_mem_t fb; + drm_sis_mem_t *fb = data; struct sis_memreq req; - drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data; int retval = 0; - DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb)); - - req.size = fb.size; + req.size = fb->size; sis_malloc(&req); if (req.offset) { /* TODO */ - fb.offset = req.offset; - fb.free = req.offset; - if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) { + fb->offset = req.offset; + fb->free = req.offset; + if (!add_alloc_set(fb->context, VIDEO_TYPE, fb->free)) { DRM_DEBUG("adding to allocation set fails\n"); sis_free(req.offset); - retval = DRM_ERR(EINVAL); + retval = -EINVAL; } } else { - fb.offset = 0; - fb.size = 0; - fb.free = 0; + fb->offset = 0; + fb->size = 0; + fb->free = 0; } - DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb)); - - DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset); + DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb->size, req.offset); return retval; } -static int sis_fb_free(DRM_IOCTL_ARGS) +static int sis_fb_free(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_sis_mem_t fb; int retval = 0; - DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb)); - - if (!fb.free) - return DRM_ERR(EINVAL); + if (!fb->free) + return -EINVAL; - if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free)) - retval = DRM_ERR(EINVAL); - sis_free(fb.free); + if (!del_alloc_set(fb->context, VIDEO_TYPE, fb->free)) + retval = -EINVAL; + sis_free(fb->free); - DRM_DEBUG("free fb, offset = 0x%lx\n", fb.free); + DRM_DEBUG("free fb, offset = 0x%lx\n", fb->free); return retval; } @@ -150,13 +143,10 @@ static int sis_fb_free(DRM_IOCTL_ARGS) * X driver/sisfb HW- Command- * framebuffer memory DRI heap Cursor queue */ -static int sis_fb_init(DRM_IOCTL_ARGS) +static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; - drm_sis_fb_t fb; - - DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *) data, sizeof(fb)); + drm_sis_fb_t *fb = data; if (dev_priv == NULL) { dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t), @@ -167,71 +157,62 @@ static int sis_fb_init(DRM_IOCTL_ARGS) } if (dev_priv->FBHeap != NULL) - return DRM_ERR(EINVAL); + return -EINVAL; - dev_priv->FBHeap = mmInit(fb.offset, fb.size); + dev_priv->FBHeap = mmInit(fb->offset, fb->size); - DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size); + DRM_DEBUG("offset = %u, size = %u", fb->offset, fb->size); return 0; } -static int sis_fb_alloc(DRM_IOCTL_ARGS) +static int sis_fb_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; - drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data; - drm_sis_mem_t fb; + drm_sis_mem_t *fb = data; PMemBlock block; int retval = 0; if (dev_priv == NULL || dev_priv->FBHeap == NULL) - return DRM_ERR(EINVAL); - - DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb)); + return -EINVAL; - block = mmAllocMem(dev_priv->FBHeap, fb.size, 0, 0); + block = mmAllocMem(dev_priv->FBHeap, fb->size, 0, 0); if (block) { /* TODO */ - fb.offset = block->ofs; - fb.free = (unsigned long)block; - if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) { + fb->offset = block->ofs; + fb->free = (unsigned long)block; + if (!add_alloc_set(fb->context, VIDEO_TYPE, fb->free)) { DRM_DEBUG("adding to allocation set fails\n"); - mmFreeMem((PMemBlock) fb.free); - retval = DRM_ERR(EINVAL); + mmFreeMem((PMemBlock) fb->free); + retval = -EINVAL; } } else { - fb.offset = 0; - fb.size = 0; - fb.free = 0; + fb->offset = 0; + fb->size = 0; + fb->free = 0; } - DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb)); - - DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, fb.offset); + DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb->size, fb->offset); return retval; } -static int sis_fb_free(DRM_IOCTL_ARGS) +static int sis_fb_free(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; - drm_sis_mem_t fb; + drm_sis_mem_t *fb = data; if (dev_priv == NULL || dev_priv->FBHeap == NULL) - return DRM_ERR(EINVAL); + return -EINVAL; - DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb)); + if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock) fb->free)) + return -EINVAL; - if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock) fb.free)) - return DRM_ERR(EINVAL); + if (!del_alloc_set(fb->context, VIDEO_TYPE, fb->free)) + return -EINVAL; + mmFreeMem((PMemBlock) fb->free); - if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free)) - return DRM_ERR(EINVAL); - mmFreeMem((PMemBlock) fb.free); - - DRM_DEBUG("free fb, free = 0x%lx\n", fb.free); + DRM_DEBUG("free fb, free = 0x%lx\n", fb->free); return 0; } @@ -240,11 +221,10 @@ static int sis_fb_free(DRM_IOCTL_ARGS) /* agp memory management */ -static int sis_ioctl_agp_init(DRM_IOCTL_ARGS) +static int sis_ioctl_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; - drm_sis_agp_t agp; + drm_sis_agp_t *agp = data; if (dev_priv == NULL) { dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t), @@ -255,75 +235,63 @@ static int sis_ioctl_agp_init(DRM_IOCTL_ARGS) } if (dev_priv->AGPHeap != NULL) - return DRM_ERR(EINVAL); - - DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *) data, - sizeof(agp)); + return -EINVAL; - dev_priv->AGPHeap = mmInit(agp.offset, agp.size); + dev_priv->AGPHeap = mmInit(agp->offset, agp->size); - DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size); + DRM_DEBUG("offset = %u, size = %u", agp->offset, agp->size); return 0; } -static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS) +static int sis_ioctl_agp_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; - drm_sis_mem_t __user *argp = (drm_sis_mem_t __user *)data; - drm_sis_mem_t agp; + drm_sis_mem_t *agp = data; PMemBlock block; int retval = 0; if (dev_priv == NULL || dev_priv->AGPHeap == NULL) - return DRM_ERR(EINVAL); + return -EINVAL; - DRM_COPY_FROM_USER_IOCTL(agp, argp, sizeof(agp)); - - block = mmAllocMem(dev_priv->AGPHeap, agp.size, 0, 0); + block = mmAllocMem(dev_priv->AGPHeap, agp->size, 0, 0); if (block) { /* TODO */ - agp.offset = block->ofs; - agp.free = (unsigned long)block; - if (!add_alloc_set(agp.context, AGP_TYPE, agp.free)) { + agp->offset = block->ofs; + agp->free = (unsigned long)block; + if (!add_alloc_set(agp->context, AGP_TYPE, agp->free)) { DRM_DEBUG("adding to allocation set fails\n"); - mmFreeMem((PMemBlock) agp.free); + mmFreeMem((PMemBlock) agp->free); retval = -1; } } else { - agp.offset = 0; - agp.size = 0; - agp.free = 0; + agp->offset = 0; + agp->size = 0; + agp->free = 0; } - DRM_COPY_TO_USER_IOCTL(argp, agp, sizeof(agp)); - - DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size, agp.offset); + DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp->size, + agp->offset); return retval; } -static int sis_ioctl_agp_free(DRM_IOCTL_ARGS) +static int sis_ioctl_agp_free(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_sis_private_t *dev_priv = dev->dev_private; - drm_sis_mem_t agp; + drm_sis_mem_t *agp = data; if (dev_priv == NULL || dev_priv->AGPHeap == NULL) - return DRM_ERR(EINVAL); - - DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t __user *) data, - sizeof(agp)); + return -EINVAL; - if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock) agp.free)) - return DRM_ERR(EINVAL); + if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock) agp->free)) + return -EINVAL; - mmFreeMem((PMemBlock) agp.free); - if (!del_alloc_set(agp.context, AGP_TYPE, agp.free)) - return DRM_ERR(EINVAL); + mmFreeMem((PMemBlock) agp->free); + if (!del_alloc_set(agp->context, AGP_TYPE, agp->free)) + return -EINVAL; - DRM_DEBUG("free agp, free = 0x%lx\n", agp.free); + DRM_DEBUG("free agp, free = 0x%lx\n", agp->free); return 0; } @@ -407,12 +375,12 @@ int sis_final_context(struct drm_device *dev, int context) } drm_ioctl_desc_t sis_ioctls[] = { - [DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, - [DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY} + DRM_IOCTL_DEF(DRM_SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_SIS_FB_FREE, sis_fb_free, DRM_AUTH), + DRM_IOCTL_DEF(DRM_SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_SIS_AGP_FREE, sis_ioctl_agp_free, DRM_AUTH), + DRM_IOCTL_DEF(DRM_SIS_FB_INIT, sis_fb_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY) }; int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); diff --git a/shared-core/via_dma.c b/shared-core/via_dma.c index 333c4bcf..bd737a7e 100644 --- a/shared-core/via_dma.c +++ b/shared-core/via_dma.c @@ -139,7 +139,7 @@ static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv, return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low); } -int via_dma_cleanup(drm_device_t * dev) +int via_dma_cleanup(struct drm_device * dev) { if (dev->dev_private) { drm_via_private_t *dev_priv = @@ -157,30 +157,30 @@ int via_dma_cleanup(drm_device_t * dev) return 0; } -static int via_initialize(drm_device_t * dev, +static int via_initialize(struct drm_device * dev, drm_via_private_t * dev_priv, drm_via_dma_init_t * init) { if (!dev_priv || !dev_priv->mmio) { DRM_ERROR("via_dma_init called before via_map_init\n"); - return DRM_ERR(EFAULT); + return -EFAULT; } if (dev_priv->ring.virtual_start != NULL) { DRM_ERROR("%s called again without calling cleanup\n", __FUNCTION__); - return DRM_ERR(EFAULT); + return -EFAULT; } if (!dev->agp || !dev->agp->base) { DRM_ERROR("%s called with no agp memory available\n", __FUNCTION__); - return DRM_ERR(EFAULT); + return -EFAULT; } if (dev_priv->chipset == VIA_DX9_0) { DRM_ERROR("AGP DMA is not supported on this chip\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } dev_priv->ring.map.offset = dev->agp->base + init->offset; @@ -195,7 +195,7 @@ static int via_initialize(drm_device_t * dev, via_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); - return DRM_ERR(ENOMEM); + return -ENOMEM; } dev_priv->ring.virtual_start = dev_priv->ring.map.handle; @@ -215,35 +215,31 @@ static int via_initialize(drm_device_t * dev, return 0; } -static int via_dma_init(DRM_IOCTL_ARGS) +static int via_dma_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; - drm_via_dma_init_t init; + drm_via_dma_init_t *init = data; int retcode = 0; - DRM_COPY_FROM_USER_IOCTL(init, (drm_via_dma_init_t __user *) data, - sizeof(init)); - - switch (init.func) { + switch (init->func) { case VIA_INIT_DMA: if (!DRM_SUSER(DRM_CURPROC)) - retcode = DRM_ERR(EPERM); + retcode = -EPERM; else - retcode = via_initialize(dev, dev_priv, &init); + retcode = via_initialize(dev, dev_priv, init); break; case VIA_CLEANUP_DMA: if (!DRM_SUSER(DRM_CURPROC)) - retcode = DRM_ERR(EPERM); + retcode = -EPERM; else retcode = via_dma_cleanup(dev); break; case VIA_DMA_INITIALIZED: retcode = (dev_priv->ring.virtual_start != NULL) ? - 0 : DRM_ERR(EFAULT); + 0 : -EFAULT; break; default: - retcode = DRM_ERR(EINVAL); + retcode = -EINVAL; break; } @@ -252,7 +248,7 @@ static int via_dma_init(DRM_IOCTL_ARGS) -static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) +static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * cmd) { drm_via_private_t *dev_priv; uint32_t *vb; @@ -263,15 +259,15 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) if (dev_priv->ring.virtual_start == NULL) { DRM_ERROR("%s called without initializing AGP ring buffer.\n", __FUNCTION__); - return DRM_ERR(EFAULT); + return -EFAULT; } if (cmd->size > VIA_PCI_BUF_SIZE) { - return DRM_ERR(ENOMEM); + return -ENOMEM; } if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) - return DRM_ERR(EFAULT); + return -EFAULT; /* * Running this function on AGP memory is dead slow. Therefore @@ -287,7 +283,7 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size); if (vb == NULL) { - return DRM_ERR(EAGAIN); + return -EAGAIN; } memcpy(vb, dev_priv->pci_buf, cmd->size); @@ -306,39 +302,35 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) return 0; } -int via_driver_dma_quiescent(drm_device_t * dev) +int via_driver_dma_quiescent(struct drm_device * dev) { drm_via_private_t *dev_priv = dev->dev_private; if (!via_wait_idle(dev_priv)) { - return DRM_ERR(EBUSY); + return -EBUSY; } return 0; } -static int via_flush_ioctl(DRM_IOCTL_ARGS) +static int via_flush_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - LOCK_TEST_WITH_RETURN(dev, filp); + LOCK_TEST_WITH_RETURN(dev, file_priv); return via_driver_dma_quiescent(dev); } -static int via_cmdbuffer(DRM_IOCTL_ARGS) +static int via_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_via_cmdbuffer_t cmdbuf; + drm_via_cmdbuffer_t *cmdbuf = data; int ret; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data, - sizeof(cmdbuf)); + LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_DEBUG("via cmdbuffer, buf %p size %lu\n", cmdbuf.buf, cmdbuf.size); + DRM_DEBUG("via cmdbuffer, buf %p size %lu\n", cmdbuf->buf, + cmdbuf->size); - ret = via_dispatch_cmdbuffer(dev, &cmdbuf); + ret = via_dispatch_cmdbuffer(dev, cmdbuf); if (ret) { return ret; } @@ -346,17 +338,17 @@ static int via_cmdbuffer(DRM_IOCTL_ARGS) return 0; } -static int via_dispatch_pci_cmdbuffer(drm_device_t * dev, +static int via_dispatch_pci_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * cmd) { drm_via_private_t *dev_priv = dev->dev_private; int ret; if (cmd->size > VIA_PCI_BUF_SIZE) { - return DRM_ERR(ENOMEM); + return -ENOMEM; } if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size)) - return DRM_ERR(EFAULT); + return -EFAULT; if ((ret = via_verify_command_stream((uint32_t *) dev_priv->pci_buf, @@ -370,21 +362,17 @@ static int via_dispatch_pci_cmdbuffer(drm_device_t * dev, return ret; } -static int via_pci_cmdbuffer(DRM_IOCTL_ARGS) +static int via_pci_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_via_cmdbuffer_t cmdbuf; + drm_via_cmdbuffer_t *cmdbuf = data; int ret; - LOCK_TEST_WITH_RETURN(dev, filp); - - DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data, - sizeof(cmdbuf)); + LOCK_TEST_WITH_RETURN(dev, file_priv); - DRM_DEBUG("via_pci_cmdbuffer, buf %p size %lu\n", cmdbuf.buf, - cmdbuf.size); + DRM_DEBUG("via_pci_cmdbuffer, buf %p size %lu\n", cmdbuf->buf, + cmdbuf->size); - ret = via_dispatch_pci_cmdbuffer(dev, &cmdbuf); + ret = via_dispatch_pci_cmdbuffer(dev, cmdbuf); if (ret) { return ret; } @@ -645,94 +633,87 @@ static void via_cmdbuf_reset(drm_via_private_t * dev_priv) * User interface to the space and lag functions. */ -static int via_cmdbuf_size(DRM_IOCTL_ARGS) +static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_via_cmdbuf_size_t d_siz; + drm_via_cmdbuf_size_t *d_siz = data; int ret = 0; uint32_t tmp_size, count; drm_via_private_t *dev_priv; DRM_DEBUG("via cmdbuf_size\n"); - LOCK_TEST_WITH_RETURN( dev, filp ); + LOCK_TEST_WITH_RETURN(dev, file_priv); dev_priv = (drm_via_private_t *) dev->dev_private; if (dev_priv->ring.virtual_start == NULL) { DRM_ERROR("%s called without initializing AGP ring buffer.\n", __FUNCTION__); - return DRM_ERR(EFAULT); + return -EFAULT; } - DRM_COPY_FROM_USER_IOCTL(d_siz, (drm_via_cmdbuf_size_t __user *) data, - sizeof(d_siz)); - - count = 1000000; - tmp_size = d_siz.size; - switch(d_siz.func) { + tmp_size = d_siz->size; + switch(d_siz->func) { case VIA_CMDBUF_SPACE: - while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz.size) + while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size) && count--) { - if (!d_siz.wait) { + if (!d_siz->wait) { break; } } if (!count) { DRM_ERROR("VIA_CMDBUF_SPACE timed out.\n"); - ret = DRM_ERR(EAGAIN); + ret = -EAGAIN; } break; case VIA_CMDBUF_LAG: - while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz.size) + while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size) && count--) { - if (!d_siz.wait) { + if (!d_siz->wait) { break; } } if (!count) { DRM_ERROR("VIA_CMDBUF_LAG timed out.\n"); - ret = DRM_ERR(EAGAIN); + ret = -EAGAIN; } break; default: - ret = DRM_ERR(EFAULT); + ret = -EFAULT; } - d_siz.size = tmp_size; + d_siz->size = tmp_size; - DRM_COPY_TO_USER_IOCTL((drm_via_cmdbuf_size_t __user *) data, d_siz, - sizeof(d_siz)); return ret; } #ifndef VIA_HAVE_DMABLIT int -via_dma_blit_sync( DRM_IOCTL_ARGS ) { +via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv ) { DRM_ERROR("PCI DMA BitBlt is not implemented for this system.\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } int -via_dma_blit( DRM_IOCTL_ARGS ) { +via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv ) { DRM_ERROR("PCI DMA BitBlt is not implemented for this system.\n"); - return DRM_ERR(EINVAL); + return -EINVAL; } #endif -drm_ioctl_desc_t via_ioctls[] = { - [DRM_IOCTL_NR(DRM_VIA_ALLOCMEM)] = {via_mem_alloc, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_FREEMEM)] = {via_mem_free, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_AGP_INIT)] = {via_agp_init, DRM_AUTH|DRM_MASTER}, - [DRM_IOCTL_NR(DRM_VIA_FB_INIT)] = {via_fb_init, DRM_AUTH|DRM_MASTER}, - [DRM_IOCTL_NR(DRM_VIA_MAP_INIT)] = {via_map_init, DRM_AUTH|DRM_MASTER}, - [DRM_IOCTL_NR(DRM_VIA_DEC_FUTEX)] = {via_decoder_futex, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_DMA_INIT)] = {via_dma_init, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_CMDBUFFER)] = {via_cmdbuffer, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_FLUSH)] = {via_flush_ioctl, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_PCICMD)] = {via_pci_cmdbuffer, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_CMDBUF_SIZE)] = {via_cmdbuf_size, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_WAIT_IRQ)] = {via_wait_irq, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_DMA_BLIT)] = {via_dma_blit, DRM_AUTH}, - [DRM_IOCTL_NR(DRM_VIA_BLIT_SYNC)] = {via_dma_blit_sync, DRM_AUTH} +struct drm_ioctl_desc via_ioctls[] = { + DRM_IOCTL_DEF(DRM_VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_FREEMEM, via_mem_free, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER), + DRM_IOCTL_DEF(DRM_VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER), + DRM_IOCTL_DEF(DRM_VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER), + DRM_IOCTL_DEF(DRM_VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_DMA_INIT, via_dma_init, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_FLUSH, via_flush_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_DMA_BLIT, via_dma_blit, DRM_AUTH), + DRM_IOCTL_DEF(DRM_VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH) }; int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); diff --git a/shared-core/via_drm.h b/shared-core/via_drm.h index 635e4637..b15785b3 100644 --- a/shared-core/via_drm.h +++ b/shared-core/via_drm.h @@ -54,7 +54,7 @@ #define VIA_NR_XVMC_LOCKS 5 #define VIA_MAX_CACHELINE_SIZE 64 #define XVMCLOCKPTR(saPriv,lockNo) \ - ((volatile drm_hw_lock_t *)(((((unsigned long) (saPriv)->XvMCLockArea) + \ + ((volatile struct drm_hw_lock *)(((((unsigned long) (saPriv)->XvMCLockArea) + \ (VIA_MAX_CACHELINE_SIZE - 1)) & \ ~(VIA_MAX_CACHELINE_SIZE - 1)) + \ VIA_MAX_CACHELINE_SIZE*(lockNo))) @@ -187,7 +187,7 @@ typedef struct _drm_via_tex_region { typedef struct _drm_via_sarea { unsigned int dirty; unsigned int nbox; - drm_clip_rect_t boxes[VIA_NR_SAREA_CLIPRECTS]; + struct drm_clip_rect boxes[VIA_NR_SAREA_CLIPRECTS]; drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1]; int texAge; /* last time texture was uploaded */ int ctxOwner; /* last context to upload state */ diff --git a/shared-core/via_drv.c b/shared-core/via_drv.c index 0a478fef..3a6f27fb 100644 --- a/shared-core/via_drv.c +++ b/shared-core/via_drv.c @@ -40,7 +40,7 @@ static struct pci_device_id pciidlist[] = { #ifdef VIA_HAVE_FENCE -static drm_fence_driver_t via_fence_driver = { +static struct drm_fence_driver via_fence_driver = { .num_classes = 1, .wrap_diff = (1 << 30), .flush_diff = (1 << 20), @@ -65,7 +65,7 @@ static uint32_t via_mem_prios[] = {DRM_BO_MEM_PRIV0, DRM_BO_MEM_VRAM, DRM_BO_MEM static uint32_t via_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_PRIV0, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL}; -static drm_bo_driver_t via_bo_driver = { +static struct drm_bo_driver via_bo_driver = { .mem_type_prio = via_mem_prios, .mem_busy_prio = via_busy_prios, .num_mem_type_prio = ARRAY_SIZE(via_mem_prios), @@ -83,14 +83,16 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *ent); static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | - DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL, + DRIVER_IRQ_SHARED, .load = via_driver_load, .unload = via_driver_unload, #ifndef VIA_HAVE_CORE_MM .context_ctor = via_init_context, #endif .context_dtor = via_final_context, - .vblank_wait = via_driver_vblank_wait, + .get_vblank_counter = via_get_vblank_counter, + .enable_vblank = via_enable_vblank, + .disable_vblank = via_disable_vblank, .irq_preinstall = via_driver_irq_preinstall, .irq_postinstall = via_driver_irq_postinstall, .irq_uninstall = via_driver_irq_uninstall, diff --git a/shared-core/via_drv.h b/shared-core/via_drv.h index baafbbff..bb1c4857 100644 --- a/shared-core/via_drv.h +++ b/shared-core/via_drv.h @@ -102,6 +102,7 @@ typedef struct drm_via_private { struct timeval last_vblank; int last_vblank_valid; unsigned usec_per_vblank; + atomic_t vbl_received; drm_via_state_t hc_state; char pci_buf[VIA_PCI_BUF_SIZE]; const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; @@ -116,7 +117,7 @@ typedef struct drm_via_private { /* Memory manager stuff */ #ifdef VIA_HAVE_CORE_MM unsigned int idle_fault; - drm_sman_t sman; + struct drm_sman sman; int vram_initialized; int agp_initialized; unsigned long vram_offset; @@ -148,54 +149,57 @@ enum via_family { #define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg) #define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val) -extern drm_ioctl_desc_t via_ioctls[]; +extern struct drm_ioctl_desc via_ioctls[]; extern int via_max_ioctl; -extern int via_fb_init(DRM_IOCTL_ARGS); -extern int via_mem_alloc(DRM_IOCTL_ARGS); -extern int via_mem_free(DRM_IOCTL_ARGS); -extern int via_agp_init(DRM_IOCTL_ARGS); -extern int via_map_init(DRM_IOCTL_ARGS); -extern int via_decoder_futex(DRM_IOCTL_ARGS); -extern int via_wait_irq(DRM_IOCTL_ARGS); -extern int via_dma_blit_sync( DRM_IOCTL_ARGS ); -extern int via_dma_blit( DRM_IOCTL_ARGS ); - -extern int via_driver_load(drm_device_t *dev, unsigned long chipset); -extern int via_driver_unload(drm_device_t *dev); -extern int via_final_context(drm_device_t * dev, int context); - -extern int via_do_cleanup_map(drm_device_t * dev); -extern int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence); +extern int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int via_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv ); +extern int via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv ); + +extern int via_driver_load(struct drm_device *dev, unsigned long chipset); +extern int via_driver_unload(struct drm_device *dev); +extern int via_final_context(struct drm_device * dev, int context); + +extern int via_do_cleanup_map(struct drm_device * dev); +extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc); +extern int via_enable_vblank(struct drm_device *dev, int crtc); +extern void via_disable_vblank(struct drm_device *dev, int crtc); extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS); -extern void via_driver_irq_preinstall(drm_device_t * dev); -extern void via_driver_irq_postinstall(drm_device_t * dev); -extern void via_driver_irq_uninstall(drm_device_t * dev); +extern void via_driver_irq_preinstall(struct drm_device * dev); +extern int via_driver_irq_postinstall(struct drm_device * dev); +extern void via_driver_irq_uninstall(struct drm_device * dev); -extern int via_dma_cleanup(drm_device_t * dev); +extern int via_dma_cleanup(struct drm_device * dev); extern void via_init_command_verifier(void); -extern int via_driver_dma_quiescent(drm_device_t * dev); +extern int via_driver_dma_quiescent(struct drm_device * dev); extern void via_init_futex(drm_via_private_t *dev_priv); extern void via_cleanup_futex(drm_via_private_t *dev_priv); extern void via_release_futex(drm_via_private_t *dev_priv, int context); #ifdef VIA_HAVE_CORE_MM -extern void via_reclaim_buffers_locked(drm_device_t *dev, struct file *filp); -extern void via_lastclose(drm_device_t *dev); +extern void via_reclaim_buffers_locked(struct drm_device *dev, + struct drm_file *file_priv); +extern void via_lastclose(struct drm_device *dev); #else -extern int via_init_context(drm_device_t * dev, int context); +extern int via_init_context(struct drm_device * dev, int context); #endif #ifdef VIA_HAVE_DMABLIT -extern void via_dmablit_handler(drm_device_t *dev, int engine, int from_irq); -extern void via_init_dmablit(drm_device_t *dev); +extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq); +extern void via_init_dmablit(struct drm_device *dev); #endif #ifdef VIA_HAVE_FENCE extern void via_fence_timer(unsigned long data); -extern void via_poke_flush(drm_device_t * dev, uint32_t class); -extern int via_fence_emit_sequence(drm_device_t * dev, uint32_t class, +extern void via_poke_flush(struct drm_device * dev, uint32_t class); +extern int via_fence_emit_sequence(struct drm_device * dev, uint32_t class, uint32_t flags, uint32_t * sequence, uint32_t * native_type); @@ -204,14 +208,15 @@ extern int via_fence_has_irq(struct drm_device * dev, uint32_t class, #endif #ifdef VIA_HAVE_BUFFER -extern drm_ttm_backend_t *via_create_ttm_backend_entry(drm_device_t *dev); -extern int via_fence_types(drm_buffer_object_t *bo, uint32_t *class, uint32_t *type); -extern int via_invalidate_caches(drm_device_t *dev, uint32_t buffer_flags); -extern int via_init_mem_type(drm_device_t *dev, uint32_t type, - drm_mem_type_manager_t *man); -extern uint32_t via_evict_mask(drm_buffer_object_t *bo); -extern int via_move(drm_buffer_object_t *bo, int evict, - int no_wait, drm_bo_mem_reg_t *new_mem); +extern struct drm_ttm_backend *via_create_ttm_backend_entry(struct drm_device *dev); +extern int via_fence_types(struct drm_buffer_object *bo, uint32_t *fclass, + uint32_t *type); +extern int via_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags); +extern int via_init_mem_type(struct drm_device *dev, uint32_t type, + struct drm_mem_type_manager *man); +extern uint32_t via_evict_mask(struct drm_buffer_object *bo); +extern int via_move(struct drm_buffer_object *bo, int evict, + int no_wait, struct drm_bo_mem_reg *new_mem); #endif #endif diff --git a/shared-core/via_irq.c b/shared-core/via_irq.c index 2ac86970..a1d33248 100644 --- a/shared-core/via_irq.c +++ b/shared-core/via_irq.c @@ -97,9 +97,18 @@ static unsigned time_diff(struct timeval *now,struct timeval *then) 1000000 - (then->tv_usec - now->tv_usec); } +u32 via_get_vblank_counter(struct drm_device *dev, int crtc) +{ + drm_via_private_t *dev_priv = dev->dev_private; + if (crtc != 0) + return 0; + + return atomic_read(&dev_priv->vbl_received); +} + irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) { - drm_device_t *dev = (drm_device_t *) arg; + struct drm_device *dev = (struct drm_device *) arg; drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; int handled = 0; @@ -109,8 +118,8 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) status = VIA_READ(VIA_REG_INTERRUPT); if (status & VIA_IRQ_VBLANK_PENDING) { - atomic_inc(&dev->vbl_received); - if (!(atomic_read(&dev->vbl_received) & 0x0F)) { + atomic_inc(&dev_priv->vbl_received); + if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) { #ifdef __linux__ do_gettimeofday(&cur_vblank); #else @@ -124,12 +133,11 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) dev_priv->last_vblank = cur_vblank; dev_priv->last_vblank_valid = 1; } - if (!(atomic_read(&dev->vbl_received) & 0xFF)) { + if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) { DRM_DEBUG("US per vblank is: %u\n", dev_priv->usec_per_vblank); } - DRM_WAKEUP(&dev->vbl_queue); - drm_vbl_send_signals(dev); + drm_handle_vblank(dev, 0); handled = 1; } @@ -171,35 +179,34 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) } } -int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) +int via_enable_vblank(struct drm_device *dev, int crtc) { - drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; - unsigned int cur_vblank; - int ret = 0; + drm_via_private_t *dev_priv = dev->dev_private; + u32 status; - DRM_DEBUG("viadrv_vblank_wait\n"); - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + if (crtc != 0) { + DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); return -EINVAL; } - viadrv_acknowledge_irqs(dev_priv); + status = VIA_READ(VIA_REG_INTERRUPT); + VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE); + return 0; +} - /* Assume that the user has missed the current sequence number - * by about a day rather than she wants to wait for years - * using vertical blanks... - */ +void via_disable_vblank(struct drm_device *dev, int crtc) +{ + if (crtc != 0) + DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); - DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(&dev->vbl_received)) - - *sequence) <= (1 << 23))); - - *sequence = cur_vblank; - return ret; + /* + * FIXME: implement proper interrupt disable by using the vblank + * counter register (if available). + */ } static int -via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, +via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequence, unsigned int *sequence) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; @@ -213,13 +220,13 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } if (irq >= drm_via_irq_num ) { DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, irq); - return DRM_ERR(EINVAL); + return -EINVAL; } real_irq = dev_priv->irq_map[irq]; @@ -227,7 +234,7 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, if (real_irq < 0) { DRM_ERROR("%s Video IRQ %d not available on this hardware.\n", __FUNCTION__, irq); - return DRM_ERR(EINVAL); + return -EINVAL; } masks = dev_priv->irq_masks; @@ -253,7 +260,7 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, * drm_dma.h hooks */ -void via_driver_irq_preinstall(drm_device_t * dev) +void via_driver_irq_preinstall(struct drm_device * dev) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; @@ -302,26 +309,27 @@ void via_driver_irq_preinstall(drm_device_t * dev) } } -void via_driver_irq_postinstall(drm_device_t * dev) +int via_driver_irq_postinstall(struct drm_device * dev) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; DRM_DEBUG("via_driver_irq_postinstall\n"); - if (dev_priv) { - status = VIA_READ(VIA_REG_INTERRUPT); - VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL - | dev_priv->irq_enable_mask); + if (!dev_priv) + return -EINVAL; - /* Some magic, oh for some data sheets ! */ + status = VIA_READ(VIA_REG_INTERRUPT); + VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL + | dev_priv->irq_enable_mask); - VIA_WRITE8(0x83d4, 0x11); - VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); - - } + /* Some magic, oh for some data sheets ! */ + VIA_WRITE8(0x83d4, 0x11); + VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); + + return 0; } -void via_driver_irq_uninstall(drm_device_t * dev) +void via_driver_irq_uninstall(struct drm_device * dev) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; @@ -340,11 +348,9 @@ void via_driver_irq_uninstall(drm_device_t * dev) } } -int via_wait_irq(DRM_IOCTL_ARGS) +int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_via_irqwait_t __user *argp = (void __user *)data; - drm_via_irqwait_t irqwait; + drm_via_irqwait_t *irqwait = data; struct timeval now; int ret = 0; drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; @@ -352,46 +358,44 @@ int via_wait_irq(DRM_IOCTL_ARGS) int force_sequence; if (!dev->irq) - return DRM_ERR(EINVAL); + return -EINVAL; - DRM_COPY_FROM_USER_IOCTL(irqwait, argp, sizeof(irqwait)); - if (irqwait.request.irq >= dev_priv->num_irqs) { + if (irqwait->request.irq >= dev_priv->num_irqs) { DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, - irqwait.request.irq); - return DRM_ERR(EINVAL); + irqwait->request.irq); + return -EINVAL; } - cur_irq += irqwait.request.irq; + cur_irq += irqwait->request.irq; - switch (irqwait.request.type & ~VIA_IRQ_FLAGS_MASK) { + switch (irqwait->request.type & ~VIA_IRQ_FLAGS_MASK) { case VIA_IRQ_RELATIVE: - irqwait.request.sequence += atomic_read(&cur_irq->irq_received); - irqwait.request.type &= ~_DRM_VBLANK_RELATIVE; + irqwait->request.sequence += + atomic_read(&cur_irq->irq_received); + irqwait->request.type &= ~_DRM_VBLANK_RELATIVE; case VIA_IRQ_ABSOLUTE: break; default: - return DRM_ERR(EINVAL); + return -EINVAL; } - if (irqwait.request.type & VIA_IRQ_SIGNAL) { + if (irqwait->request.type & VIA_IRQ_SIGNAL) { DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n", __FUNCTION__); - return DRM_ERR(EINVAL); + return -EINVAL; } - force_sequence = (irqwait.request.type & VIA_IRQ_FORCE_SEQUENCE); + force_sequence = (irqwait->request.type & VIA_IRQ_FORCE_SEQUENCE); - ret = via_driver_irq_wait(dev, irqwait.request.irq, force_sequence, - &irqwait.request.sequence); + ret = via_driver_irq_wait(dev, irqwait->request.irq, force_sequence, + &irqwait->request.sequence); #ifdef __linux__ do_gettimeofday(&now); #else microtime(&now); #endif - irqwait.reply.tval_sec = now.tv_sec; - irqwait.reply.tval_usec = now.tv_usec; - - DRM_COPY_TO_USER_IOCTL(argp, irqwait, sizeof(irqwait)); + irqwait->reply.tval_sec = now.tv_sec; + irqwait->reply.tval_usec = now.tv_usec; return ret; } diff --git a/shared-core/via_map.c b/shared-core/via_map.c index 037a1c2c..1623df68 100644 --- a/shared-core/via_map.c +++ b/shared-core/via_map.c @@ -25,7 +25,7 @@ #include "via_drm.h" #include "via_drv.h" -static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) +static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init) { drm_via_private_t *dev_priv = dev->dev_private; int ret = 0; @@ -83,7 +83,7 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) } -int via_do_cleanup_map(drm_device_t * dev) +int via_do_cleanup_map(struct drm_device * dev) { via_dma_cleanup(dev); @@ -91,19 +91,15 @@ int via_do_cleanup_map(drm_device_t * dev) } -int via_map_init(DRM_IOCTL_ARGS) +int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_via_init_t init; + drm_via_init_t *init = data; DRM_DEBUG("%s\n", __FUNCTION__); - DRM_COPY_FROM_USER_IOCTL(init, (drm_via_init_t __user *) data, - sizeof(init)); - - switch (init.func) { + switch (init->func) { case VIA_INIT_MAP: - return via_do_init_map(dev, &init); + return via_do_init_map(dev, init); case VIA_CLEANUP_MAP: return via_do_cleanup_map(dev); } @@ -111,14 +107,14 @@ int via_map_init(DRM_IOCTL_ARGS) return -EINVAL; } -int via_driver_load(drm_device_t *dev, unsigned long chipset) +int via_driver_load(struct drm_device *dev, unsigned long chipset) { drm_via_private_t *dev_priv; int ret = 0; dev_priv = drm_calloc(1, sizeof(drm_via_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) - return DRM_ERR(ENOMEM); + return -ENOMEM; dev->dev_private = (void *)dev_priv; @@ -133,7 +129,7 @@ int via_driver_load(drm_device_t *dev, unsigned long chipset) return ret; } -int via_driver_unload(drm_device_t *dev) +int via_driver_unload(struct drm_device *dev) { drm_via_private_t *dev_priv = dev->dev_private; diff --git a/shared-core/via_mm.c b/shared-core/via_mm.c index 8f175a7d..45790dc2 100644 --- a/shared-core/via_mm.c +++ b/shared-core/via_mm.c @@ -72,17 +72,14 @@ static int del_alloc_set(int context, int type, unsigned long val) /* agp memory management */ static memHeap_t *AgpHeap = NULL; -int via_agp_init(DRM_IOCTL_ARGS) +int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_via_agp_t agp; + drm_via_agp_t *agp = data; - DRM_COPY_FROM_USER_IOCTL(agp, (drm_via_agp_t __user *) data, - sizeof(agp)); + AgpHeap = via_mmInit(agp->offset, agp->size); - AgpHeap = via_mmInit(agp.offset, agp.size); - - DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset, - (unsigned long)agp.size); + DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp->offset, + (unsigned long)agp->size); return 0; } @@ -90,11 +87,9 @@ int via_agp_init(DRM_IOCTL_ARGS) /* fb memory management */ static memHeap_t *FBHeap = NULL; -int via_fb_init(DRM_IOCTL_ARGS) +int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_via_fb_t fb; - - DRM_COPY_FROM_USER_IOCTL(fb, (drm_via_fb_t __user *) data, sizeof(fb)); + drm_via_fb_t *fb = data; FBHeap = via_mmInit(fb.offset, fb.size); @@ -191,25 +186,18 @@ int via_final_context(struct drm_device *dev, int context) return 1; } -int via_mem_alloc(DRM_IOCTL_ARGS) +int via_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_via_mem_t mem; - - DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data, - sizeof(mem)); + drm_via_mem_t *mem = data; switch (mem.type) { case VIA_MEM_VIDEO: - if (via_fb_alloc(&mem) < 0) + if (via_fb_alloc(mem) < 0) return -EFAULT; - DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, - sizeof(mem)); return 0; case VIA_MEM_AGP: - if (via_agp_alloc(&mem) < 0) + if (via_agp_alloc(mem) < 0) return -EFAULT; - DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, - sizeof(mem)); return 0; } @@ -288,21 +276,18 @@ static int via_agp_alloc(drm_via_mem_t * mem) return retval; } -int via_mem_free(DRM_IOCTL_ARGS) +int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv) { - drm_via_mem_t mem; + drm_via_mem_t *mem = data; - DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data, - sizeof(mem)); - - switch (mem.type) { + switch (mem->type) { case VIA_MEM_VIDEO: - if (via_fb_free(&mem) == 0) + if (via_fb_free(mem) == 0) return 0; break; case VIA_MEM_AGP: - if (via_agp_free(&mem) == 0) + if (via_agp_free(mem) == 0) return 0; break; } @@ -356,7 +341,7 @@ static int via_agp_free(drm_via_mem_t * mem) retval = -1; } - DRM_DEBUG("free agp, free = %ld\n", agp.free); + DRM_DEBUG("free agp, free = %ld\n", agp.nfree); return retval; } diff --git a/shared-core/via_verifier.c b/shared-core/via_verifier.c index 4b844af0..ded5c4e1 100644 --- a/shared-core/via_verifier.c +++ b/shared-core/via_verifier.c @@ -252,10 +252,10 @@ eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words) static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t * seq, unsigned long offset, unsigned long size, - drm_device_t * dev) + struct drm_device * dev) { #ifdef __linux__ - drm_map_list_t *r_list; + struct drm_map_list *r_list; #endif drm_local_map_t *map = seq->map_cache; @@ -967,7 +967,7 @@ via_parse_vheader6(drm_via_private_t * dev_priv, uint32_t const **buffer, int via_verify_command_stream(const uint32_t * buf, unsigned int size, - drm_device_t * dev, int agp) + struct drm_device * dev, int agp) { drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; @@ -1031,18 +1031,18 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, case state_error: default: *hc_state = saved_state; - return DRM_ERR(EINVAL); + return -EINVAL; } } if (state == state_error) { *hc_state = saved_state; - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; } int -via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, +via_parse_command_stream(struct drm_device * dev, const uint32_t * buf, unsigned int size) { @@ -1087,11 +1087,11 @@ via_parse_command_stream(drm_device_t * dev, const uint32_t * buf, break; case state_error: default: - return DRM_ERR(EINVAL); + return -EINVAL; } } if (state == state_error) { - return DRM_ERR(EINVAL); + return -EINVAL; } return 0; } diff --git a/shared-core/via_verifier.h b/shared-core/via_verifier.h index 84497c44..dac1db91 100644 --- a/shared-core/via_verifier.h +++ b/shared-core/via_verifier.h @@ -49,7 +49,7 @@ typedef struct { drm_via_sequence_t unfinished; int agp_texture; int multitex; - drm_device_t *dev; + struct drm_device *dev; drm_local_map_t *map_cache; uint32_t vertex_count; int agp; @@ -57,8 +57,8 @@ typedef struct { } drm_via_state_t; extern int via_verify_command_stream(const uint32_t * buf, unsigned int size, - drm_device_t *dev, int agp); -extern int via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, + struct drm_device *dev, int agp); +extern int via_parse_command_stream(struct drm_device *dev, const uint32_t * buf, unsigned int size); #endif diff --git a/shared-core/via_video.c b/shared-core/via_video.c index 300ac61b..c15e75b5 100644 --- a/shared-core/via_video.c +++ b/shared-core/via_video.c @@ -65,10 +65,9 @@ void via_release_futex(drm_via_private_t * dev_priv, int context) } } -int via_decoder_futex(DRM_IOCTL_ARGS) +int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv) { - DRM_DEVICE; - drm_via_futex_t fx; + drm_via_futex_t *fx = data; volatile int *lock; drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; drm_via_sarea_t *sAPriv = dev_priv->sarea_priv; @@ -76,21 +75,18 @@ int via_decoder_futex(DRM_IOCTL_ARGS) DRM_DEBUG("%s\n", __FUNCTION__); - DRM_COPY_FROM_USER_IOCTL(fx, (drm_via_futex_t __user *) data, - sizeof(fx)); - - if (fx.lock > VIA_NR_XVMC_LOCKS) + if (fx->lock > VIA_NR_XVMC_LOCKS) return -EFAULT; - lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx.lock); + lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock); - switch (fx.func) { + switch (fx->func) { case VIA_FUTEX_WAIT: - DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx.lock], - (fx.ms / 10) * (DRM_HZ / 100), *lock != fx.val); + DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx->lock], + (fx->ms / 10) * (DRM_HZ / 100), *lock != fx->val); return ret; case VIA_FUTEX_WAKE: - DRM_WAKEUP(&(dev_priv->decoder_queue[fx.lock])); + DRM_WAKEUP(&(dev_priv->decoder_queue[fx->lock])); return 0; } return 0; diff --git a/shared-core/xgi_drm.h b/shared-core/xgi_drm.h new file mode 100644 index 00000000..de0fb532 --- /dev/null +++ b/shared-core/xgi_drm.h @@ -0,0 +1,133 @@ +/**************************************************************************** + * Copyright (C) 2003-2006 by XGI Technology, Taiwan. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR + * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ***************************************************************************/ + +#ifndef _XGI_DRM_H_ +#define _XGI_DRM_H_ + +#include <linux/types.h> +#include <asm/ioctl.h> + +struct drm_xgi_sarea { + __u16 device_id; + __u16 vendor_id; + + char device_name[32]; + + unsigned int scrn_start; + unsigned int scrn_xres; + unsigned int scrn_yres; + unsigned int scrn_bpp; + unsigned int scrn_pitch; +}; + + +struct xgi_bootstrap { + /** + * Size of PCI-e GART range in megabytes. + */ + struct drm_map gart; +}; + + +enum xgi_mem_location { + XGI_MEMLOC_NON_LOCAL = 0, + XGI_MEMLOC_LOCAL = 1, + XGI_MEMLOC_INVALID = 0x7fffffff +}; + +struct xgi_mem_alloc { + /** + * Memory region to be used for allocation. + * + * Must be one of XGI_MEMLOC_NON_LOCAL or XGI_MEMLOC_LOCAL. + */ + unsigned int location; + + /** + * Number of bytes request. + * + * On successful allocation, set to the actual number of bytes + * allocated. + */ + unsigned int size; + + /** + * Address of the memory from the graphics hardware's point of view. + */ + __u32 hw_addr; + + /** + * Offset of the allocation in the mapping. + */ + __u32 offset; + + /** + * Magic handle used to release memory. + * + * See also DRM_XGI_FREE ioctl. + */ + __u32 index; +}; + +enum xgi_batch_type { + BTYPE_2D = 0, + BTYPE_3D = 1, + BTYPE_FLIP = 2, + BTYPE_CTRL = 3, + BTYPE_NONE = 0x7fffffff +}; + +struct xgi_cmd_info { + __u32 type; + __u32 hw_addr; + __u32 size; + __u32 id; +}; + +struct xgi_state_info { + unsigned int _fromState; + unsigned int _toState; +}; + + +/* + * Ioctl definitions + */ + +#define DRM_XGI_BOOTSTRAP 0 +#define DRM_XGI_ALLOC 1 +#define DRM_XGI_FREE 2 +#define DRM_XGI_SUBMIT_CMDLIST 3 +#define DRM_XGI_STATE_CHANGE 4 + +#define XGI_IOCTL_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_BOOTSTRAP, struct xgi_bootstrap) +#define XGI_IOCTL_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_ALLOC, struct xgi_mem_alloc) +#define XGI_IOCTL_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_FREE, __u32) +#define XGI_IOCTL_SUBMIT_CMDLIST DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_SUBMIT_CMDLIST, struct xgi_cmd_info) +#define XGI_IOCTL_STATE_CHANGE DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_STATE_CHANGE, struct xgi_state_info) + +#endif /* _XGI_DRM_H_ */ |