1 1.1 riastrad /* $NetBSD: amdgpu_vcn.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright 2016 Advanced Micro Devices, Inc. 5 1.1 riastrad * All Rights Reserved. 6 1.1 riastrad * 7 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 8 1.1 riastrad * copy of this software and associated documentation files (the 9 1.1 riastrad * "Software"), to deal in the Software without restriction, including 10 1.1 riastrad * without limitation the rights to use, copy, modify, merge, publish, 11 1.1 riastrad * distribute, sub license, and/or sell copies of the Software, and to 12 1.1 riastrad * permit persons to whom the Software is furnished to do so, subject to 13 1.1 riastrad * the following conditions: 14 1.1 riastrad * 15 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 1.1 riastrad * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 1.1 riastrad * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 1.1 riastrad * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 1.1 riastrad * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 1.1 riastrad * 23 1.1 riastrad * The above copyright notice and this permission notice (including the 24 1.1 riastrad * next paragraph) shall be included in all copies or substantial portions 25 1.1 riastrad * of the Software. 26 1.1 riastrad * 27 1.1 riastrad */ 28 1.1 riastrad 29 1.1 riastrad #include <sys/cdefs.h> 30 1.1 riastrad __KERNEL_RCSID(0, "$NetBSD: amdgpu_vcn.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $"); 31 1.1 riastrad 32 1.1 riastrad #include <linux/firmware.h> 33 1.1 riastrad #include <linux/module.h> 34 1.1 riastrad #include <linux/pci.h> 35 1.1 riastrad 36 1.1 riastrad #include "amdgpu.h" 37 1.1 riastrad #include "amdgpu_pm.h" 38 1.1 riastrad #include "amdgpu_vcn.h" 39 1.1 riastrad #include "soc15d.h" 40 1.1 riastrad 41 1.1 riastrad /* Firmware Names */ 42 1.1 riastrad #define FIRMWARE_RAVEN "amdgpu/raven_vcn.bin" 43 1.1 riastrad #define FIRMWARE_PICASSO "amdgpu/picasso_vcn.bin" 44 1.1 riastrad #define FIRMWARE_RAVEN2 "amdgpu/raven2_vcn.bin" 45 1.1 riastrad #define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin" 46 1.1 riastrad #define FIRMWARE_RENOIR "amdgpu/renoir_vcn.bin" 47 1.1 riastrad #define FIRMWARE_NAVI10 "amdgpu/navi10_vcn.bin" 48 1.1 riastrad #define FIRMWARE_NAVI14 "amdgpu/navi14_vcn.bin" 49 1.1 riastrad #define FIRMWARE_NAVI12 "amdgpu/navi12_vcn.bin" 50 1.1 riastrad 51 1.1 riastrad MODULE_FIRMWARE(FIRMWARE_RAVEN); 52 1.1 riastrad MODULE_FIRMWARE(FIRMWARE_PICASSO); 53 1.1 riastrad MODULE_FIRMWARE(FIRMWARE_RAVEN2); 54 1.1 riastrad MODULE_FIRMWARE(FIRMWARE_ARCTURUS); 55 1.1 riastrad MODULE_FIRMWARE(FIRMWARE_RENOIR); 56 1.1 riastrad MODULE_FIRMWARE(FIRMWARE_NAVI10); 57 1.1 riastrad MODULE_FIRMWARE(FIRMWARE_NAVI14); 58 1.1 riastrad MODULE_FIRMWARE(FIRMWARE_NAVI12); 59 1.1 riastrad 60 1.1 riastrad static void amdgpu_vcn_idle_work_handler(struct work_struct *work); 61 1.1 riastrad 62 1.1 riastrad int amdgpu_vcn_sw_init(struct amdgpu_device *adev) 63 1.1 riastrad { 64 1.1 riastrad unsigned long bo_size; 65 1.1 riastrad const char *fw_name; 66 1.1 riastrad const struct common_firmware_header *hdr; 67 1.1 riastrad unsigned char fw_check; 68 1.1 riastrad int i, r; 69 1.1 riastrad 70 1.1 riastrad INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler); 71 1.1 riastrad 72 1.1 riastrad switch (adev->asic_type) { 73 1.1 riastrad case CHIP_RAVEN: 74 1.1 riastrad if (adev->rev_id >= 8) 75 1.1 riastrad fw_name = FIRMWARE_RAVEN2; 76 1.1 riastrad else if (adev->pdev->device == 0x15d8) 77 1.1 riastrad fw_name = FIRMWARE_PICASSO; 78 1.1 riastrad else 79 1.1 riastrad fw_name = FIRMWARE_RAVEN; 80 1.1 riastrad break; 81 1.1 riastrad case CHIP_ARCTURUS: 82 1.1 riastrad fw_name = FIRMWARE_ARCTURUS; 83 1.1 riastrad if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && 84 1.1 riastrad (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) 85 1.1 riastrad adev->vcn.indirect_sram = true; 86 1.1 riastrad break; 87 1.1 riastrad case CHIP_RENOIR: 88 1.1 riastrad fw_name = FIRMWARE_RENOIR; 89 1.1 riastrad if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && 90 1.1 riastrad (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) 91 1.1 riastrad adev->vcn.indirect_sram = true; 92 1.1 riastrad break; 93 1.1 riastrad case CHIP_NAVI10: 94 1.1 riastrad fw_name = FIRMWARE_NAVI10; 95 1.1 riastrad if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && 96 1.1 riastrad (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) 97 1.1 riastrad adev->vcn.indirect_sram = true; 98 1.1 riastrad break; 99 1.1 riastrad case CHIP_NAVI14: 100 1.1 riastrad fw_name = FIRMWARE_NAVI14; 101 1.1 riastrad if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && 102 1.1 riastrad (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) 103 1.1 riastrad adev->vcn.indirect_sram = true; 104 1.1 riastrad break; 105 1.1 riastrad case CHIP_NAVI12: 106 1.1 riastrad fw_name = FIRMWARE_NAVI12; 107 1.1 riastrad if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && 108 1.1 riastrad (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) 109 1.1 riastrad adev->vcn.indirect_sram = true; 110 1.1 riastrad break; 111 1.1 riastrad default: 112 1.1 riastrad return -EINVAL; 113 1.1 riastrad } 114 1.1 riastrad 115 1.1 riastrad r = request_firmware(&adev->vcn.fw, fw_name, adev->dev); 116 1.1 riastrad if (r) { 117 1.1 riastrad dev_err(adev->dev, "amdgpu_vcn: Can't load firmware \"%s\"\n", 118 1.1 riastrad fw_name); 119 1.1 riastrad return r; 120 1.1 riastrad } 121 1.1 riastrad 122 1.1 riastrad r = amdgpu_ucode_validate(adev->vcn.fw); 123 1.1 riastrad if (r) { 124 1.1 riastrad dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware \"%s\"\n", 125 1.1 riastrad fw_name); 126 1.1 riastrad release_firmware(adev->vcn.fw); 127 1.1 riastrad adev->vcn.fw = NULL; 128 1.1 riastrad return r; 129 1.1 riastrad } 130 1.1 riastrad 131 1.1 riastrad hdr = (const struct common_firmware_header *)adev->vcn.fw->data; 132 1.1 riastrad adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version); 133 1.1 riastrad 134 1.1 riastrad /* Bit 20-23, it is encode major and non-zero for new naming convention. 135 1.1 riastrad * This field is part of version minor and DRM_DISABLED_FLAG in old naming 136 1.1 riastrad * convention. Since the l:wq!atest version minor is 0x5B and DRM_DISABLED_FLAG 137 1.1 riastrad * is zero in old naming convention, this field is always zero so far. 138 1.1 riastrad * These four bits are used to tell which naming convention is present. 139 1.1 riastrad */ 140 1.1 riastrad fw_check = (le32_to_cpu(hdr->ucode_version) >> 20) & 0xf; 141 1.1 riastrad if (fw_check) { 142 1.1 riastrad unsigned int dec_ver, enc_major, enc_minor, vep, fw_rev; 143 1.1 riastrad 144 1.1 riastrad fw_rev = le32_to_cpu(hdr->ucode_version) & 0xfff; 145 1.1 riastrad enc_minor = (le32_to_cpu(hdr->ucode_version) >> 12) & 0xff; 146 1.1 riastrad enc_major = fw_check; 147 1.1 riastrad dec_ver = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xf; 148 1.1 riastrad vep = (le32_to_cpu(hdr->ucode_version) >> 28) & 0xf; 149 1.1 riastrad DRM_INFO("Found VCN firmware Version ENC: %hu.%hu DEC: %hu VEP: %hu Revision: %hu\n", 150 1.1 riastrad enc_major, enc_minor, dec_ver, vep, fw_rev); 151 1.1 riastrad } else { 152 1.1 riastrad unsigned int version_major, version_minor, family_id; 153 1.1 riastrad 154 1.1 riastrad family_id = le32_to_cpu(hdr->ucode_version) & 0xff; 155 1.1 riastrad version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff; 156 1.1 riastrad version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff; 157 1.1 riastrad DRM_INFO("Found VCN firmware Version: %hu.%hu Family ID: %hu\n", 158 1.1 riastrad version_major, version_minor, family_id); 159 1.1 riastrad } 160 1.1 riastrad 161 1.1 riastrad bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_CONTEXT_SIZE; 162 1.1 riastrad if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) 163 1.1 riastrad bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); 164 1.1 riastrad 165 1.1 riastrad for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 166 1.1 riastrad if (adev->vcn.harvest_config & (1 << i)) 167 1.1 riastrad continue; 168 1.1 riastrad 169 1.1 riastrad r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, 170 1.1 riastrad AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].vcpu_bo, 171 1.1 riastrad &adev->vcn.inst[i].gpu_addr, &adev->vcn.inst[i].cpu_addr); 172 1.1 riastrad if (r) { 173 1.1 riastrad dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r); 174 1.1 riastrad return r; 175 1.1 riastrad } 176 1.1 riastrad 177 1.1 riastrad if (adev->vcn.indirect_sram) { 178 1.1 riastrad r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE, 179 1.1 riastrad AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].dpg_sram_bo, 180 1.1 riastrad &adev->vcn.inst[i].dpg_sram_gpu_addr, &adev->vcn.inst[i].dpg_sram_cpu_addr); 181 1.1 riastrad if (r) { 182 1.1 riastrad dev_err(adev->dev, "VCN %d (%d) failed to allocate DPG bo\n", i, r); 183 1.1 riastrad return r; 184 1.1 riastrad } 185 1.1 riastrad } 186 1.1 riastrad } 187 1.1 riastrad 188 1.1 riastrad return 0; 189 1.1 riastrad } 190 1.1 riastrad 191 1.1 riastrad int amdgpu_vcn_sw_fini(struct amdgpu_device *adev) 192 1.1 riastrad { 193 1.1 riastrad int i, j; 194 1.1 riastrad 195 1.1 riastrad cancel_delayed_work_sync(&adev->vcn.idle_work); 196 1.1 riastrad 197 1.1 riastrad for (j = 0; j < adev->vcn.num_vcn_inst; ++j) { 198 1.1 riastrad if (adev->vcn.harvest_config & (1 << j)) 199 1.1 riastrad continue; 200 1.1 riastrad if (adev->vcn.indirect_sram) { 201 1.1 riastrad amdgpu_bo_free_kernel(&adev->vcn.inst[j].dpg_sram_bo, 202 1.1 riastrad &adev->vcn.inst[j].dpg_sram_gpu_addr, 203 1.1 riastrad (void **)&adev->vcn.inst[j].dpg_sram_cpu_addr); 204 1.1 riastrad } 205 1.1 riastrad kvfree(adev->vcn.inst[j].saved_bo); 206 1.1 riastrad 207 1.1 riastrad amdgpu_bo_free_kernel(&adev->vcn.inst[j].vcpu_bo, 208 1.1 riastrad &adev->vcn.inst[j].gpu_addr, 209 1.1 riastrad (void **)&adev->vcn.inst[j].cpu_addr); 210 1.1 riastrad 211 1.1 riastrad amdgpu_ring_fini(&adev->vcn.inst[j].ring_dec); 212 1.1 riastrad 213 1.1 riastrad for (i = 0; i < adev->vcn.num_enc_rings; ++i) 214 1.1 riastrad amdgpu_ring_fini(&adev->vcn.inst[j].ring_enc[i]); 215 1.1 riastrad } 216 1.1 riastrad 217 1.1 riastrad release_firmware(adev->vcn.fw); 218 1.1 riastrad 219 1.1 riastrad return 0; 220 1.1 riastrad } 221 1.1 riastrad 222 1.1 riastrad int amdgpu_vcn_suspend(struct amdgpu_device *adev) 223 1.1 riastrad { 224 1.1 riastrad unsigned size; 225 1.1 riastrad void *ptr; 226 1.1 riastrad int i; 227 1.1 riastrad 228 1.1 riastrad cancel_delayed_work_sync(&adev->vcn.idle_work); 229 1.1 riastrad 230 1.1 riastrad for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 231 1.1 riastrad if (adev->vcn.harvest_config & (1 << i)) 232 1.1 riastrad continue; 233 1.1 riastrad if (adev->vcn.inst[i].vcpu_bo == NULL) 234 1.1 riastrad return 0; 235 1.1 riastrad 236 1.1 riastrad size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo); 237 1.1 riastrad ptr = adev->vcn.inst[i].cpu_addr; 238 1.1 riastrad 239 1.1 riastrad adev->vcn.inst[i].saved_bo = kvmalloc(size, GFP_KERNEL); 240 1.1 riastrad if (!adev->vcn.inst[i].saved_bo) 241 1.1 riastrad return -ENOMEM; 242 1.1 riastrad 243 1.1 riastrad memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size); 244 1.1 riastrad } 245 1.1 riastrad return 0; 246 1.1 riastrad } 247 1.1 riastrad 248 1.1 riastrad int amdgpu_vcn_resume(struct amdgpu_device *adev) 249 1.1 riastrad { 250 1.1 riastrad unsigned size; 251 1.1 riastrad void *ptr; 252 1.1 riastrad int i; 253 1.1 riastrad 254 1.1 riastrad for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { 255 1.1 riastrad if (adev->vcn.harvest_config & (1 << i)) 256 1.1 riastrad continue; 257 1.1 riastrad if (adev->vcn.inst[i].vcpu_bo == NULL) 258 1.1 riastrad return -EINVAL; 259 1.1 riastrad 260 1.1 riastrad size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo); 261 1.1 riastrad ptr = adev->vcn.inst[i].cpu_addr; 262 1.1 riastrad 263 1.1 riastrad if (adev->vcn.inst[i].saved_bo != NULL) { 264 1.1 riastrad memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size); 265 1.1 riastrad kvfree(adev->vcn.inst[i].saved_bo); 266 1.1 riastrad adev->vcn.inst[i].saved_bo = NULL; 267 1.1 riastrad } else { 268 1.1 riastrad const struct common_firmware_header *hdr; 269 1.1 riastrad unsigned offset; 270 1.1 riastrad 271 1.1 riastrad hdr = (const struct common_firmware_header *)adev->vcn.fw->data; 272 1.1 riastrad if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { 273 1.1 riastrad offset = le32_to_cpu(hdr->ucode_array_offset_bytes); 274 1.1 riastrad memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset, 275 1.1 riastrad le32_to_cpu(hdr->ucode_size_bytes)); 276 1.1 riastrad size -= le32_to_cpu(hdr->ucode_size_bytes); 277 1.1 riastrad ptr += le32_to_cpu(hdr->ucode_size_bytes); 278 1.1 riastrad } 279 1.1 riastrad memset_io(ptr, 0, size); 280 1.1 riastrad } 281 1.1 riastrad } 282 1.1 riastrad return 0; 283 1.1 riastrad } 284 1.1 riastrad 285 1.1 riastrad static void amdgpu_vcn_idle_work_handler(struct work_struct *work) 286 1.1 riastrad { 287 1.1 riastrad struct amdgpu_device *adev = 288 1.1 riastrad container_of(work, struct amdgpu_device, vcn.idle_work.work); 289 1.1 riastrad unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0}; 290 1.1 riastrad unsigned int i, j; 291 1.1 riastrad 292 1.1 riastrad for (j = 0; j < adev->vcn.num_vcn_inst; ++j) { 293 1.1 riastrad if (adev->vcn.harvest_config & (1 << j)) 294 1.1 riastrad continue; 295 1.1 riastrad 296 1.1 riastrad for (i = 0; i < adev->vcn.num_enc_rings; ++i) { 297 1.1 riastrad fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]); 298 1.1 riastrad } 299 1.1 riastrad 300 1.1 riastrad if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 301 1.1 riastrad struct dpg_pause_state new_state; 302 1.1 riastrad 303 1.1 riastrad if (fence[j]) 304 1.1 riastrad new_state.fw_based = VCN_DPG_STATE__PAUSE; 305 1.1 riastrad else 306 1.1 riastrad new_state.fw_based = VCN_DPG_STATE__UNPAUSE; 307 1.1 riastrad 308 1.1 riastrad adev->vcn.pause_dpg_mode(adev, j, &new_state); 309 1.1 riastrad } 310 1.1 riastrad 311 1.1 riastrad fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_dec); 312 1.1 riastrad fences += fence[j]; 313 1.1 riastrad } 314 1.1 riastrad 315 1.1 riastrad if (fences == 0) { 316 1.1 riastrad amdgpu_gfx_off_ctrl(adev, true); 317 1.1 riastrad amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, 318 1.1 riastrad AMD_PG_STATE_GATE); 319 1.1 riastrad } else { 320 1.1 riastrad schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT); 321 1.1 riastrad } 322 1.1 riastrad } 323 1.1 riastrad 324 1.1 riastrad void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) 325 1.1 riastrad { 326 1.1 riastrad struct amdgpu_device *adev = ring->adev; 327 1.1 riastrad bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work); 328 1.1 riastrad 329 1.1 riastrad if (set_clocks) { 330 1.1 riastrad amdgpu_gfx_off_ctrl(adev, false); 331 1.1 riastrad amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, 332 1.1 riastrad AMD_PG_STATE_UNGATE); 333 1.1 riastrad } 334 1.1 riastrad 335 1.1 riastrad if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { 336 1.1 riastrad struct dpg_pause_state new_state; 337 1.1 riastrad unsigned int fences = 0; 338 1.1 riastrad unsigned int i; 339 1.1 riastrad 340 1.1 riastrad for (i = 0; i < adev->vcn.num_enc_rings; ++i) { 341 1.1 riastrad fences += amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_enc[i]); 342 1.1 riastrad } 343 1.1 riastrad if (fences) 344 1.1 riastrad new_state.fw_based = VCN_DPG_STATE__PAUSE; 345 1.1 riastrad else 346 1.1 riastrad new_state.fw_based = VCN_DPG_STATE__UNPAUSE; 347 1.1 riastrad 348 1.1 riastrad if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) 349 1.1 riastrad new_state.fw_based = VCN_DPG_STATE__PAUSE; 350 1.1 riastrad 351 1.1 riastrad adev->vcn.pause_dpg_mode(adev, ring->me, &new_state); 352 1.1 riastrad } 353 1.1 riastrad } 354 1.1 riastrad 355 1.1 riastrad void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring) 356 1.1 riastrad { 357 1.1 riastrad schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT); 358 1.1 riastrad } 359 1.1 riastrad 360 1.1 riastrad int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) 361 1.1 riastrad { 362 1.1 riastrad struct amdgpu_device *adev = ring->adev; 363 1.1 riastrad uint32_t tmp = 0; 364 1.1 riastrad unsigned i; 365 1.1 riastrad int r; 366 1.1 riastrad 367 1.1 riastrad WREG32(adev->vcn.inst[ring->me].external.scratch9, 0xCAFEDEAD); 368 1.1 riastrad r = amdgpu_ring_alloc(ring, 3); 369 1.1 riastrad if (r) 370 1.1 riastrad return r; 371 1.1 riastrad amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.scratch9, 0)); 372 1.1 riastrad amdgpu_ring_write(ring, 0xDEADBEEF); 373 1.1 riastrad amdgpu_ring_commit(ring); 374 1.1 riastrad for (i = 0; i < adev->usec_timeout; i++) { 375 1.1 riastrad tmp = RREG32(adev->vcn.inst[ring->me].external.scratch9); 376 1.1 riastrad if (tmp == 0xDEADBEEF) 377 1.1 riastrad break; 378 1.1 riastrad udelay(1); 379 1.1 riastrad } 380 1.1 riastrad 381 1.1 riastrad if (i >= adev->usec_timeout) 382 1.1 riastrad r = -ETIMEDOUT; 383 1.1 riastrad 384 1.1 riastrad return r; 385 1.1 riastrad } 386 1.1 riastrad 387 1.1 riastrad static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, 388 1.1 riastrad struct amdgpu_bo *bo, 389 1.1 riastrad struct dma_fence **fence) 390 1.1 riastrad { 391 1.1 riastrad struct amdgpu_device *adev = ring->adev; 392 1.1 riastrad struct dma_fence *f = NULL; 393 1.1 riastrad struct amdgpu_job *job; 394 1.1 riastrad struct amdgpu_ib *ib; 395 1.1 riastrad uint64_t addr; 396 1.1 riastrad int i, r; 397 1.1 riastrad 398 1.1 riastrad r = amdgpu_job_alloc_with_ib(adev, 64, &job); 399 1.1 riastrad if (r) 400 1.1 riastrad goto err; 401 1.1 riastrad 402 1.1 riastrad ib = &job->ibs[0]; 403 1.1 riastrad addr = amdgpu_bo_gpu_offset(bo); 404 1.1 riastrad ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0); 405 1.1 riastrad ib->ptr[1] = addr; 406 1.1 riastrad ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0); 407 1.1 riastrad ib->ptr[3] = addr >> 32; 408 1.1 riastrad ib->ptr[4] = PACKET0(adev->vcn.internal.cmd, 0); 409 1.1 riastrad ib->ptr[5] = 0; 410 1.1 riastrad for (i = 6; i < 16; i += 2) { 411 1.1 riastrad ib->ptr[i] = PACKET0(adev->vcn.internal.nop, 0); 412 1.1 riastrad ib->ptr[i+1] = 0; 413 1.1 riastrad } 414 1.1 riastrad ib->length_dw = 16; 415 1.1 riastrad 416 1.1 riastrad r = amdgpu_job_submit_direct(job, ring, &f); 417 1.1 riastrad if (r) 418 1.1 riastrad goto err_free; 419 1.1 riastrad 420 1.1 riastrad amdgpu_bo_fence(bo, f, false); 421 1.1 riastrad amdgpu_bo_unreserve(bo); 422 1.1 riastrad amdgpu_bo_unref(&bo); 423 1.1 riastrad 424 1.1 riastrad if (fence) 425 1.1 riastrad *fence = dma_fence_get(f); 426 1.1 riastrad dma_fence_put(f); 427 1.1 riastrad 428 1.1 riastrad return 0; 429 1.1 riastrad 430 1.1 riastrad err_free: 431 1.1 riastrad amdgpu_job_free(job); 432 1.1 riastrad 433 1.1 riastrad err: 434 1.1 riastrad amdgpu_bo_unreserve(bo); 435 1.1 riastrad amdgpu_bo_unref(&bo); 436 1.1 riastrad return r; 437 1.1 riastrad } 438 1.1 riastrad 439 1.1 riastrad static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, 440 1.1 riastrad struct dma_fence **fence) 441 1.1 riastrad { 442 1.1 riastrad struct amdgpu_device *adev = ring->adev; 443 1.1 riastrad struct amdgpu_bo *bo = NULL; 444 1.1 riastrad uint32_t *msg; 445 1.1 riastrad int r, i; 446 1.1 riastrad 447 1.1 riastrad r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE, 448 1.1 riastrad AMDGPU_GEM_DOMAIN_VRAM, 449 1.1 riastrad &bo, NULL, (void **)&msg); 450 1.1 riastrad if (r) 451 1.1 riastrad return r; 452 1.1 riastrad 453 1.1 riastrad msg[0] = cpu_to_le32(0x00000028); 454 1.1 riastrad msg[1] = cpu_to_le32(0x00000038); 455 1.1 riastrad msg[2] = cpu_to_le32(0x00000001); 456 1.1 riastrad msg[3] = cpu_to_le32(0x00000000); 457 1.1 riastrad msg[4] = cpu_to_le32(handle); 458 1.1 riastrad msg[5] = cpu_to_le32(0x00000000); 459 1.1 riastrad msg[6] = cpu_to_le32(0x00000001); 460 1.1 riastrad msg[7] = cpu_to_le32(0x00000028); 461 1.1 riastrad msg[8] = cpu_to_le32(0x00000010); 462 1.1 riastrad msg[9] = cpu_to_le32(0x00000000); 463 1.1 riastrad msg[10] = cpu_to_le32(0x00000007); 464 1.1 riastrad msg[11] = cpu_to_le32(0x00000000); 465 1.1 riastrad msg[12] = cpu_to_le32(0x00000780); 466 1.1 riastrad msg[13] = cpu_to_le32(0x00000440); 467 1.1 riastrad for (i = 14; i < 1024; ++i) 468 1.1 riastrad msg[i] = cpu_to_le32(0x0); 469 1.1 riastrad 470 1.1 riastrad return amdgpu_vcn_dec_send_msg(ring, bo, fence); 471 1.1 riastrad } 472 1.1 riastrad 473 1.1 riastrad static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, 474 1.1 riastrad struct dma_fence **fence) 475 1.1 riastrad { 476 1.1 riastrad struct amdgpu_device *adev = ring->adev; 477 1.1 riastrad struct amdgpu_bo *bo = NULL; 478 1.1 riastrad uint32_t *msg; 479 1.1 riastrad int r, i; 480 1.1 riastrad 481 1.1 riastrad r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE, 482 1.1 riastrad AMDGPU_GEM_DOMAIN_VRAM, 483 1.1 riastrad &bo, NULL, (void **)&msg); 484 1.1 riastrad if (r) 485 1.1 riastrad return r; 486 1.1 riastrad 487 1.1 riastrad msg[0] = cpu_to_le32(0x00000028); 488 1.1 riastrad msg[1] = cpu_to_le32(0x00000018); 489 1.1 riastrad msg[2] = cpu_to_le32(0x00000000); 490 1.1 riastrad msg[3] = cpu_to_le32(0x00000002); 491 1.1 riastrad msg[4] = cpu_to_le32(handle); 492 1.1 riastrad msg[5] = cpu_to_le32(0x00000000); 493 1.1 riastrad for (i = 6; i < 1024; ++i) 494 1.1 riastrad msg[i] = cpu_to_le32(0x0); 495 1.1 riastrad 496 1.1 riastrad return amdgpu_vcn_dec_send_msg(ring, bo, fence); 497 1.1 riastrad } 498 1.1 riastrad 499 1.1 riastrad int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout) 500 1.1 riastrad { 501 1.1 riastrad struct amdgpu_device *adev = ring->adev; 502 1.1 riastrad struct dma_fence *fence; 503 1.1 riastrad long r; 504 1.1 riastrad 505 1.1 riastrad /* temporarily disable ib test for sriov */ 506 1.1 riastrad if (amdgpu_sriov_vf(adev)) 507 1.1 riastrad return 0; 508 1.1 riastrad 509 1.1 riastrad r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL); 510 1.1 riastrad if (r) 511 1.1 riastrad goto error; 512 1.1 riastrad 513 1.1 riastrad r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence); 514 1.1 riastrad if (r) 515 1.1 riastrad goto error; 516 1.1 riastrad 517 1.1 riastrad r = dma_fence_wait_timeout(fence, false, timeout); 518 1.1 riastrad if (r == 0) 519 1.1 riastrad r = -ETIMEDOUT; 520 1.1 riastrad else if (r > 0) 521 1.1 riastrad r = 0; 522 1.1 riastrad 523 1.1 riastrad dma_fence_put(fence); 524 1.1 riastrad error: 525 1.1 riastrad return r; 526 1.1 riastrad } 527 1.1 riastrad 528 1.1 riastrad int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) 529 1.1 riastrad { 530 1.1 riastrad struct amdgpu_device *adev = ring->adev; 531 1.1 riastrad uint32_t rptr; 532 1.1 riastrad unsigned i; 533 1.1 riastrad int r; 534 1.1 riastrad 535 1.1 riastrad r = amdgpu_ring_alloc(ring, 16); 536 1.1 riastrad if (r) 537 1.1 riastrad return r; 538 1.1 riastrad 539 1.1 riastrad rptr = amdgpu_ring_get_rptr(ring); 540 1.1 riastrad 541 1.1 riastrad amdgpu_ring_write(ring, VCN_ENC_CMD_END); 542 1.1 riastrad amdgpu_ring_commit(ring); 543 1.1 riastrad 544 1.1 riastrad for (i = 0; i < adev->usec_timeout; i++) { 545 1.1 riastrad if (amdgpu_ring_get_rptr(ring) != rptr) 546 1.1 riastrad break; 547 1.1 riastrad udelay(1); 548 1.1 riastrad } 549 1.1 riastrad 550 1.1 riastrad if (i >= adev->usec_timeout) 551 1.1 riastrad r = -ETIMEDOUT; 552 1.1 riastrad 553 1.1 riastrad return r; 554 1.1 riastrad } 555 1.1 riastrad 556 1.1 riastrad static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, 557 1.1 riastrad struct amdgpu_bo *bo, 558 1.1 riastrad struct dma_fence **fence) 559 1.1 riastrad { 560 1.1 riastrad const unsigned ib_size_dw = 16; 561 1.1 riastrad struct amdgpu_job *job; 562 1.1 riastrad struct amdgpu_ib *ib; 563 1.1 riastrad struct dma_fence *f = NULL; 564 1.1 riastrad uint64_t addr; 565 1.1 riastrad int i, r; 566 1.1 riastrad 567 1.1 riastrad r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); 568 1.1 riastrad if (r) 569 1.1 riastrad return r; 570 1.1 riastrad 571 1.1 riastrad ib = &job->ibs[0]; 572 1.1 riastrad addr = amdgpu_bo_gpu_offset(bo); 573 1.1 riastrad 574 1.1 riastrad ib->length_dw = 0; 575 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000018; 576 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ 577 1.1 riastrad ib->ptr[ib->length_dw++] = handle; 578 1.1 riastrad ib->ptr[ib->length_dw++] = upper_32_bits(addr); 579 1.1 riastrad ib->ptr[ib->length_dw++] = addr; 580 1.1 riastrad ib->ptr[ib->length_dw++] = 0x0000000b; 581 1.1 riastrad 582 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000014; 583 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ 584 1.1 riastrad ib->ptr[ib->length_dw++] = 0x0000001c; 585 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000000; 586 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000000; 587 1.1 riastrad 588 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000008; 589 1.1 riastrad ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */ 590 1.1 riastrad 591 1.1 riastrad for (i = ib->length_dw; i < ib_size_dw; ++i) 592 1.1 riastrad ib->ptr[i] = 0x0; 593 1.1 riastrad 594 1.1 riastrad r = amdgpu_job_submit_direct(job, ring, &f); 595 1.1 riastrad if (r) 596 1.1 riastrad goto err; 597 1.1 riastrad 598 1.1 riastrad if (fence) 599 1.1 riastrad *fence = dma_fence_get(f); 600 1.1 riastrad dma_fence_put(f); 601 1.1 riastrad 602 1.1 riastrad return 0; 603 1.1 riastrad 604 1.1 riastrad err: 605 1.1 riastrad amdgpu_job_free(job); 606 1.1 riastrad return r; 607 1.1 riastrad } 608 1.1 riastrad 609 1.1 riastrad static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, 610 1.1 riastrad struct amdgpu_bo *bo, 611 1.1 riastrad struct dma_fence **fence) 612 1.1 riastrad { 613 1.1 riastrad const unsigned ib_size_dw = 16; 614 1.1 riastrad struct amdgpu_job *job; 615 1.1 riastrad struct amdgpu_ib *ib; 616 1.1 riastrad struct dma_fence *f = NULL; 617 1.1 riastrad uint64_t addr; 618 1.1 riastrad int i, r; 619 1.1 riastrad 620 1.1 riastrad r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); 621 1.1 riastrad if (r) 622 1.1 riastrad return r; 623 1.1 riastrad 624 1.1 riastrad ib = &job->ibs[0]; 625 1.1 riastrad addr = amdgpu_bo_gpu_offset(bo); 626 1.1 riastrad 627 1.1 riastrad ib->length_dw = 0; 628 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000018; 629 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000001; 630 1.1 riastrad ib->ptr[ib->length_dw++] = handle; 631 1.1 riastrad ib->ptr[ib->length_dw++] = upper_32_bits(addr); 632 1.1 riastrad ib->ptr[ib->length_dw++] = addr; 633 1.1 riastrad ib->ptr[ib->length_dw++] = 0x0000000b; 634 1.1 riastrad 635 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000014; 636 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000002; 637 1.1 riastrad ib->ptr[ib->length_dw++] = 0x0000001c; 638 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000000; 639 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000000; 640 1.1 riastrad 641 1.1 riastrad ib->ptr[ib->length_dw++] = 0x00000008; 642 1.1 riastrad ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */ 643 1.1 riastrad 644 1.1 riastrad for (i = ib->length_dw; i < ib_size_dw; ++i) 645 1.1 riastrad ib->ptr[i] = 0x0; 646 1.1 riastrad 647 1.1 riastrad r = amdgpu_job_submit_direct(job, ring, &f); 648 1.1 riastrad if (r) 649 1.1 riastrad goto err; 650 1.1 riastrad 651 1.1 riastrad if (fence) 652 1.1 riastrad *fence = dma_fence_get(f); 653 1.1 riastrad dma_fence_put(f); 654 1.1 riastrad 655 1.1 riastrad return 0; 656 1.1 riastrad 657 1.1 riastrad err: 658 1.1 riastrad amdgpu_job_free(job); 659 1.1 riastrad return r; 660 1.1 riastrad } 661 1.1 riastrad 662 1.1 riastrad int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) 663 1.1 riastrad { 664 1.1 riastrad struct amdgpu_device *adev = ring->adev; 665 1.1 riastrad struct dma_fence *fence = NULL; 666 1.1 riastrad struct amdgpu_bo *bo = NULL; 667 1.1 riastrad long r; 668 1.1 riastrad 669 1.1 riastrad /* temporarily disable ib test for sriov */ 670 1.1 riastrad if (amdgpu_sriov_vf(adev)) 671 1.1 riastrad return 0; 672 1.1 riastrad 673 1.1 riastrad r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, 674 1.1 riastrad AMDGPU_GEM_DOMAIN_VRAM, 675 1.1 riastrad &bo, NULL, NULL); 676 1.1 riastrad if (r) 677 1.1 riastrad return r; 678 1.1 riastrad 679 1.1 riastrad r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL); 680 1.1 riastrad if (r) 681 1.1 riastrad goto error; 682 1.1 riastrad 683 1.1 riastrad r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence); 684 1.1 riastrad if (r) 685 1.1 riastrad goto error; 686 1.1 riastrad 687 1.1 riastrad r = dma_fence_wait_timeout(fence, false, timeout); 688 1.1 riastrad if (r == 0) 689 1.1 riastrad r = -ETIMEDOUT; 690 1.1 riastrad else if (r > 0) 691 1.1 riastrad r = 0; 692 1.1 riastrad 693 1.1 riastrad error: 694 1.1 riastrad dma_fence_put(fence); 695 1.1 riastrad amdgpu_bo_unreserve(bo); 696 1.1 riastrad amdgpu_bo_unref(&bo); 697 1.1 riastrad return r; 698 1.1 riastrad } 699