Merge branch 'drm-next-4.15' of git://people.freedesktop.org/~agd5f/linux into drm...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_vm.h
index 6716355..0af0906 100644 (file)
@@ -25,6 +25,7 @@
 #define __AMDGPU_VM_H__
 
 #include <linux/rbtree.h>
+#include <linux/idr.h>
 
 #include "gpu_scheduler.h"
 #include "amdgpu_sync.h"
@@ -105,17 +106,24 @@ struct amdgpu_vm_bo_base {
 
        /* protected by spinlock */
        struct list_head                vm_status;
+
+       /* protected by the BO being reserved */
+       bool                            moved;
 };
 
 struct amdgpu_vm_pt {
-       struct amdgpu_bo        *bo;
-       uint64_t                addr;
+       struct amdgpu_vm_bo_base        base;
+       uint64_t                        addr;
 
        /* array of page tables, one for each directory entry */
-       struct amdgpu_vm_pt     *entries;
-       unsigned                last_entry_used;
+       struct amdgpu_vm_pt             *entries;
+       unsigned                        last_entry_used;
 };
 
+#define AMDGPU_VM_FAULT(pasid, addr) (((u64)(pasid) << 48) | (addr))
+#define AMDGPU_VM_FAULT_PASID(fault) ((u64)(fault) >> 48)
+#define AMDGPU_VM_FAULT_ADDR(fault)  ((u64)(fault) & 0xfffffffff000ULL)
+
 struct amdgpu_vm {
        /* tree of virtual addresses mapped */
        struct rb_root_cached   va;
@@ -123,19 +131,21 @@ struct amdgpu_vm {
        /* protecting invalidated */
        spinlock_t              status_lock;
 
+       /* BOs who needs a validation */
+       struct list_head        evicted;
+
+       /* PT BOs which relocated and their parent need an update */
+       struct list_head        relocated;
+
        /* BOs moved, but not yet updated in the PT */
        struct list_head        moved;
 
-       /* BOs cleared in the PT because of a move */
-       struct list_head        cleared;
-
        /* BO mappings freed, but not yet updated in the PT */
        struct list_head        freed;
 
        /* contains the page directory */
        struct amdgpu_vm_pt     root;
-       struct dma_fence        *last_dir_update;
-       uint64_t                last_eviction_counter;
+       struct dma_fence        *last_update;
 
        /* protecting freed */
        spinlock_t              freed_lock;
@@ -143,8 +153,9 @@ struct amdgpu_vm {
        /* Scheduler entity for page table updates */
        struct amd_sched_entity entity;
 
-       /* client id */
+       /* client id and PASID (TODO: replace client_id with PASID) */
        u64                     client_id;
+       unsigned int            pasid;
        /* dedicated to vm */
        struct amdgpu_vm_id     *reserved_vmid[AMDGPU_MAX_VMHUBS];
 
@@ -153,6 +164,9 @@ struct amdgpu_vm {
 
        /* Flag to indicate ATS support from PTE for GFX9 */
        bool                    pte_support_ats;
+
+       /* Up to 128 pending page faults */
+       DECLARE_KFIFO(faults, u64, 128);
 };
 
 struct amdgpu_vm_id {
@@ -215,16 +229,25 @@ struct amdgpu_vm_manager {
         * BIT1[= 0] Compute updated by SDMA [= 1] by CPU
         */
        int                                     vm_update_mode;
+
+       /* PASID to VM mapping, will be used in interrupt context to
+        * look up VM of a page fault
+        */
+       struct idr                              pasid_idr;
+       spinlock_t                              pasid_lock;
 };
 
+int amdgpu_vm_alloc_pasid(unsigned int bits);
+void amdgpu_vm_free_pasid(unsigned int pasid);
 void amdgpu_vm_manager_init(struct amdgpu_device *adev);
 void amdgpu_vm_manager_fini(struct amdgpu_device *adev);
 int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
-                  int vm_context);
+                  int vm_context, unsigned int pasid);
 void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
 void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
                         struct list_head *validated,
                         struct amdgpu_bo_list_entry *entry);
+bool amdgpu_vm_ready(struct amdgpu_vm *vm);
 int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                              int (*callback)(void *p, struct amdgpu_bo *bo),
                              void *param);
@@ -243,13 +266,13 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev,
 int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
                          struct amdgpu_vm *vm,
                          struct dma_fence **fence);
-int amdgpu_vm_clear_moved(struct amdgpu_device *adev, struct amdgpu_vm *vm,
-                         struct amdgpu_sync *sync);
+int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
+                          struct amdgpu_vm *vm);
 int amdgpu_vm_bo_update(struct amdgpu_device *adev,
                        struct amdgpu_bo_va *bo_va,
                        bool clear);
 void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
-                            struct amdgpu_bo *bo);
+                            struct amdgpu_bo *bo, bool evicted);
 struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm,
                                       struct amdgpu_bo *bo);
 struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
@@ -269,6 +292,8 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
 int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
                                struct amdgpu_vm *vm,
                                uint64_t saddr, uint64_t size);
+struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
+                                                        uint64_t addr);
 void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
                      struct amdgpu_bo_va *bo_va);
 void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,