diff options
Diffstat (limited to 'shared-core')
-rw-r--r-- | shared-core/drm.h | 348 | ||||
-rw-r--r-- | shared-core/i915_dma.c | 50 | ||||
-rw-r--r-- | shared-core/i915_drm.h | 52 | ||||
-rw-r--r-- | shared-core/i915_init.c | 2 | ||||
-rw-r--r-- | shared-core/r300_cmdbuf.c | 47 | ||||
-rw-r--r-- | shared-core/r300_reg.h | 14 | ||||
-rw-r--r-- | shared-core/radeon_cp.c | 56 | ||||
-rw-r--r-- | shared-core/radeon_cs.c | 411 | ||||
-rw-r--r-- | shared-core/radeon_drm.h | 24 | ||||
-rw-r--r-- | shared-core/radeon_drv.h | 180 | ||||
-rw-r--r-- | shared-core/radeon_state.c | 11 |
11 files changed, 678 insertions, 517 deletions
diff --git a/shared-core/drm.h b/shared-core/drm.h index dd03bf9b..b177dfe5 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -675,324 +675,6 @@ struct drm_set_version { int drm_dd_minor; }; - -#define DRM_FENCE_FLAG_EMIT 0x00000001 -#define DRM_FENCE_FLAG_SHAREABLE 0x00000002 -/** - * On hardware with no interrupt events for operation completion, - * indicates that the kernel should sleep while waiting for any blocking - * operation to complete rather than spinning. - * - * Has no effect otherwise. - */ -#define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004 -#define DRM_FENCE_FLAG_NO_USER 0x00000010 - -/* Reserved for driver use */ -#define DRM_FENCE_MASK_DRIVER 0xFF000000 - -#define DRM_FENCE_TYPE_EXE 0x00000001 - -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. - * Typically a texture buffer is read, A destination buffer is write and - * a command (batch-) buffer is exe. Can be or-ed together. - */ - -#define DRM_BO_FLAG_READ (1ULL << 0) -#define DRM_BO_FLAG_WRITE (1ULL << 1) -#define DRM_BO_FLAG_EXE (1ULL << 2) - -/* - * All of the bits related to access mode - */ -#define DRM_BO_MASK_ACCESS (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE) -/* - * Status flags. Can be read to determine the actual state of a buffer. - * Can also be set in the buffer mask before validation. - */ - -/* - * Mask: Never evict this buffer. Not even with force. This type of buffer is only - * available to root and must be manually removed before buffer manager shutdown - * or lock. - * Flags: Acknowledge - */ -#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 (1ULL << 5) - -/* Mask: The buffer should be shareable with other processes. - * Flags: The buffer is shareable with other processes. - */ -#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 (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. - * The buffer will also not be evicted when claiming space for - * other buffers. Basically a pinned buffer but it may be thrown out as - * part of buffer manager shutdown or locking. - * Flags: Acknowledge. - */ -#define DRM_BO_FLAG_NO_MOVE (1ULL << 8) - -/* Mask: Make sure the buffer is in cached memory when mapped. In conjunction - * with DRM_BO_FLAG_CACHED it also allows the buffer to be bound into the GART - * with unsnooped PTEs instead of snooped, by using chipset-specific cache - * flushing at bind time. A better name might be DRM_BO_FLAG_TT_UNSNOOPED, - * as the eviction to local memory (TTM unbind) on map is just a side effect - * to prevent aggressive cache prefetch from the GPU disturbing the cache - * management that the DRM is doing. - * - * Flags: Acknowledge. - * Buffers allocated with this flag should not be used for suballocators - * This type may have issues on CPUs with over-aggressive caching - * http://marc.info/?l=linux-kernel&m=102376926732464&w=2 - */ -#define DRM_BO_FLAG_CACHED_MAPPED (1ULL << 19) - - -/* Mask: Force DRM_BO_FLAG_CACHED flag strictly also if it is set. - * Flags: Acknowledge. - */ -#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 (1ULL << 14) -#define DRM_BO_FLAG_TILE (1ULL << 15) - -/* - * Memory type flags that can be or'ed together in the mask, but only - * one appears in flags. - */ - -/* System memory */ -#define DRM_BO_FLAG_MEM_LOCAL (1ULL << 24) -/* Translation table memory */ -#define DRM_BO_FLAG_MEM_TT (1ULL << 25) -/* Vram memory */ -#define DRM_BO_FLAG_MEM_VRAM (1ULL << 26) -/* Up to the driver to define. */ -#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 */ - -/* - * This is a mask covering all of the memory type flags; easier to just - * use a single constant than a bunch of | values. It covers - * DRM_BO_FLAG_MEM_LOCAL through DRM_BO_FLAG_MEM_PRIV4 - */ -#define DRM_BO_MASK_MEM 0x00000000FF000000ULL -/* - * This adds all of the CPU-mapping options in with the memory - * type to label all bits which change how the page gets mapped - */ -#define DRM_BO_MASK_MEMTYPE (DRM_BO_MASK_MEM | \ - DRM_BO_FLAG_CACHED_MAPPED | \ - DRM_BO_FLAG_CACHED | \ - DRM_BO_FLAG_MAPPABLE) - -/* Driver-private flags */ -#define DRM_BO_MASK_DRIVER 0xFFFF000000000000ULL - -/* - * Don't block on validate and map. Instead, return EBUSY. - */ -#define DRM_BO_HINT_DONT_BLOCK 0x00000002 -/* - * Don't place this buffer on the unfenced list. This means - * that the buffer will not end up having a fence associated - * with it as a result of this operation - */ -#define DRM_BO_HINT_DONT_FENCE 0x00000004 -/** - * On hardware with no interrupt events for operation completion, - * indicates that the kernel should sleep while waiting for any blocking - * operation to complete rather than spinning. - * - * Has no effect otherwise. - */ -#define DRM_BO_HINT_WAIT_LAZY 0x00000008 -/* - * The client has compute relocations refering to this buffer using the - * offset in the presumed_offset field. If that offset ends up matching - * where this buffer lands, the kernel is free to skip executing those - * relocations - */ -#define DRM_BO_HINT_PRESUMED_OFFSET 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; - uint64_t presumed_offset; -}; - -struct drm_bo_create_req { - uint64_t flags; - uint64_t size; - uint64_t buffer_start; - unsigned int hint; - unsigned int page_alignment; -}; - - -/* - * Reply flags - */ - -#define DRM_BO_REP_BUSY 0x00000001 - -struct drm_bo_info_rep { - uint64_t flags; - uint64_t proposed_flags; - 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 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 { - struct drm_bo_handle_arg req; - struct drm_bo_info_rep rep; - } d; -}; - -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 -#define DRM_BO_MEM_VRAM 2 -#define DRM_BO_MEM_PRIV0 3 -#define DRM_BO_MEM_PRIV1 4 -#define DRM_BO_MEM_PRIV2 5 -#define DRM_BO_MEM_PRIV3 6 -#define DRM_BO_MEM_PRIV4 7 - -#define DRM_BO_MEM_TYPES 8 /* For now. */ - -#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; -}; - -struct drm_mm_info_arg { - unsigned int mem_type; - uint64_t p_size; -}; - struct drm_gem_close { /** Handle of the object to be closed. */ uint32_t handle; @@ -1337,31 +1019,6 @@ struct drm_mode_crtc_lut { #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_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_arg) - #define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) #define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc) #define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA2, struct drm_mode_get_connector) @@ -1439,11 +1096,6 @@ 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/i915_dma.c b/shared-core/i915_dma.c index 1fdc5e17..7f025e62 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -135,7 +135,7 @@ int i915_dma_cleanup(struct drm_device * dev) return 0; } -#if defined(I915_HAVE_BUFFER) && defined(DRI2) +#if defined(DRI2) #define DRI2_SAREA_BLOCK_TYPE(b) ((b) >> 16) #define DRI2_SAREA_BLOCK_SIZE(b) ((b) & 0xffff) #define DRI2_SAREA_BLOCK_NEXT(p) \ @@ -213,12 +213,7 @@ static int i915_initialize(struct drm_device * dev, } } -#ifdef I915_HAVE_BUFFER - if (!drm_core_check_feature(dev, DRIVER_MODESET)) { - dev_priv->max_validate_buffers = I915_MAX_VALIDATE_BUFFERS; - } -#endif - + if (init->ring_size != 0) { dev_priv->ring.Size = init->ring_size; dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; @@ -253,10 +248,25 @@ static int i915_initialize(struct drm_device * dev, */ dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A; -#ifdef I915_HAVE_BUFFER - if (!drm_core_check_feature(dev, DRIVER_MODESET)) { - mutex_init(&dev_priv->cmdbuf_mutex); + /* Program Hardware Status Page */ + if (!I915_NEED_GFX_HWS(dev)) { + dev_priv->status_page_dmah = + drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff); + + if (!dev_priv->status_page_dmah) { + i915_dma_cleanup(dev); + DRM_ERROR("Can not allocate hardware status page\n"); + return -ENOMEM; + } + dev_priv->hws_vaddr = dev_priv->status_page_dmah->vaddr; + dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; + + memset(dev_priv->hws_vaddr, 0, PAGE_SIZE); + + I915_WRITE(0x02080, dev_priv->dma_status_page); } + DRM_DEBUG("Enabled hardware status page\n"); + #ifdef DRI2 if (init->func == I915_INIT_DMA2) { int ret = setup_dri2_sarea(dev, file_priv, init); @@ -267,7 +277,6 @@ static int i915_initialize(struct drm_device * dev, } } #endif /* DRI2 */ -#endif /* I915_HAVE_BUFFER */ return 0; } @@ -533,9 +542,6 @@ int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush) static int i915_dispatch_cmdbuffer(struct drm_device * dev, struct drm_i915_cmdbuffer * cmd) { -#ifdef I915_HAVE_FENCE - struct drm_i915_private *dev_priv = dev->dev_private; -#endif int nbox = cmd->num_cliprects; int i = 0, count, ret; @@ -562,10 +568,6 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev, } i915_emit_breadcrumb(dev); -#ifdef I915_HAVE_FENCE - if (unlikely((dev_priv->counter & 0xFF) == 0)) - drm_fence_flush_old(dev, 0, dev_priv->counter); -#endif return 0; } @@ -616,10 +618,6 @@ int i915_dispatch_batchbuffer(struct drm_device * dev, } i915_emit_breadcrumb(dev); -#ifdef I915_HAVE_FENCE - if (unlikely((dev_priv->counter & 0xFF) == 0)) - drm_fence_flush_old(dev, 0, dev_priv->counter); -#endif return 0; } @@ -678,7 +676,6 @@ static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync) void i915_dispatch_flip(struct drm_device * dev, int planes, int sync) { - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; int i; @@ -692,10 +689,6 @@ void i915_dispatch_flip(struct drm_device * dev, int planes, int sync) i915_do_dispatch_flip(dev, i, sync); i915_emit_breadcrumb(dev); -#ifdef I915_HAVE_FENCE - if (unlikely(!sync && ((dev_priv->counter & 0xFF) == 0))) - drm_fence_flush_old(dev, 0, dev_priv->counter); -#endif } int i915_quiescent(struct drm_device *dev) @@ -1049,9 +1042,6 @@ struct drm_ioctl_desc i915_ioctls[] = { 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 DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index 53087b57..ab13cd4a 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -380,58 +380,6 @@ typedef struct drm_i915_hws_addr { uint64_t addr; } drm_i915_hws_addr_t; -/* - * Relocation header is 4 uint32_ts - * 0 - 32 bit reloc count - * 1 - 32-bit relocation type - * 2-3 - 64-bit user buffer handle ptr for another list of relocs. - */ -#define I915_RELOC_HEADER 4 - -/* - * type 0 relocation has 4-uint32_t stride - * 0 - offset into buffer - * 1 - delta to add in - * 2 - buffer handle - * 3 - reserved (for optimisations later). - */ -/* - * type 1 relocation has 4-uint32_t stride. - * Hangs off the first item in the op list. - * Performed after all valiations are done. - * Try to group relocs into the same relocatee together for - * performance reasons. - * 0 - offset into buffer - * 1 - delta to add in - * 2 - buffer index in op list. - * 3 - relocatee index in op list. - */ -#define I915_RELOC_TYPE_0 0 -#define I915_RELOC0_STRIDE 4 -#define I915_RELOC_TYPE_1 1 -#define I915_RELOC1_STRIDE 4 - - -struct drm_i915_op_arg { - uint64_t next; - uint64_t reloc_ptr; - int handled; - unsigned int pad64; - 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; - drm_context_t context; /* for lockless use in the future */ - struct drm_fence_arg fence_arg; -}; - struct drm_i915_gem_init { /** * Beginning offset in the GTT to be managed by the DRM memory diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index b21351c0..7b88cc8d 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -437,7 +437,7 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) return; if (master_priv->sarea) - drm_rmmap(dev, master_priv->sarea); + drm_rmmap_locked(dev, master_priv->sarea); drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c index 05a76ef1..53961fc7 100644 --- a/shared-core/r300_cmdbuf.c +++ b/shared-core/r300_cmdbuf.c @@ -166,8 +166,6 @@ void r300_init_reg_flags(struct drm_device *dev) for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\ r300_reg_flags[i]|=(mark); -#define MARK_SAFE 1 -#define MARK_CHECK_OFFSET 2 #define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE) @@ -247,6 +245,11 @@ void r300_init_reg_flags(struct drm_device *dev) ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8); ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8); + ADD_RANGE(R500_SU_REG_DEST, 1); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV410) { + ADD_RANGE(R300_DST_PIPE_CONFIG, 1); + } + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { ADD_RANGE(R500_VAP_INDEX_OFFSET, 1); ADD_RANGE(R500_US_CONFIG, 2); @@ -257,6 +260,7 @@ void r300_init_reg_flags(struct drm_device *dev) ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2); ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2); ADD_RANGE(R500_ZB_FIFO_SIZE, 2); + ADD_RANGE(R500_GA_US_VECTOR_INDEX, 2); } else { ADD_RANGE(R300_PFS_CNTL_0, 3); ADD_RANGE(R300_PFS_NODE_0, 4); @@ -269,9 +273,39 @@ void r300_init_reg_flags(struct drm_device *dev) ADD_RANGE(R300_RS_ROUTE_0, 8); } + + /* add 2d blit engine registers for DDX */ + ADD_RANGE(RADEON_SRC_Y_X, 3); /* 1434, 1438, 143c, + SRC_Y_X, DST_Y_X, DST_HEIGHT_WIDTH + */ + ADD_RANGE(RADEON_DP_GUI_MASTER_CNTL, 1); /* 146c */ + ADD_RANGE(RADEON_DP_BRUSH_BKGD_CLR, 2); /* 1478, 147c */ + ADD_RANGE(RADEON_DP_SRC_FRGD_CLR, 2); /* 15d8, 15dc */ + ADD_RANGE(RADEON_DP_CNTL, 1); /* 16c0 */ + ADD_RANGE(RADEON_DP_WRITE_MASK, 1); /* 16cc */ + ADD_RANGE(RADEON_DEFAULT_SC_BOTTOM_RIGHT, 1); /* 16e8 */ + + ADD_RANGE(RADEON_DSTCACHE_CTLSTAT, 1); + ADD_RANGE(RADEON_WAIT_UNTIL, 1); + + ADD_RANGE_MARK(RADEON_DST_OFFSET, 1, MARK_CHECK_OFFSET); + ADD_RANGE_MARK(RADEON_SRC_OFFSET, 1, MARK_CHECK_OFFSET); + + ADD_RANGE_MARK(RADEON_DST_PITCH_OFFSET, 1, MARK_CHECK_OFFSET); + ADD_RANGE_MARK(RADEON_SRC_PITCH_OFFSET, 1, MARK_CHECK_OFFSET); + + /* TODO SCISSOR */ + ADD_RANGE_MARK(R300_SC_SCISSOR0, 2, MARK_CHECK_SCISSOR); + + ADD_RANGE(R300_SC_CLIP_0_A, 2); + ADD_RANGE(R300_SC_CLIP_RULE, 1); + ADD_RANGE(R300_SC_SCREENDOOR, 1); + + ADD_RANGE(R300_VAP_PVS_CODE_CNTL_0, 4); + ADD_RANGE(R300_VAP_PVS_VECTOR_INDX_REG, 2); } -static __inline__ int r300_check_range(unsigned reg, int count) +int r300_check_range(unsigned reg, int count) { int i; if (reg & ~0xffff) @@ -282,6 +316,13 @@ static __inline__ int r300_check_range(unsigned reg, int count) return 0; } +int r300_get_reg_flags(unsigned reg) +{ + if (reg & ~0xffff) + return -1; + return r300_reg_flags[(reg >> 2)]; +} + static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * dev_priv, drm_radeon_kcmd_buffer_t diff --git a/shared-core/r300_reg.h b/shared-core/r300_reg.h index d35dd39d..9e9cb526 100644 --- a/shared-core/r300_reg.h +++ b/shared-core/r300_reg.h @@ -129,15 +129,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* END: Wild guesses */ #define R300_SE_VTE_CNTL 0x20b0 -# define R300_VPORT_X_SCALE_ENA 0x00000001 -# define R300_VPORT_X_OFFSET_ENA 0x00000002 -# define R300_VPORT_Y_SCALE_ENA 0x00000004 -# define R300_VPORT_Y_OFFSET_ENA 0x00000008 -# define R300_VPORT_Z_SCALE_ENA 0x00000010 -# define R300_VPORT_Z_OFFSET_ENA 0x00000020 -# define R300_VTX_XY_FMT 0x00000100 -# define R300_VTX_Z_FMT 0x00000200 -# define R300_VTX_W0_FMT 0x00000400 # define R300_VTX_W0_NORMALIZE 0x00000800 # define R300_VTX_ST_DENORMALIZED 0x00001000 @@ -493,7 +484,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */ # define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24 -#define R300_GB_SELECT 0x401C + # define R300_GB_FOG_SELECT_C0A 0 # define R300_GB_FOG_SELECT_C1A 1 # define R300_GB_FOG_SELECT_C2A 2 @@ -955,7 +946,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* 32 bit chroma key */ #define R300_TX_CHROMA_KEY_0 0x4580 /* ff00ff00 == { 0, 1.0, 0, 1.0 } */ -#define R300_TX_BORDER_COLOR_0 0x45C0 /* END: Texture specification */ @@ -1340,7 +1330,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* gap */ -#define R300_RB3D_COLOROFFSET0 0x4E28 # define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */ #define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */ #define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */ @@ -1352,7 +1341,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Bit 17: 4x2 tiles * Bit 18: Extremely weird tile like, but some pixels duplicated? */ -#define R300_RB3D_COLORPITCH0 0x4E38 # define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */ # define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */ # define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */ diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 6fbcfeab..04f4b1f8 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -190,7 +190,7 @@ void radeon_pll_errata_after_data(struct drm_radeon_private *dev_priv) } } -int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr) +u32 RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr) { uint32_t data; @@ -661,8 +661,8 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, ((dev_priv->gart_vm_start - 1) & 0xffff0000) | (dev_priv->fb_location >> 16)); - if (dev_priv->mm.ring) { - ring_start = dev_priv->mm.ring->offset + + if (dev_priv->mm.ring.bo) { + ring_start = dev_priv->mm.ring.bo->offset + dev_priv->gart_vm_start; } else #if __OS_HAS_AGP @@ -695,9 +695,9 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->ring.tail = cur_read_ptr; - if (dev_priv->mm.ring_read_ptr) { + if (dev_priv->mm.ring_read.bo) { RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, - dev_priv->mm.ring_read_ptr->offset + + dev_priv->mm.ring_read.bo->offset + dev_priv->gart_vm_start); } else #if __OS_HAS_AGP @@ -748,9 +748,9 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) + RADEON_SCRATCH_REG_OFFSET); - if (dev_priv->mm.ring_read_ptr) + if (dev_priv->mm.ring_read.bo) dev_priv->scratch = ((__volatile__ u32 *) - dev_priv->mm.ring_read_ptr_map.virtual + + dev_priv->mm.ring_read.kmap.virtual + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); else dev_priv->scratch = ((__volatile__ u32 *) @@ -775,12 +775,18 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, radeon_do_wait_for_idle(dev_priv); /* Sync everything up */ + if (dev_priv->chip_family > CHIP_RV280) { RADEON_WRITE(RADEON_ISYNC_CNTL, (RADEON_ISYNC_ANY2D_IDLE3D | RADEON_ISYNC_ANY3D_IDLE2D | RADEON_ISYNC_WAIT_IDLEGUI | RADEON_ISYNC_CPSCRATCH_IDLEGUI)); - + } else { + RADEON_WRITE(RADEON_ISYNC_CNTL, + (RADEON_ISYNC_ANY2D_IDLE3D | + RADEON_ISYNC_ANY3D_IDLE2D | + RADEON_ISYNC_WAIT_IDLEGUI)); + } } static void radeon_test_writeback(drm_radeon_private_t * dev_priv) @@ -788,8 +794,8 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) u32 tmp; void *ring_read_ptr; - if (dev_priv->mm.ring_read_ptr) - ring_read_ptr = dev_priv->mm.ring_read_ptr_map.virtual; + if (dev_priv->mm.ring_read.bo) + ring_read_ptr = dev_priv->mm.ring_read.kmap.virtual; else ring_read_ptr = dev_priv->ring_rptr->handle; @@ -1353,8 +1359,7 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) if (dev_priv->gart_info.bus_addr) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); - if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) - DRM_ERROR("failed to cleanup PCI GART!\n"); + drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info); } if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) @@ -1362,6 +1367,7 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) if (dev_priv->pcigart_offset_set == 1) { drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); dev_priv->gart_info.addr = NULL; + dev_priv->pcigart_offset_set = 0; } } } @@ -1553,8 +1559,10 @@ void radeon_do_release(struct drm_device * dev) radeon_mem_takedown(&(dev_priv->gart_heap)); radeon_mem_takedown(&(dev_priv->fb_heap)); - - radeon_gem_mm_fini(dev); + if (dev_priv->user_mm_enable) { + radeon_gem_mm_fini(dev); + dev_priv->user_mm_enable = false; + } /* deallocate kernel resources */ radeon_do_cleanup_cp(dev); @@ -2270,6 +2278,7 @@ static void radeon_set_dynamic_clock(struct drm_device *dev, int mode) int radeon_modeset_cp_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; + uint32_t tmp; /* allocate a ring and ring rptr bits from GART space */ /* these are allocated in GEM files */ @@ -2278,8 +2287,8 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->ring.size = RADEON_DEFAULT_RING_SIZE; dev_priv->cp_mode = RADEON_CSQ_PRIBM_INDBM; - dev_priv->ring.start = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual; - dev_priv->ring.end = (u32 *)(void *)(unsigned long)dev_priv->mm.ring_map.virtual + + dev_priv->ring.start = (u32 *)(void *)(unsigned long)dev_priv->mm.ring.kmap.virtual; + dev_priv->ring.end = (u32 *)(void *)(unsigned long)dev_priv->mm.ring.kmap.virtual + dev_priv->ring.size / sizeof(u32); dev_priv->ring.size_l2qw = drm_order(dev_priv->ring.size / 8); dev_priv->ring.rptr_update = 4096; @@ -2289,14 +2298,21 @@ int radeon_modeset_cp_init(struct drm_device *dev) dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; - dev_priv->new_memmap = 1; + dev_priv->new_memmap = true; + r300_init_reg_flags(dev); + radeon_cp_load_microcode(dev_priv); - DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring->offset, dev_priv->mm.ring_read_ptr->offset); + DRM_DEBUG("ring offset is %x %x\n", dev_priv->mm.ring.bo->offset, dev_priv->mm.ring_read.bo->offset); radeon_cp_init_ring_buffer(dev, dev_priv); + /* need to enable BUS mastering in Buscntl */ + tmp = RADEON_READ(RADEON_BUS_CNTL); + tmp &= ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + radeon_do_engine_reset(dev); radeon_test_writeback(dev_priv); @@ -2367,8 +2383,8 @@ int radeon_modeset_preinit(struct drm_device *dev) if (dev_priv->is_atom_bios) { dev_priv->mode_info.atom_context = atom_parse(&card, dev_priv->bios); - radeon_get_clock_info(dev); } + radeon_get_clock_info(dev); return 0; } @@ -2523,7 +2539,7 @@ void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) master_priv->sarea_priv = NULL; if (master_priv->sarea) - drm_rmmap(dev, master_priv->sarea); + drm_rmmap_locked(dev, master_priv->sarea); drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); diff --git a/shared-core/radeon_cs.c b/shared-core/radeon_cs.c new file mode 100644 index 00000000..b0c4abe8 --- /dev/null +++ b/shared-core/radeon_cs.c @@ -0,0 +1,411 @@ +/* + * Copyright 2008 Jerome Glisse. + * 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 + * 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. + * + * Authors: + * Jerome Glisse <glisse@freedesktop.org> + */ +#include "drmP.h" +#include "radeon_drm.h" +#include "radeon_drv.h" +#include "r300_reg.h" + +int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct drm_radeon_cs *cs = data; + uint32_t *packets = NULL; + uint32_t cs_id; + uint32_t card_offset; + void *ib = NULL; + long size; + int r; + RING_LOCALS; + + /* set command stream id to 0 which is fake id */ + cs_id = 0; + DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); + + if (dev_priv == NULL) { + DRM_ERROR("called with no initialization\n"); + return -EINVAL; + } + if (!cs->dwords) { + return 0; + } + /* limit cs to 64K ib */ + if (cs->dwords > (16 * 1024)) { + return -EINVAL; + } + /* copy cs from userspace maybe we should copy into ib to save + * one copy but ib will be mapped wc so not good for cmd checking + * somethings worth testing i guess (Jerome) + */ + size = cs->dwords * sizeof(uint32_t); + packets = drm_alloc(size, DRM_MEM_DRIVER); + if (packets == NULL) { + return -ENOMEM; + } + if (DRM_COPY_FROM_USER(packets, (void __user *)(unsigned long)cs->packets, size)) { + r = -EFAULT; + goto out; + } + /* get ib */ + r = dev_priv->cs.ib_get(dev, &ib, cs->dwords, &card_offset); + if (r) { + goto out; + } + + /* now parse command stream */ + r = dev_priv->cs.parse(dev, fpriv, ib, packets, cs->dwords); + if (r) { + goto out; + } + + BEGIN_RING(4); + OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); + OUT_RING(card_offset); + OUT_RING(cs->dwords); + OUT_RING(CP_PACKET2()); + ADVANCE_RING(); + + /* emit cs id sequence */ + dev_priv->cs.id_emit(dev, &cs_id); + COMMIT_RING(); + + DRM_COPY_TO_USER(&cs->cs_id, &cs_id, sizeof(uint32_t)); +out: + dev_priv->cs.ib_free(dev, ib, cs->dwords); + drm_free(packets, size, DRM_MEM_DRIVER); + return r; +} + +/* for non-mm */ +static int radeon_nomm_relocate(struct drm_device *dev, struct drm_file *file_priv, uint32_t *reloc, uint32_t *offset) +{ + *offset = reloc[1]; + return 0; +} +#define RELOC_SIZE 2 +#define RADEON_2D_OFFSET_MASK 0x3fffff + +static __inline__ int radeon_cs_relocate_packet0(struct drm_device *dev, struct drm_file *file_priv, + uint32_t *packets, uint32_t offset_dw) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + uint32_t hdr = packets[offset_dw]; + uint32_t reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; + uint32_t val = packets[offset_dw + 1]; + uint32_t packet3_hdr = packets[offset_dw+2]; + uint32_t tmp, offset; + int ret; + + /* this is too strict we may want to expand the length in the future and have + old kernels ignore it. */ + if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) { + DRM_ERROR("Packet 3 was %x should have been %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16)); + return -EINVAL; + } + + switch(reg) { + case RADEON_DST_PITCH_OFFSET: + case RADEON_SRC_PITCH_OFFSET: + /* pass in the start of the reloc */ + ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset); + if (ret) + return ret; + tmp = (val & RADEON_2D_OFFSET_MASK) << 10; + val &= ~RADEON_2D_OFFSET_MASK; + offset += tmp; + offset >>= 10; + val |= offset; + break; + case R300_RB3D_COLOROFFSET0: + case R300_ZB_DEPTHOFFSET: + case R300_TX_OFFSET_0: + case R300_TX_OFFSET_0+4: + ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + 2, &offset); + if (ret) + return ret; + + offset &= 0xffffffe0; + val += offset; + break; + default: + break; + } + + packets[offset_dw + 1] = val; + return 0; +} + +static int radeon_cs_relocate_packet3(struct drm_device *dev, struct drm_file *file_priv, + uint32_t *packets, uint32_t offset_dw) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + uint32_t hdr = packets[offset_dw]; + int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16; + uint32_t reg = hdr & 0xff00; + uint32_t offset, val, tmp; + int ret; + + switch(reg) { + case RADEON_CNTL_HOSTDATA_BLT: + { + val = packets[offset_dw + 2]; + ret = dev_priv->cs.relocate(dev, file_priv, packets + offset_dw + num_dw + 2, &offset); + if (ret) + return ret; + + tmp = (val & RADEON_2D_OFFSET_MASK) << 10; + val &= ~RADEON_2D_OFFSET_MASK; + offset += tmp; + offset >>= 10; + val |= offset; + + packets[offset_dw + 2] = val; + } + default: + return -EINVAL; + } + return 0; +} + +static __inline__ int radeon_cs_check_offset(struct drm_device *dev, + uint32_t reg, uint32_t val) +{ + uint32_t offset; + + switch(reg) { + case RADEON_DST_PITCH_OFFSET: + case RADEON_SRC_PITCH_OFFSET: + offset = val & ((1 << 22) - 1); + offset <<= 10; + break; + case R300_RB3D_COLOROFFSET0: + case R300_ZB_DEPTHOFFSET: + offset = val; + break; + case R300_TX_OFFSET_0: + case R300_TX_OFFSET_0+4: + offset = val & 0xffffffe0; + break; + } + + return 0; +} + +int radeon_cs_packet0(struct drm_device *dev, struct drm_file *file_priv, + uint32_t *packets, uint32_t offset_dw) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + uint32_t hdr = packets[offset_dw]; + int num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2; + int need_reloc = 0; + int reg = (hdr & R300_CP_PACKET0_REG_MASK) << 2; + int count_dw = 1; + int ret; + + while (count_dw < num_dw) { + /* need to have something like the r300 validation here - + list of allowed registers */ + int flags; + + ret = r300_check_range(reg, 1); + switch(ret) { + case -1: + DRM_ERROR("Illegal register %x\n", reg); + break; + case 0: + break; + case 1: + flags = r300_get_reg_flags(reg); + if (flags == MARK_CHECK_OFFSET) { + if (num_dw > 2) { + DRM_ERROR("Cannot relocate inside type stream of reg0 packets\n"); + return -EINVAL; + } + + ret = radeon_cs_relocate_packet0(dev, file_priv, packets, offset_dw); + if (ret) + return ret; + DRM_DEBUG("need to relocate %x %d\n", reg, flags); + /* okay it should be followed by a NOP */ + } else if (flags == MARK_CHECK_SCISSOR) { + DRM_DEBUG("need to validate scissor %x %d\n", reg, flags); + } else { + DRM_DEBUG("illegal register %x %d\n", reg, flags); + return -EINVAL; + } + break; + } + count_dw++; + reg += 4; + } + return 0; +} + +int radeon_cs_parse(struct drm_device *dev, struct drm_file *file_priv, + void *ib, uint32_t *packets, uint32_t dwords) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + volatile int rb; + int size_dw = dwords; + /* scan the packet for various things */ + int count_dw = 0; + int ret = 0; + + while (count_dw < size_dw && ret == 0) { + int hdr = packets[count_dw]; + int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16; + int reg; + + switch (hdr & RADEON_CP_PACKET_MASK) { + case RADEON_CP_PACKET0: + ret = radeon_cs_packet0(dev, file_priv, packets, count_dw); + break; + case RADEON_CP_PACKET1: + case RADEON_CP_PACKET2: + reg = hdr & RADEON_CP_PACKET0_REG_MASK; + DRM_DEBUG("Packet 1/2: %d %x\n", num_dw, reg); + break; + + case RADEON_CP_PACKET3: + reg = hdr & 0xff00; + + switch(reg) { + case RADEON_CNTL_HOSTDATA_BLT: + radeon_cs_relocate_packet3(dev, file_priv, packets, count_dw); + break; + + case RADEON_CNTL_BITBLT_MULTI: + case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ + case RADEON_CP_INDX_BUFFER: + DRM_ERROR("need relocate packet 3 for %x\n", reg); + break; + + case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ + case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ + case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ + case RADEON_WAIT_FOR_IDLE: + case RADEON_CP_NOP: + break; + default: + DRM_ERROR("unknown packet 3 %x\n", reg); + ret = -EINVAL; + } + break; + } + + count_dw += num_dw+2; + } + + if (ret) + return ret; + + + /* copy the packet into the IB */ + memcpy(ib, packets, dwords * sizeof(uint32_t)); + + /* read back last byte to flush WC buffers */ + rb = readl((ib + (dwords-1) * sizeof(uint32_t))); + + return 0; +} + +uint32_t radeon_cs_id_get(struct drm_radeon_private *radeon) +{ + /* FIXME: protect with a spinlock */ + /* FIXME: check if wrap affect last reported wrap & sequence */ + radeon->cs.id_scnt = (radeon->cs.id_scnt + 1) & 0x00FFFFFF; + if (!radeon->cs.id_scnt) { + /* increment wrap counter */ + radeon->cs.id_wcnt += 0x01000000; + /* valid sequence counter start at 1 */ + radeon->cs.id_scnt = 1; + } + return (radeon->cs.id_scnt | radeon->cs.id_wcnt); +} + +void r100_cs_id_emit(struct drm_device *dev, uint32_t *id) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + /* ISYNC_CNTL should have CPSCRACTH bit set */ + *id = radeon_cs_id_get(dev_priv); + /* emit id in SCRATCH4 (not used yet in old drm) */ + BEGIN_RING(2); + OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG4, 0)); + OUT_RING(*id); + ADVANCE_RING(); +} + +void r300_cs_id_emit(struct drm_device *dev, uint32_t *id) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + /* ISYNC_CNTL should not have CPSCRACTH bit set */ + *id = radeon_cs_id_get(dev_priv); + /* emit id in SCRATCH6 */ + BEGIN_RING(6); + OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 0)); + OUT_RING(6); + OUT_RING(CP_PACKET0(R300_CP_RESYNC_DATA, 0)); + OUT_RING(*id); + OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + OUT_RING(R300_RB3D_DC_FINISH); + ADVANCE_RING(); +} + +uint32_t r100_cs_id_last_get(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + return RADEON_READ(RADEON_SCRATCH_REG4); +} + +uint32_t r300_cs_id_last_get(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + return RADEON_READ(RADEON_SCRATCH_REG6); +} + +int radeon_cs_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + if (dev_priv->chip_family < CHIP_RV280) { + dev_priv->cs.id_emit = r100_cs_id_emit; + dev_priv->cs.id_last_get = r100_cs_id_last_get; + } else if (dev_priv->chip_family < CHIP_R600) { + dev_priv->cs.id_emit = r300_cs_id_emit; + dev_priv->cs.id_last_get = r300_cs_id_last_get; + } + + dev_priv->cs.parse = radeon_cs_parse; + /* ib get depends on memory manager or not so memory manager */ + dev_priv->cs.relocate = radeon_nomm_relocate; + return 0; +} diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index 7fcf9305..8bb5d87c 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -455,6 +455,13 @@ typedef struct { int tiling_enabled; /* set by drm, read by 2d + 3d clients */ unsigned int last_fence; + + uint32_t front_handle; + uint32_t back_handle; + uint32_t depth_handle; + uint32_t front_pitch; + uint32_t back_pitch; + uint32_t depth_pitch; } drm_radeon_sarea_t; @@ -506,6 +513,7 @@ typedef struct { #define DRM_RADEON_GEM_SET_DOMAIN 0x23 #define DRM_RADEON_GEM_INDIRECT 0x24 // temporary for X server +#define DRM_RADEON_CS 0x25 #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) @@ -545,6 +553,7 @@ typedef struct { #define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain) #define DRM_IOCTL_RADEON_GEM_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INDIRECT, struct drm_radeon_gem_indirect) +#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) typedef struct drm_radeon_init { @@ -703,6 +712,7 @@ typedef struct drm_radeon_indirect { #define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */ #define RADEON_PARAM_FB_LOCATION 14 /* FB location */ #define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */ +#define RADEON_PARAM_KERNEL_MM 16 typedef struct drm_radeon_getparam { int param; @@ -758,6 +768,7 @@ typedef struct drm_radeon_setparam { #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ #define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */ +#define RADEON_SETPARAM_MM_INIT 7 /* Initialise the mm */ /* 1.14: Clients can allocate/free a surface */ typedef struct drm_radeon_surface_alloc { @@ -861,4 +872,17 @@ struct drm_radeon_gem_indirect { uint32_t used; }; +/* New interface which obsolete all previous interface. + */ + + +struct drm_radeon_cs { +// uint32_t __user *packets; + uint32_t dwords; + uint32_t cs_id; + uint64_t packets; + +}; + + #endif diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 5ce97b64..a40ff6dd 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -195,11 +195,11 @@ enum radeon_mac_model { #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ - (dev_priv->mm.ring_read_ptr ? readl(dev_priv->mm.ring_read_ptr_map.virtual + 0) : DRM_READ32((dev_priv)->ring_rptr, 0 )) : \ + (dev_priv->mm.ring_read.bo ? readl(dev_priv->mm.ring_read.kmap.virtual + 0) : DRM_READ32((dev_priv)->ring_rptr, 0 )) : \ RADEON_READ(RADEON_CP_RB_RPTR)) -#define SET_RING_HEAD(dev_priv,val) (dev_priv->mm.ring_read_ptr ? \ - writel((val), dev_priv->mm.ring_read_ptr_map.virtual) : \ +#define SET_RING_HEAD(dev_priv,val) (dev_priv->mm.ring_read.bo ? \ + writel((val), dev_priv->mm.ring_read.kmap.virtual) : \ DRM_WRITE32((dev_priv)->ring_rptr, 0, (val))) typedef struct drm_radeon_freelist { @@ -261,6 +261,11 @@ struct radeon_virt_surface { struct drm_file *file_priv; }; +struct radeon_mm_obj { + struct drm_buffer_object *bo; + struct drm_bo_kmap_obj kmap; +}; + struct radeon_mm_info { uint64_t vram_offset; // Offset into GPU space uint64_t vram_size; @@ -268,15 +273,13 @@ struct radeon_mm_info { uint64_t gart_start; uint64_t gart_size; + + struct radeon_mm_obj pcie_table; + struct radeon_mm_obj ring; + struct radeon_mm_obj ring_read; - struct drm_buffer_object *pcie_table; - struct drm_bo_kmap_obj pcie_table_map; - - struct drm_buffer_object *ring; - struct drm_bo_kmap_obj ring_map; - - struct drm_buffer_object *ring_read_ptr; - struct drm_bo_kmap_obj ring_read_ptr_map; + struct radeon_mm_obj dma_bufs; + struct drm_map fake_agp_map; }; #include "radeon_mode.h" @@ -289,11 +292,35 @@ struct drm_radeon_master_private { #define RADEON_FLUSH_EMITED (1 < 0) #define RADEON_PURGE_EMITED (1 < 1) +/* command submission struct */ +struct drm_radeon_cs_priv { + uint32_t id_wcnt; + uint32_t id_scnt; + uint32_t id_last_wcnt; + uint32_t id_last_scnt; + + int (*parse)(struct drm_device *dev, struct drm_file *file_priv, + void *ib, uint32_t *packets, uint32_t dwords); + void (*id_emit)(struct drm_device *dev, uint32_t *id); + uint32_t (*id_last_get)(struct drm_device *dev); + /* this ib handling callback are for hidding memory manager drm + * from memory manager less drm, free have to emit ib discard + * sequence into the ring */ + int (*ib_get)(struct drm_device *dev, void **ib, uint32_t dwords, uint32_t *card_offset); + uint32_t (*ib_get_ptr)(struct drm_device *dev, void *ib); + void (*ib_free)(struct drm_device *dev, void *ib, uint32_t dwords); + /* do a relocation either MM or non-MM */ + int (*relocate)(struct drm_device *dev, struct drm_file *file_priv, + uint32_t *reloc, uint32_t *offset); +}; + typedef struct drm_radeon_private { drm_radeon_ring_buffer_t ring; - int new_memmap; + bool new_memmap; + + bool user_mm_enable; int gart_size; u32 gart_vm_start; @@ -372,6 +399,7 @@ typedef struct drm_radeon_private { uint32_t flags; /* see radeon_chip_flags */ unsigned long fb_aper_offset; + bool mm_enabled; struct radeon_mm_info mm; drm_local_map_t *mmio; @@ -395,6 +423,11 @@ typedef struct drm_radeon_private { int num_gb_pipes; int track_flush; uint32_t chip_family; /* extract from flags */ + + struct radeon_mm_obj **ib_objs; + /* ib bitmap */ + uint64_t ib_alloc_bitmap; // TO DO replace with a real bitmap + struct drm_radeon_cs_priv cs; } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { @@ -672,14 +705,15 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define RADEON_SCRATCH_REG3 0x15ec #define RADEON_SCRATCH_REG4 0x15f0 #define RADEON_SCRATCH_REG5 0x15f4 +#define RADEON_SCRATCH_REG6 0x15f8 #define RADEON_SCRATCH_UMSK 0x0770 #define RADEON_SCRATCH_ADDR 0x0774 #define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) #define GET_SCRATCH( x ) (dev_priv->writeback_works ? \ - (dev_priv->mm.ring_read_ptr ? \ - readl(dev_priv->mm.ring_read_ptr_map.virtual + RADEON_SCRATCHOFF(0)) : \ + (dev_priv->mm.ring_read.bo ? \ + readl(dev_priv->mm.ring_read.kmap.virtual + RADEON_SCRATCHOFF(0)) : \ DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x))) : \ RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x))) @@ -1243,44 +1277,62 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev, #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) #define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) -extern int RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr); +extern u32 RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr); extern void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data); -#define RADEON_WRITE_PCIE( addr, val ) \ +#define RADEON_WRITE_P(reg, val, mask) \ +do { \ + uint32_t tmp = RADEON_READ(reg); \ + tmp &= (mask); \ + tmp |= ((val) & ~(mask)); \ + RADEON_WRITE(reg, tmp); \ +} while(0) + +#define RADEON_WRITE_PLL_P(dev_priv, addr, val, mask) \ +do { \ + uint32_t tmp_ = RADEON_READ_PLL(dev_priv, addr); \ + tmp_ &= (mask); \ + tmp_ |= ((val) & ~(mask)); \ + RADEON_WRITE_PLL(dev_priv, addr, tmp_); \ +} while (0) + + + +#define RADEON_WRITE_PCIE(addr, val) \ do { \ - RADEON_WRITE8( RADEON_PCIE_INDEX, \ + RADEON_WRITE8(RADEON_PCIE_INDEX, \ ((addr) & 0xff)); \ - RADEON_WRITE( RADEON_PCIE_DATA, (val) ); \ + RADEON_WRITE(RADEON_PCIE_DATA, (val)); \ } while (0) -#define R500_WRITE_MCIND( addr, val ) \ +#define R500_WRITE_MCIND(addr, val) \ do { \ RADEON_WRITE(R520_MC_IND_INDEX, 0xff0000 | ((addr) & 0xff)); \ RADEON_WRITE(R520_MC_IND_DATA, (val)); \ RADEON_WRITE(R520_MC_IND_INDEX, 0); \ } while (0) -#define RS480_WRITE_MCIND( addr, val ) \ +#define RS480_WRITE_MCIND(addr, val) \ do { \ - RADEON_WRITE( RS480_NB_MC_INDEX, \ + RADEON_WRITE(RS480_NB_MC_INDEX, \ ((addr) & 0xff) | RS480_NB_MC_IND_WR_EN); \ - RADEON_WRITE( RS480_NB_MC_DATA, (val) ); \ - RADEON_WRITE( RS480_NB_MC_INDEX, 0xff ); \ + RADEON_WRITE(RS480_NB_MC_DATA, (val)); \ + RADEON_WRITE(RS480_NB_MC_INDEX, 0xff); \ } while (0) -#define RS690_WRITE_MCIND( addr, val ) \ +#define RS690_WRITE_MCIND(addr, val) \ do { \ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \ RADEON_WRITE(RS690_MC_DATA, val); \ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \ } while (0) -#define IGP_WRITE_MCIND( addr, val ) \ +#define IGP_WRITE_MCIND(addr, val) \ do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) \ - RS690_WRITE_MCIND( addr, val ); \ - else \ - RS480_WRITE_MCIND( addr, val ); \ + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) \ + RS690_WRITE_MCIND(addr, val); \ + else \ + RS480_WRITE_MCIND(addr, val); \ } while (0) #define CP_PACKET0( reg, n ) \ @@ -1324,42 +1376,42 @@ do { \ #define RADEON_FLUSH_CACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_DC_FLUSH); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_DC_FLUSH); \ } else { \ - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_RB3D_DC_FLUSH); \ - } \ + OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_DC_FLUSH); \ + } \ } while (0) #define RADEON_PURGE_CACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \ } else { \ - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE ); \ - } \ + OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ + OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE ); \ + } \ } while (0) #define RADEON_FLUSH_ZCACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_ZC_FLUSH ); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_ZC_FLUSH); \ } else { \ - OUT_RING( CP_PACKET0( R300_ZB_ZCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( R300_ZC_FLUSH ); \ - } \ + OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(R300_ZC_FLUSH); \ + } \ } while (0) #define RADEON_PURGE_ZCACHE() do { \ if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \ + OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \ } else { \ - OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \ - } \ + OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \ + OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \ + } \ } while (0) /* ================================================================ @@ -1380,7 +1432,7 @@ do { \ #define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ do { \ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; \ - drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \ + drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \ if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ int __ret = radeon_do_cp_idle( dev_priv ); \ if ( __ret ) return __ret; \ @@ -1556,6 +1608,23 @@ static inline int radeon_update_breadcrumb(struct drm_device *dev) #define radeon_is_dce3(dev_priv) ((dev_priv->chip_family >= CHIP_RV620)) +#define radeon_is_rv100(dev_priv) ((dev_priv->chip_family == CHIP_RV100) || \ + (dev_priv->chip_family == CHIP_RV200) || \ + (dev_priv->chip_family == CHIP_RS100) || \ + (dev_priv->chip_family == CHIP_RS200) || \ + (dev_priv->chip_family == CHIP_RV250) || \ + (dev_priv->chip_family == CHIP_RV280) || \ + (dev_priv->chip_family == CHIP_RS300)) + +#define radeon_is_r300(dev_priv) ((dev_priv->chip_family == CHIP_R300) || \ + (dev_priv->chip_family == CHIP_RV350) || \ + (dev_priv->chip_family == CHIP_R350) || \ + (dev_priv->chip_family == CHIP_RV380) || \ + (dev_priv->chip_family == CHIP_R420) || \ + (dev_priv->chip_family == CHIP_RV410) || \ + (dev_priv->chip_family == CHIP_RS400) || \ + (dev_priv->chip_family == CHIP_RS480)) + #define radeon_bios8(dev_priv, v) (dev_priv->bios[v]) #define radeon_bios16(dev_priv, v) (dev_priv->bios[v] | (dev_priv->bios[(v) + 1] << 8)) #define radeon_bios32(dev_priv, v) ((dev_priv->bios[v]) | \ @@ -1563,6 +1632,7 @@ static inline int radeon_update_breadcrumb(struct drm_device *dev) (dev_priv->bios[(v) + 2] << 16) | \ (dev_priv->bios[(v) + 3] << 24)) +extern void radeon_pll_errata_after_index(struct drm_radeon_private *dev_priv); extern int radeon_emit_irq(struct drm_device * dev); extern void radeon_gem_free_object(struct drm_gem_object *obj); @@ -1592,4 +1662,14 @@ extern void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on); extern int radeon_master_create(struct drm_device *dev, struct drm_master *master); extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master); extern void radeon_cp_dispatch_flip(struct drm_device * dev, struct drm_master *master); +extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); +extern int radeon_cs_init(struct drm_device *dev); +void radeon_gem_update_offsets(struct drm_device *dev, struct drm_master *master); + +#define MARK_SAFE 1 +#define MARK_CHECK_OFFSET 2 +#define MARK_CHECK_SCISSOR 3 + +extern int r300_check_range(unsigned reg, int count); +extern int r300_get_reg_flags(unsigned reg); #endif /* __RADEON_DRV_H__ */ diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 6de4b135..7262b2aa 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -2223,6 +2223,9 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; + if (dev_priv->mm.vram_offset) + radeon_gem_update_offsets(dev, file_priv->master); + radeon_cp_dispatch_swap(dev, file_priv->master); sarea_priv->ctx_owner = 0; @@ -3117,6 +3120,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil case RADEON_PARAM_NUM_GB_PIPES: value = dev_priv->num_gb_pipes; break; + case RADEON_PARAM_KERNEL_MM: + value = dev_priv->mm_enabled; + break; default: DRM_DEBUG( "Invalid parameter %d\n", param->param ); return -EINVAL; @@ -3178,6 +3184,10 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil case RADEON_SETPARAM_VBLANK_CRTC: return radeon_vblank_crtc_set(dev, sp->value); break; + case RADEON_SETPARAM_MM_INIT: + dev_priv->user_mm_enable = true; + dev_priv->new_memmap = true; + return radeon_gem_mm_init(dev); default: DRM_DEBUG("Invalid parameter %d\n", sp->param); return -EINVAL; @@ -3279,6 +3289,7 @@ struct drm_ioctl_desc radeon_ioctls[] = { DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH), DRM_IOCTL_DEF(DRM_RADEON_GEM_INDIRECT, radeon_gem_indirect_ioctl, DRM_AUTH), + DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH), }; int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); |