OSDN Git Service

Merge commit 'origin/drm-gem' into modesetting-gem
[android-x86/external-libdrm.git] / linux-core / drm_objects.h
index 375420d..d8e8ee3 100644 (file)
@@ -147,25 +147,23 @@ struct drm_fence_object {
 
        struct list_head ring;
        int fence_class;
-       uint32_t native_type;
+       uint32_t native_types;
        uint32_t type;
-       uint32_t signaled;
+       uint32_t signaled_types;
        uint32_t sequence;
-       uint32_t flush_mask;
-       uint32_t submitted_flush;
+       uint32_t waiting_types;
        uint32_t error;
 };
 
 #define _DRM_FENCE_CLASSES 8
-#define _DRM_FENCE_TYPE_EXE 0x00
 
 struct drm_fence_class_manager {
        struct list_head ring;
        uint32_t pending_flush;
+       uint32_t waiting_types;
        wait_queue_head_t fence_queue;
-       int pending_exe_flush;
-       uint32_t last_exe_flush;
-       uint32_t exe_flush_sequence;
+       uint32_t highest_waiting_sequence;
+        uint32_t latest_queued_sequence;
 };
 
 struct drm_fence_manager {
@@ -177,19 +175,49 @@ struct drm_fence_manager {
 };
 
 struct drm_fence_driver {
+       unsigned long *waiting_jiffies;
        uint32_t num_classes;
        uint32_t wrap_diff;
        uint32_t flush_diff;
        uint32_t sequence_mask;
-       int lazy_capable;
+
+       /*
+        * Driver implemented functions:
+        * has_irq() : 1 if the hardware can update the indicated type_flags using an
+        * irq handler. 0 if polling is required.
+        *
+        * emit() : Emit a sequence number to the command stream.
+        * Return the sequence number.
+        *
+        * flush() : Make sure the flags indicated in fc->pending_flush will eventually
+        * signal for fc->highest_received_sequence and all preceding sequences.
+        * Acknowledge by clearing the flags fc->pending_flush.
+        *
+        * poll() : Call drm_fence_handler with any new information.
+        *
+        * needed_flush() : Given the current state of the fence->type flags and previusly 
+        * executed or queued flushes, return the type_flags that need flushing.
+        *
+        * wait(): Wait for the "mask" flags to signal on a given fence, performing
+        * whatever's necessary to make this happen.
+        */
+
        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);
+       void (*flush) (struct drm_device *dev, uint32_t fence_class);
+       void (*poll) (struct drm_device *dev, uint32_t fence_class,
+               uint32_t types);
+       uint32_t (*needed_flush) (struct drm_fence_object *fence);
+       int (*wait) (struct drm_fence_object *fence, int lazy,
+                    int interruptible, uint32_t mask);
 };
 
+extern int drm_fence_wait_polling(struct drm_fence_object *fence, int lazy,
+                                 int interruptible, uint32_t mask,
+                                 unsigned long end_jiffies);
 extern void drm_fence_handler(struct drm_device *dev, uint32_t fence_class,
                              uint32_t sequence, uint32_t type,
                              uint32_t error);
@@ -200,7 +228,7 @@ extern void drm_fence_flush_old(struct drm_device *dev, uint32_t fence_class,
 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);
+                                    uint32_t type);
 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);
@@ -263,7 +291,8 @@ 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);
+                        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);
@@ -271,7 +300,12 @@ struct drm_ttm_backend_func {
        void (*destroy) (struct drm_ttm_backend *backend);
 };
 
-
+/**
+ * This structure associates a set of flags and methods with a drm_ttm
+ * object, and will also be subclassed by the particular backend.
+ *
+ * \sa #drm_agp_ttm_backend
+ */
 struct drm_ttm_backend {
        struct drm_device *dev;
        uint32_t flags;
@@ -281,6 +315,8 @@ struct drm_ttm_backend {
 struct drm_ttm {
        struct page *dummy_read_page;
        struct page **pages;
+       long first_himem_page;
+       long last_lomem_page;
        uint32_t page_flags;
        unsigned long num_pages;
        atomic_t vma_count;
@@ -288,6 +324,8 @@ struct drm_ttm {
        int destroy;
        uint32_t mapping_offset;
        struct drm_ttm_backend *be;
+       unsigned long highest_lomem_entry;
+       unsigned long lowest_himem_entry;
        enum {
                ttm_bound,
                ttm_evicted,
@@ -305,7 +343,7 @@ 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 void drm_ttm_cache_flush(struct page *pages[], unsigned long num_pages);
 extern int drm_ttm_populate(struct drm_ttm *ttm);
 extern int drm_ttm_set_user(struct drm_ttm *ttm,
                            struct task_struct *tsk,
@@ -354,7 +392,7 @@ extern int drm_ttm_destroy(struct drm_ttm *ttm);
  * The array of page pointers was allocated with vmalloc
  * instead of drm_calloc.
  */
-#define DRM_TTM_PAGE_VMALLOC    (1 << 4)
+#define DRM_TTM_PAGEDIR_VMALLOC (1 << 4)
 /*
  * This ttm is mapped from user space
  */
@@ -384,16 +422,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;
+       /**
+        * 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 {
@@ -449,9 +521,18 @@ struct drm_buffer_object {
 #define _DRM_BO_FLAG_UNFENCED 0x00000001
 #define _DRM_BO_FLAG_EVICTED  0x00000002
 
+/*
+ * This flag indicates that a flag called with bo->mutex held has
+ * temporarily released the buffer object mutex, (usually to wait for something).
+ * and thus any post-lock validation needs to be rerun.
+ */
+
+#define _DRM_BO_FLAG_UNLOCKED 0x00000004
+
 struct drm_mem_type_manager {
        int has_type;
        int use_type;
+       int kern_init_type;
        struct drm_mm manager;
        struct list_head lru;
        struct list_head pinned;
@@ -461,6 +542,7 @@ struct drm_mem_type_manager {
        unsigned long io_offset;
        unsigned long io_size;
        void *io_addr;
+       uint64_t size; /* size of managed area for reporting to userspace */
 };
 
 struct drm_bo_lock {
@@ -510,21 +592,75 @@ struct drm_bo_driver {
        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);
+       /*
+        * 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);
+
+       /*
+        * command_stream_barrier
+        *
+        * @dev: The drm device.
+        *
+        * @bo: The buffer object to validate.
+        *
+        * @new_fence_class: The new fence class for the buffer object.
+        *
+        * @new_fence_type: The new fence type for the buffer object.
+        *
+        * @no_wait: whether this should give up and return -EBUSY
+        * if this operation would require sleeping
+        *
+        * Insert a command stream barrier that makes sure that the
+        * buffer is idle once the commands associated with the
+        * current validation are starting to execute. If an error
+        * condition is returned, or the function pointer is NULL,
+        * the drm core will force buffer idle
+        * during validation.
+        */
+
+       int (*command_stream_barrier) (struct drm_buffer_object *bo,
+                                      uint32_t new_fence_class,
+                                      uint32_t new_fence_type,
+                                      int no_wait);                                   
 };
 
 /*
  * buffer objects (drm_bo.c)
  */
-
 extern int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int drm_bo_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int drm_bo_unmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo, int pin);
 extern int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int drm_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
@@ -533,6 +669,7 @@ extern int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file
 extern int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int drm_mm_unlock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int drm_mm_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int drm_bo_version_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int drm_bo_driver_finish(struct drm_device *dev);
 extern int drm_bo_driver_init(struct drm_device *dev);
@@ -543,6 +680,8 @@ extern int drm_bo_pci_offset(struct drm_device *dev,
                             unsigned long *bus_size);
 extern int drm_mem_reg_is_pci(struct drm_device *dev, struct drm_bo_mem_reg *mem);
 
+extern int drm_bo_add_user_object(struct drm_file *file_priv,
+                                 struct drm_buffer_object *bo, int shareable);
 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);
@@ -553,23 +692,24 @@ extern int drm_fence_buffer_objects(struct drm_device *dev,
                                    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,
-                      int no_wait);
+extern int drm_bo_wait(struct drm_buffer_object *bo, int lazy, int interruptible,
+                      int no_wait, int check_unfenced);
 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_clean_mm(struct drm_device *dev, unsigned mem_type, int kern_clean);
 extern int drm_bo_init_mm(struct drm_device *dev, unsigned type,
-                         unsigned long p_offset, unsigned long p_size);
+                         unsigned long p_offset, unsigned long p_size,
+                         int kern_init);
 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,
+                                 uint32_t 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,
@@ -579,7 +719,9 @@ extern int drm_bo_do_validate(struct drm_buffer_object *bo,
                              uint64_t flags, uint64_t mask, uint32_t hint,
                              uint32_t fence_class,
                              struct drm_bo_info_rep *rep);
+extern int drm_bo_evict_cached(struct drm_buffer_object *bo);
 
+extern void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo);
 /*
  * Buffer object memory move- and map helpers.
  * drm_bo_move.c
@@ -620,6 +762,12 @@ static inline void *drm_bmo_virtual(struct drm_bo_kmap_obj *map, int *is_iomem)
 extern void drm_bo_kunmap(struct drm_bo_kmap_obj *map);
 extern int drm_bo_kmap(struct drm_buffer_object *bo, unsigned long start_page,
                       unsigned long num_pages, struct drm_bo_kmap_obj *map);
+extern int drm_bo_pfn_prot(struct drm_buffer_object *bo,
+                          unsigned long dst_offset,
+                          unsigned long *pfn,
+                          pgprot_t *prot);
+extern void drm_bo_fill_rep_arg(struct drm_buffer_object *bo,
+                               struct drm_bo_info_rep *rep);
 
 
 /*
@@ -660,6 +808,10 @@ extern void drm_regs_init(struct drm_reg_manager *manager,
                                              const void *),
                          void (*reg_destroy)(struct drm_reg *));
 
+extern int drm_mem_reg_ioremap(struct drm_device *dev, struct drm_bo_mem_reg * mem,
+                              void **virtual);
+extern void drm_mem_reg_iounmap(struct drm_device *dev, struct drm_bo_mem_reg * mem,
+                               void *virtual);
 /*
  * drm_bo_lock.c
  * Simple replacement for the hardware lock on buffer manager init and clean.
@@ -668,8 +820,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_read_lock(struct drm_bo_lock *lock,
+                           int interruptible);
 extern int drm_bo_write_lock(struct drm_bo_lock *lock,
+                            int interruptible,
                             struct drm_file *file_priv);
 
 extern int drm_bo_write_unlock(struct drm_bo_lock *lock,