diff options
Diffstat (limited to 'linux-core/drm_objects.h')
-rw-r--r-- | linux-core/drm_objects.h | 334 |
1 files changed, 221 insertions, 113 deletions
diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index cea811eb..a2d10b5d 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -68,12 +68,12 @@ struct drm_user_object { atomic_t refcount; int shareable; struct drm_file *owner; - void (*ref_struct_locked) (struct drm_file * priv, - struct drm_user_object * obj, + void (*ref_struct_locked) (struct drm_file *priv, + struct drm_user_object *obj, enum drm_ref_type ref_action); - void (*unref) (struct drm_file * priv, struct drm_user_object * obj, + void (*unref) (struct drm_file *priv, struct drm_user_object *obj, enum drm_ref_type unref_action); - void (*remove) (struct drm_file * priv, struct drm_user_object * obj); + void (*remove) (struct drm_file *priv, struct drm_user_object *obj); }; /* @@ -94,29 +94,29 @@ struct drm_ref_object { * Must be called with the struct_mutex held. */ -extern int drm_add_user_object(struct drm_file * priv, struct drm_user_object * item, +extern int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item, int shareable); /** * Must be called with the struct_mutex held. */ -extern struct drm_user_object *drm_lookup_user_object(struct drm_file * priv, +extern struct drm_user_object *drm_lookup_user_object(struct drm_file *priv, uint32_t key); /* * Must be called with the struct_mutex held. May temporarily release it. */ -extern int drm_add_ref_object(struct drm_file * priv, - struct drm_user_object * referenced_object, +extern int drm_add_ref_object(struct drm_file *priv, + struct drm_user_object *referenced_object, enum drm_ref_type ref_action); /* * Must be called with the struct_mutex held. */ -struct drm_ref_object *drm_lookup_ref_object(struct drm_file * priv, - struct drm_user_object * referenced_object, +struct drm_ref_object *drm_lookup_ref_object(struct drm_file *priv, + struct drm_user_object *referenced_object, enum drm_ref_type ref_action); /* * Must be called with the struct_mutex held. @@ -125,11 +125,11 @@ struct drm_ref_object *drm_lookup_ref_object(struct drm_file * priv, * This function may temporarily release the struct_mutex. */ -extern void drm_remove_ref_object(struct drm_file * priv, struct drm_ref_object * item); -extern int drm_user_object_ref(struct drm_file * priv, uint32_t user_token, +extern void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item); +extern int drm_user_object_ref(struct drm_file *priv, uint32_t user_token, enum drm_object_type type, - struct drm_user_object ** object); -extern int drm_user_object_unref(struct drm_file * priv, uint32_t user_token, + struct drm_user_object **object); +extern int drm_user_object_unref(struct drm_file *priv, uint32_t user_token, enum drm_object_type type); /*************************************************** @@ -138,7 +138,7 @@ extern int drm_user_object_unref(struct drm_file * priv, uint32_t user_token, struct drm_fence_object { struct drm_user_object base; - struct drm_device *dev; + struct drm_device *dev; atomic_t usage; /* @@ -153,7 +153,7 @@ struct drm_fence_object { uint32_t sequence; uint32_t flush_mask; uint32_t submitted_flush; - uint32_t error; + uint32_t error; }; #define _DRM_FENCE_CLASSES 8 @@ -182,40 +182,44 @@ struct drm_fence_driver { uint32_t flush_diff; uint32_t sequence_mask; int lazy_capable; - int (*has_irq) (struct drm_device * dev, uint32_t fence_class, + int (*has_irq) (struct drm_device *dev, uint32_t fence_class, uint32_t flags); - int (*emit) (struct drm_device * dev, uint32_t fence_class, uint32_t flags, - uint32_t * breadcrumb, uint32_t * native_type); - void (*poke_flush) (struct drm_device * dev, uint32_t fence_class); + int (*emit) (struct drm_device *dev, uint32_t fence_class, + uint32_t flags, uint32_t *breadcrumb, + uint32_t *native_type); + void (*poke_flush) (struct drm_device *dev, uint32_t fence_class); }; extern void drm_fence_handler(struct drm_device *dev, uint32_t fence_class, - uint32_t sequence, uint32_t type, uint32_t error); + uint32_t sequence, uint32_t type, + uint32_t error); extern void drm_fence_manager_init(struct drm_device *dev); extern void drm_fence_manager_takedown(struct drm_device *dev); extern void drm_fence_flush_old(struct drm_device *dev, uint32_t fence_class, uint32_t sequence); -extern int drm_fence_object_flush(struct drm_fence_object * fence, uint32_t type); -extern int drm_fence_object_signaled(struct drm_fence_object * fence, +extern int drm_fence_object_flush(struct drm_fence_object *fence, + uint32_t type); +extern int drm_fence_object_signaled(struct drm_fence_object *fence, uint32_t type, int flush); -extern void drm_fence_usage_deref_locked(struct drm_fence_object ** fence); -extern void drm_fence_usage_deref_unlocked(struct drm_fence_object ** fence); +extern void drm_fence_usage_deref_locked(struct drm_fence_object **fence); +extern void drm_fence_usage_deref_unlocked(struct drm_fence_object **fence); extern struct drm_fence_object *drm_fence_reference_locked(struct drm_fence_object *src); extern void drm_fence_reference_unlocked(struct drm_fence_object **dst, struct drm_fence_object *src); -extern int drm_fence_object_wait(struct drm_fence_object * fence, +extern int drm_fence_object_wait(struct drm_fence_object *fence, int lazy, int ignore_signals, uint32_t mask); extern int drm_fence_object_create(struct drm_device *dev, uint32_t type, uint32_t fence_flags, uint32_t fence_class, - struct drm_fence_object ** c_fence); -extern int drm_fence_object_emit(struct drm_fence_object * fence, + struct drm_fence_object **c_fence); +extern int drm_fence_object_emit(struct drm_fence_object *fence, uint32_t fence_flags, uint32_t class, uint32_t type); extern void drm_fence_fill_arg(struct drm_fence_object *fence, struct drm_fence_arg *arg); -extern int drm_fence_add_user_object(struct drm_file * priv, - struct drm_fence_object * fence, int shareable); +extern int drm_fence_add_user_object(struct drm_file *priv, + struct drm_fence_object *fence, + int shareable); extern int drm_fence_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -242,7 +246,7 @@ extern int drm_fence_buffers_ioctl(struct drm_device *dev, void *data, /* * The ttm backend GTT interface. (In our case AGP). * Any similar type of device (PCIE?) - * needs only to implement these functions to be usable with the "TTM" interface. + * needs only to implement these functions to be usable with the TTM interface. * The AGP backend implementation lives in drm_agpsupport.c * basically maps these calls to available functions in agpgart. * Each drm device driver gets an @@ -257,24 +261,26 @@ extern int drm_fence_buffers_ioctl(struct drm_device *dev, void *data, struct drm_ttm_backend; struct drm_ttm_backend_func { - int (*needs_ub_cache_adjust) (struct drm_ttm_backend * backend); - int (*populate) (struct drm_ttm_backend * backend, - unsigned long num_pages, struct page ** pages); - void (*clear) (struct drm_ttm_backend * backend); - int (*bind) (struct drm_ttm_backend * backend, - struct drm_bo_mem_reg * bo_mem); - int (*unbind) (struct drm_ttm_backend * backend); - void (*destroy) (struct drm_ttm_backend * backend); + int (*needs_ub_cache_adjust) (struct drm_ttm_backend *backend); + int (*populate) (struct drm_ttm_backend *backend, + unsigned long num_pages, struct page **pages, + struct page *dummy_read_page); + void (*clear) (struct drm_ttm_backend *backend); + int (*bind) (struct drm_ttm_backend *backend, + struct drm_bo_mem_reg *bo_mem); + int (*unbind) (struct drm_ttm_backend *backend); + void (*destroy) (struct drm_ttm_backend *backend); }; -typedef struct drm_ttm_backend { - struct drm_device *dev; - uint32_t flags; - struct drm_ttm_backend_func *func; -} drm_ttm_backend_t; +struct drm_ttm_backend { + struct drm_device *dev; + uint32_t flags; + struct drm_ttm_backend_func *func; +}; struct drm_ttm { + struct page *dummy_read_page; struct page **pages; uint32_t page_flags; unsigned long num_pages; @@ -292,22 +298,28 @@ struct drm_ttm { }; -extern struct drm_ttm *drm_ttm_init(struct drm_device *dev, unsigned long size); -extern int drm_bind_ttm(struct drm_ttm * ttm, struct drm_bo_mem_reg *bo_mem); -extern void drm_ttm_unbind(struct drm_ttm * ttm); -extern void drm_ttm_evict(struct drm_ttm * ttm); -extern void drm_ttm_fixup_caching(struct drm_ttm * ttm); -extern struct page *drm_ttm_get_page(struct drm_ttm * ttm, int index); +extern struct drm_ttm *drm_ttm_create(struct drm_device *dev, unsigned long size, + uint32_t page_flags, + struct page *dummy_read_page); +extern int drm_ttm_bind(struct drm_ttm *ttm, struct drm_bo_mem_reg *bo_mem); +extern void drm_ttm_unbind(struct drm_ttm *ttm); +extern void drm_ttm_evict(struct drm_ttm *ttm); +extern void drm_ttm_fixup_caching(struct drm_ttm *ttm); +extern struct page *drm_ttm_get_page(struct drm_ttm *ttm, int index); extern void drm_ttm_cache_flush(void); -extern int drm_ttm_populate(struct drm_ttm * ttm); +extern int drm_ttm_populate(struct drm_ttm *ttm); +extern int drm_ttm_set_user(struct drm_ttm *ttm, + struct task_struct *tsk, + unsigned long start, + unsigned long num_pages); /* - * Destroy a ttm. The user normally calls drmRmMap or a similar IOCTL to do this, - * which calls this function iff there are no vmas referencing it anymore. Otherwise it is called - * when the last vma exits. + * Destroy a ttm. The user normally calls drmRmMap or a similar IOCTL to do + * this which calls this function iff there are no vmas referencing it anymore. + * Otherwise it is called when the last vma exits. */ -extern int drm_destroy_ttm(struct drm_ttm * ttm); +extern int drm_ttm_destroy(struct drm_ttm *ttm); #define DRM_FLAG_MASKED(_old, _new, _mask) {\ (_old) ^= (((_old) ^ (_new)) & (_mask)); \ @@ -320,11 +332,48 @@ extern int drm_destroy_ttm(struct drm_ttm * ttm); * Page flags. */ -#define DRM_TTM_PAGE_UNCACHED 0x01 -#define DRM_TTM_PAGE_USED 0x02 -#define DRM_TTM_PAGE_BOUND 0x04 -#define DRM_TTM_PAGE_PRESENT 0x08 -#define DRM_TTM_PAGE_VMALLOC 0x10 +/* + * This ttm should not be cached by the CPU + */ +#define DRM_TTM_PAGE_UNCACHED (1 << 0) +/* + * This flat is not used at this time; I don't know what the + * intent was + */ +#define DRM_TTM_PAGE_USED (1 << 1) +/* + * This flat is not used at this time; I don't know what the + * intent was + */ +#define DRM_TTM_PAGE_BOUND (1 << 2) +/* + * This flat is not used at this time; I don't know what the + * intent was + */ +#define DRM_TTM_PAGE_PRESENT (1 << 3) +/* + * The array of page pointers was allocated with vmalloc + * instead of drm_calloc. + */ +#define DRM_TTM_PAGE_VMALLOC (1 << 4) +/* + * This ttm is mapped from user space + */ +#define DRM_TTM_PAGE_USER (1 << 5) +/* + * This ttm will be written to by the GPU + */ +#define DRM_TTM_PAGE_WRITE (1 << 6) +/* + * This ttm was mapped to the GPU, and so the contents may have + * been modified + */ +#define DRM_TTM_PAGE_USER_DIRTY (1 << 7) +/* + * This flag is not used at this time; I don't know what the + * intent was. + */ +#define DRM_TTM_PAGE_USER_DMA (1 << 8) /*************************************************** * Buffer objects. (drm_bo.c, drm_bo_move.c) @@ -336,16 +385,50 @@ struct drm_bo_mem_reg { unsigned long num_pages; uint32_t page_alignment; uint32_t mem_type; + /* + * Current buffer status flags, indicating + * where the buffer is located and which + * access modes are in effect + */ uint64_t flags; - uint64_t mask; - uint32_t desired_tile_stride; - uint32_t hw_tile_stride; + /** + * These are the flags proposed for + * a validate operation. If the + * validate succeeds, they'll get moved + * into the flags field + */ + uint64_t proposed_flags; + + uint32_t desired_tile_stride; + uint32_t hw_tile_stride; }; enum drm_bo_type { - drm_bo_type_dc, + /* + * drm_bo_type_device are 'normal' drm allocations, + * pages are allocated from within the kernel automatically + * and the objects can be mmap'd from the drm device. Each + * drm_bo_type_device object has a unique name which can be + * used by other processes to share access to the underlying + * buffer. + */ + drm_bo_type_device, + /* + * drm_bo_type_user are buffers of pages that already exist + * in the process address space. They are more limited than + * drm_bo_type_device buffers in that they must always + * remain cached (as we assume the user pages are mapped cached), + * and they are not sharable to other processes through DRM + * (although, regular shared memory should still work fine). + */ drm_bo_type_user, - drm_bo_type_kernel, /* for initial kernel allocations */ + /* + * drm_bo_type_kernel are buffers that exist solely for use + * within the kernel. The pages cannot be mapped into the + * process. One obvious use would be for the ring + * buffer where user access would not (ideally) be required. + */ + drm_bo_type_kernel, }; struct drm_buffer_object { @@ -369,8 +452,8 @@ struct drm_buffer_object { uint32_t fence_type; uint32_t fence_class; - uint32_t new_fence_type; - uint32_t new_fence_class; + uint32_t new_fence_type; + uint32_t new_fence_class; struct drm_fence_object *fence; uint32_t priv_flags; wait_queue_head_t event_queue; @@ -409,7 +492,7 @@ struct drm_mem_type_manager { struct list_head pinned; uint32_t flags; uint32_t drm_bus_maptype; - unsigned long gpu_offset; + unsigned long gpu_offset; unsigned long io_offset; unsigned long io_size; void *io_addr; @@ -431,8 +514,8 @@ struct drm_bo_lock { #define _DRM_FLAG_MEMTYPE_CSELECT 0x00000020 /* Select caching */ struct drm_buffer_manager { - struct drm_bo_lock bm_lock; - struct mutex evict_mutex; + struct drm_bo_lock bm_lock; + struct mutex evict_mutex; int nice_mode; int initialized; struct drm_file *last_to_validate; @@ -447,6 +530,7 @@ struct drm_buffer_manager { uint32_t fence_type; unsigned long cur_pages; atomic_t count; + struct page *dummy_read_page; }; struct drm_bo_driver { @@ -455,15 +539,42 @@ struct drm_bo_driver { uint32_t num_mem_type_prio; uint32_t num_mem_busy_prio; struct drm_ttm_backend *(*create_ttm_backend_entry) - (struct drm_device * dev); + (struct drm_device *dev); int (*fence_type) (struct drm_buffer_object *bo, uint32_t *fclass, - uint32_t * type); - int (*invalidate_caches) (struct drm_device * dev, uint64_t flags); - int (*init_mem_type) (struct drm_device * dev, uint32_t type, - struct drm_mem_type_manager * man); - uint32_t(*evict_mask) (struct drm_buffer_object *bo); - int (*move) (struct drm_buffer_object * bo, - int evict, int no_wait, struct drm_bo_mem_reg * new_mem); + uint32_t *type); + int (*invalidate_caches) (struct drm_device *dev, uint64_t flags); + int (*init_mem_type) (struct drm_device *dev, uint32_t type, + struct drm_mem_type_manager *man); + /* + * evict_flags: + * + * @bo: the buffer object to be evicted + * + * Return the bo flags for a buffer which is not mapped to the hardware. + * These will be placed in proposed_flags so that when the move is + * finished, they'll end up in bo->mem.flags + */ + uint64_t(*evict_flags) (struct drm_buffer_object *bo); + /* + * move: + * + * @bo: the buffer to move + * + * @evict: whether this motion is evicting the buffer from + * the graphics address space + * + * @no_wait: whether this should give up and return -EBUSY + * if this move would require sleeping + * + * @new_mem: the new memory region receiving the buffer + * + * Move a buffer between two memory regions. + */ + int (*move) (struct drm_buffer_object *bo, + int evict, int no_wait, struct drm_bo_mem_reg *new_mem); + /* + * ttm_cache_flush + */ void (*ttm_cache_flush)(struct drm_ttm *ttm); }; @@ -488,49 +599,47 @@ extern int drm_bo_version_ioctl(struct drm_device *dev, void *data, struct drm_f extern int drm_bo_driver_finish(struct drm_device *dev); extern int drm_bo_driver_init(struct drm_device *dev); extern int drm_bo_pci_offset(struct drm_device *dev, - struct drm_bo_mem_reg * mem, + struct drm_bo_mem_reg *mem, unsigned long *bus_base, unsigned long *bus_offset, unsigned long *bus_size); -extern int drm_mem_reg_is_pci(struct drm_device *dev, struct drm_bo_mem_reg * mem); +extern int drm_mem_reg_is_pci(struct drm_device *dev, struct drm_bo_mem_reg *mem); -extern void drm_bo_usage_deref_locked(struct drm_buffer_object ** bo); -extern void drm_bo_usage_deref_unlocked(struct drm_buffer_object ** bo); +extern void drm_bo_usage_deref_locked(struct drm_buffer_object **bo); +extern void drm_bo_usage_deref_unlocked(struct drm_buffer_object **bo); extern void drm_putback_buffer_objects(struct drm_device *dev); -extern int drm_fence_buffer_objects(struct drm_device * dev, +extern int drm_fence_buffer_objects(struct drm_device *dev, struct list_head *list, uint32_t fence_flags, - struct drm_fence_object * fence, - struct drm_fence_object ** used_fence); -extern void drm_bo_add_to_lru(struct drm_buffer_object * bo); + struct drm_fence_object *fence, + struct drm_fence_object **used_fence); +extern void drm_bo_add_to_lru(struct drm_buffer_object *bo); extern int drm_buffer_object_create(struct drm_device *dev, unsigned long size, - enum drm_bo_type type, uint64_t mask, + enum drm_bo_type type, uint64_t flags, uint32_t hint, uint32_t page_alignment, unsigned long buffer_start, struct drm_buffer_object **bo); -extern int drm_bo_wait(struct drm_buffer_object * bo, int lazy, int ignore_signals, +extern int drm_bo_wait(struct drm_buffer_object *bo, int lazy, int ignore_signals, int no_wait); -extern int drm_bo_mem_space(struct drm_buffer_object * bo, - struct drm_bo_mem_reg * mem, int no_wait); -extern int drm_bo_move_buffer(struct drm_buffer_object * bo, +extern int drm_bo_mem_space(struct drm_buffer_object *bo, + struct drm_bo_mem_reg *mem, int no_wait); +extern int drm_bo_move_buffer(struct drm_buffer_object *bo, uint64_t new_mem_flags, int no_wait, int move_unfenced); -extern int drm_bo_clean_mm(struct drm_device * dev, unsigned mem_type); -extern int drm_bo_init_mm(struct drm_device * dev, unsigned type, +extern int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type); +extern int drm_bo_init_mm(struct drm_device *dev, unsigned type, unsigned long p_offset, unsigned long p_size); -extern int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle, - uint32_t fence_class, uint64_t flags, - uint64_t mask, uint32_t hint, - int use_old_fence_class, - struct drm_bo_info_rep * rep, +extern int drm_bo_handle_validate(struct drm_file *file_priv, uint32_t handle, + uint64_t flags, uint64_t mask, uint32_t hint, + uint32_t fence_class, int use_old_fence_class, + struct drm_bo_info_rep *rep, struct drm_buffer_object **bo_rep); -extern struct drm_buffer_object *drm_lookup_buffer_object(struct drm_file * file_priv, +extern struct drm_buffer_object *drm_lookup_buffer_object(struct drm_file *file_priv, uint32_t handle, int check_owner); extern int drm_bo_do_validate(struct drm_buffer_object *bo, uint64_t flags, uint64_t mask, uint32_t hint, uint32_t fence_class, - int no_wait, struct drm_bo_info_rep *rep); /* @@ -538,18 +647,17 @@ extern int drm_bo_do_validate(struct drm_buffer_object *bo, * drm_bo_move.c */ -extern int drm_bo_move_ttm(struct drm_buffer_object * bo, - int evict, int no_wait, struct drm_bo_mem_reg * new_mem); -extern int drm_bo_move_memcpy(struct drm_buffer_object * bo, +extern int drm_bo_move_ttm(struct drm_buffer_object *bo, + int evict, int no_wait, + struct drm_bo_mem_reg *new_mem); +extern int drm_bo_move_memcpy(struct drm_buffer_object *bo, int evict, - int no_wait, struct drm_bo_mem_reg * new_mem); -extern int drm_bo_move_accel_cleanup(struct drm_buffer_object * bo, - int evict, - int no_wait, - uint32_t fence_class, - uint32_t fence_type, + int no_wait, struct drm_bo_mem_reg *new_mem); +extern int drm_bo_move_accel_cleanup(struct drm_buffer_object *bo, + int evict, int no_wait, + uint32_t fence_class, uint32_t fence_type, uint32_t fence_flags, - struct drm_bo_mem_reg * new_mem); + struct drm_bo_mem_reg *new_mem); extern int drm_bo_same_page(unsigned long offset, unsigned long offset2); extern unsigned long drm_bo_offset_end(unsigned long offset, unsigned long end); @@ -615,7 +723,7 @@ extern void drm_regs_init(struct drm_reg_manager *manager, void (*reg_destroy)(struct drm_reg *)); /* - * drm_bo_lock.c + * drm_bo_lock.c * Simple replacement for the hardware lock on buffer manager init and clean. */ @@ -623,10 +731,10 @@ extern void drm_regs_init(struct drm_reg_manager *manager, extern void drm_bo_init_lock(struct drm_bo_lock *lock); extern void drm_bo_read_unlock(struct drm_bo_lock *lock); extern int drm_bo_read_lock(struct drm_bo_lock *lock); -extern int drm_bo_write_lock(struct drm_bo_lock *lock, +extern int drm_bo_write_lock(struct drm_bo_lock *lock, struct drm_file *file_priv); -extern int drm_bo_write_unlock(struct drm_bo_lock *lock, +extern int drm_bo_write_unlock(struct drm_bo_lock *lock, struct drm_file *file_priv); #ifdef CONFIG_DEBUG_MUTEXES |