Home | History | Annotate | Line # | Download | only in amdgpu
      1 /*
      2  * Copyright  2014 Advanced Micro Devices, Inc.
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be included in
     13  * all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     21  * OTHER DEALINGS IN THE SOFTWARE.
     22  *
     23  */
     24 
     25 #ifndef _AMDGPU_INTERNAL_H_
     26 #define _AMDGPU_INTERNAL_H_
     27 
     28 #include <assert.h>
     29 #include <pthread.h>
     30 
     31 #include "libdrm_macros.h"
     32 #include "xf86atomic.h"
     33 #include "amdgpu.h"
     34 #include "util_double_list.h"
     35 #include "handle_table.h"
     36 
     37 #define AMDGPU_CS_MAX_RINGS 8
     38 /* do not use below macro if b is not power of 2 aligned value */
     39 #define __round_mask(x, y) ((__typeof__(x))((y)-1))
     40 #define ROUND_UP(x, y) ((((x)-1) | __round_mask(x, y))+1)
     41 #define ROUND_DOWN(x, y) ((x) & ~__round_mask(x, y))
     42 
     43 #define AMDGPU_INVALID_VA_ADDRESS	0xffffffffffffffff
     44 #define AMDGPU_NULL_SUBMIT_SEQ		0
     45 
     46 struct amdgpu_bo_va_hole {
     47 	struct list_head list;
     48 	uint64_t offset;
     49 	uint64_t size;
     50 };
     51 
     52 struct amdgpu_bo_va_mgr {
     53 	uint64_t va_max;
     54 	struct list_head va_holes;
     55 	pthread_mutex_t bo_va_mutex;
     56 	uint32_t va_alignment;
     57 };
     58 
     59 struct amdgpu_va {
     60 	uint64_t address;
     61 	uint64_t size;
     62 	enum amdgpu_gpu_va_range range;
     63 	struct amdgpu_bo_va_mgr *vamgr;
     64 };
     65 
     66 struct amdgpu_va_manager {
     67 	/** The VA manager for the lower virtual address space */
     68 	struct amdgpu_bo_va_mgr vamgr_low;
     69 	/** The VA manager for the 32bit address space */
     70 	struct amdgpu_bo_va_mgr vamgr_32;
     71 	/** The VA manager for the high virtual address space */
     72 	struct amdgpu_bo_va_mgr vamgr_high;
     73 	/** The VA manager for the 32bit high address space */
     74 	struct amdgpu_bo_va_mgr vamgr_high_32;
     75 
     76 	/** The bit to control whether it's the "LOW" or "HIGH" halves, when
     77 	 *  half of the address space is reserved for PRT to implement a SW
     78 	 *  workaround. */
     79 	unsigned address_prt_wa_control_bit;
     80 };
     81 
     82 struct amdgpu_device {
     83 	atomic_t refcount;
     84 	struct amdgpu_device *next;
     85 	int fd;
     86 	int flink_fd;
     87 	unsigned major_version;
     88 	unsigned minor_version;
     89 
     90 	char *marketing_name;
     91 	/** List of buffer handles. Protected by bo_table_mutex. */
     92 	struct handle_table bo_handles;
     93 	/** List of buffer GEM flink names. Protected by bo_table_mutex. */
     94 	struct handle_table bo_flink_names;
     95 	/** This protects all hash tables. */
     96 	pthread_mutex_t bo_table_mutex;
     97 	struct drm_amdgpu_info_device dev_info;
     98 	struct amdgpu_gpu_info info;
     99 
    100 	struct amdgpu_va_manager va_mgr;
    101 };
    102 
    103 struct amdgpu_bo {
    104 	atomic_t refcount;
    105 	struct amdgpu_device *dev;
    106 
    107 	uint64_t alloc_size;
    108 
    109 	uint32_t handle;
    110 	uint32_t flink_name;
    111 
    112 	pthread_mutex_t cpu_access_mutex;
    113 	void *cpu_ptr;
    114 	int64_t cpu_map_count;
    115 };
    116 
    117 struct amdgpu_bo_list {
    118 	struct amdgpu_device *dev;
    119 
    120 	uint32_t handle;
    121 };
    122 
    123 struct amdgpu_context {
    124 	struct amdgpu_device *dev;
    125 	/** Mutex for accessing fences and to maintain command submissions
    126 	    in good sequence. */
    127 	pthread_mutex_t sequence_mutex;
    128 	/* context id*/
    129 	uint32_t id;
    130 	uint64_t last_seq[AMDGPU_HW_IP_NUM][AMDGPU_HW_IP_INSTANCE_MAX_COUNT][AMDGPU_CS_MAX_RINGS];
    131 	struct list_head sem_list[AMDGPU_HW_IP_NUM][AMDGPU_HW_IP_INSTANCE_MAX_COUNT][AMDGPU_CS_MAX_RINGS];
    132 };
    133 
    134 /**
    135  * Structure describing sw semaphore based on scheduler
    136  *
    137  */
    138 struct amdgpu_semaphore {
    139 	atomic_t refcount;
    140 	struct list_head list;
    141 	struct amdgpu_cs_fence signal_fence;
    142 };
    143 
    144 /**
    145  * Functions.
    146  */
    147 
    148 drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
    149 		       uint64_t max, uint64_t alignment);
    150 
    151 drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr);
    152 
    153 drm_private void amdgpu_parse_asic_ids(struct amdgpu_device *dev);
    154 
    155 drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev);
    156 
    157 drm_private uint64_t amdgpu_cs_calculate_timeout(uint64_t timeout);
    158 
    159 /**
    160  * Inline functions.
    161  */
    162 
    163 /**
    164  * Increment src and decrement dst as if we were updating references
    165  * for an assignment between 2 pointers of some objects.
    166  *
    167  * \return  true if dst is 0
    168  */
    169 static inline bool update_references(atomic_t *dst, atomic_t *src)
    170 {
    171 	if (dst != src) {
    172 		/* bump src first */
    173 		if (src) {
    174 			assert(atomic_read(src) > 0);
    175 			atomic_inc(src);
    176 		}
    177 		if (dst) {
    178 			assert(atomic_read(dst) > 0);
    179 			return atomic_dec_and_test(dst);
    180 		}
    181 	}
    182 	return false;
    183 }
    184 
    185 #endif
    186