0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include "kfd_mqd_manager.h"
0026 #include "amdgpu_amdkfd.h"
0027 #include "kfd_device_queue_manager.h"
0028
0029
0030 int pipe_priority_map[] = {
0031 KFD_PIPE_PRIORITY_CS_LOW,
0032 KFD_PIPE_PRIORITY_CS_LOW,
0033 KFD_PIPE_PRIORITY_CS_LOW,
0034 KFD_PIPE_PRIORITY_CS_LOW,
0035 KFD_PIPE_PRIORITY_CS_LOW,
0036 KFD_PIPE_PRIORITY_CS_LOW,
0037 KFD_PIPE_PRIORITY_CS_LOW,
0038 KFD_PIPE_PRIORITY_CS_MEDIUM,
0039 KFD_PIPE_PRIORITY_CS_MEDIUM,
0040 KFD_PIPE_PRIORITY_CS_MEDIUM,
0041 KFD_PIPE_PRIORITY_CS_MEDIUM,
0042 KFD_PIPE_PRIORITY_CS_HIGH,
0043 KFD_PIPE_PRIORITY_CS_HIGH,
0044 KFD_PIPE_PRIORITY_CS_HIGH,
0045 KFD_PIPE_PRIORITY_CS_HIGH,
0046 KFD_PIPE_PRIORITY_CS_HIGH
0047 };
0048
0049 struct kfd_mem_obj *allocate_hiq_mqd(struct kfd_dev *dev, struct queue_properties *q)
0050 {
0051 struct kfd_mem_obj *mqd_mem_obj = NULL;
0052
0053 mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL);
0054 if (!mqd_mem_obj)
0055 return NULL;
0056
0057 mqd_mem_obj->gtt_mem = dev->dqm->hiq_sdma_mqd.gtt_mem;
0058 mqd_mem_obj->gpu_addr = dev->dqm->hiq_sdma_mqd.gpu_addr;
0059 mqd_mem_obj->cpu_ptr = dev->dqm->hiq_sdma_mqd.cpu_ptr;
0060
0061 return mqd_mem_obj;
0062 }
0063
0064 struct kfd_mem_obj *allocate_sdma_mqd(struct kfd_dev *dev,
0065 struct queue_properties *q)
0066 {
0067 struct kfd_mem_obj *mqd_mem_obj = NULL;
0068 uint64_t offset;
0069
0070 mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL);
0071 if (!mqd_mem_obj)
0072 return NULL;
0073
0074 offset = (q->sdma_engine_id *
0075 dev->device_info.num_sdma_queues_per_engine +
0076 q->sdma_queue_id) *
0077 dev->dqm->mqd_mgrs[KFD_MQD_TYPE_SDMA]->mqd_size;
0078
0079 offset += dev->dqm->mqd_mgrs[KFD_MQD_TYPE_HIQ]->mqd_size;
0080
0081 mqd_mem_obj->gtt_mem = (void *)((uint64_t)dev->dqm->hiq_sdma_mqd.gtt_mem
0082 + offset);
0083 mqd_mem_obj->gpu_addr = dev->dqm->hiq_sdma_mqd.gpu_addr + offset;
0084 mqd_mem_obj->cpu_ptr = (uint32_t *)((uint64_t)
0085 dev->dqm->hiq_sdma_mqd.cpu_ptr + offset);
0086
0087 return mqd_mem_obj;
0088 }
0089
0090 void free_mqd_hiq_sdma(struct mqd_manager *mm, void *mqd,
0091 struct kfd_mem_obj *mqd_mem_obj)
0092 {
0093 WARN_ON(!mqd_mem_obj->gtt_mem);
0094 kfree(mqd_mem_obj);
0095 }
0096
0097 void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm,
0098 const uint32_t *cu_mask, uint32_t cu_mask_count,
0099 uint32_t *se_mask)
0100 {
0101 struct kfd_cu_info cu_info;
0102 uint32_t cu_per_sh[KFD_MAX_NUM_SE][KFD_MAX_NUM_SH_PER_SE] = {0};
0103 bool wgp_mode_req = KFD_GC_VERSION(mm->dev) >= IP_VERSION(10, 0, 0);
0104 uint32_t en_mask = wgp_mode_req ? 0x3 : 0x1;
0105 int i, se, sh, cu, cu_bitmap_sh_mul, inc = wgp_mode_req ? 2 : 1;
0106
0107 amdgpu_amdkfd_get_cu_info(mm->dev->adev, &cu_info);
0108
0109 if (cu_mask_count > cu_info.cu_active_number)
0110 cu_mask_count = cu_info.cu_active_number;
0111
0112
0113
0114
0115
0116 if (cu_info.num_shader_engines > KFD_MAX_NUM_SE) {
0117 pr_err("Exceeded KFD_MAX_NUM_SE, chip reports %d\n", cu_info.num_shader_engines);
0118 return;
0119 }
0120 if (cu_info.num_shader_arrays_per_engine > KFD_MAX_NUM_SH_PER_SE) {
0121 pr_err("Exceeded KFD_MAX_NUM_SH, chip reports %d\n",
0122 cu_info.num_shader_arrays_per_engine * cu_info.num_shader_engines);
0123 return;
0124 }
0125
0126 cu_bitmap_sh_mul = (KFD_GC_VERSION(mm->dev) >= IP_VERSION(11, 0, 0) &&
0127 KFD_GC_VERSION(mm->dev) < IP_VERSION(12, 0, 0)) ? 2 : 1;
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140 for (se = 0; se < cu_info.num_shader_engines; se++)
0141 for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++)
0142 cu_per_sh[se][sh] = hweight32(
0143 cu_info.cu_bitmap[se % 4][sh + (se / 4) * cu_bitmap_sh_mul]);
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 for (i = 0; i < cu_info.num_shader_engines; i++)
0169 se_mask[i] = 0;
0170
0171 i = 0;
0172 for (cu = 0; cu < 16; cu += inc) {
0173 for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++) {
0174 for (se = 0; se < cu_info.num_shader_engines; se++) {
0175 if (cu_per_sh[se][sh] > cu) {
0176 if (cu_mask[i / 32] & (en_mask << (i % 32)))
0177 se_mask[se] |= en_mask << (cu + sh * 16);
0178 i += inc;
0179 if (i == cu_mask_count)
0180 return;
0181 }
0182 }
0183 }
0184 }
0185 }
0186
0187 int kfd_hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd,
0188 uint32_t pipe_id, uint32_t queue_id,
0189 struct queue_properties *p, struct mm_struct *mms)
0190 {
0191 return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->adev, mqd, pipe_id,
0192 queue_id, p->doorbell_off);
0193 }
0194
0195 int kfd_destroy_mqd_cp(struct mqd_manager *mm, void *mqd,
0196 enum kfd_preempt_type type, unsigned int timeout,
0197 uint32_t pipe_id, uint32_t queue_id)
0198 {
0199 return mm->dev->kfd2kgd->hqd_destroy(mm->dev->adev, mqd, type, timeout,
0200 pipe_id, queue_id);
0201 }
0202
0203 void kfd_free_mqd_cp(struct mqd_manager *mm, void *mqd,
0204 struct kfd_mem_obj *mqd_mem_obj)
0205 {
0206 if (mqd_mem_obj->gtt_mem) {
0207 amdgpu_amdkfd_free_gtt_mem(mm->dev->adev, mqd_mem_obj->gtt_mem);
0208 kfree(mqd_mem_obj);
0209 } else {
0210 kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
0211 }
0212 }
0213
0214 bool kfd_is_occupied_cp(struct mqd_manager *mm, void *mqd,
0215 uint64_t queue_address, uint32_t pipe_id,
0216 uint32_t queue_id)
0217 {
0218 return mm->dev->kfd2kgd->hqd_is_occupied(mm->dev->adev, queue_address,
0219 pipe_id, queue_id);
0220 }
0221
0222 int kfd_load_mqd_sdma(struct mqd_manager *mm, void *mqd,
0223 uint32_t pipe_id, uint32_t queue_id,
0224 struct queue_properties *p, struct mm_struct *mms)
0225 {
0226 return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd,
0227 (uint32_t __user *)p->write_ptr,
0228 mms);
0229 }
0230
0231
0232
0233
0234
0235 int kfd_destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
0236 enum kfd_preempt_type type,
0237 unsigned int timeout, uint32_t pipe_id,
0238 uint32_t queue_id)
0239 {
0240 return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout);
0241 }
0242
0243 bool kfd_is_occupied_sdma(struct mqd_manager *mm, void *mqd,
0244 uint64_t queue_address, uint32_t pipe_id,
0245 uint32_t queue_id)
0246 {
0247 return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd);
0248 }