1 /* 2 * Copyright 2019 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 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 19 * USE OR OTHER DEALINGS IN THE SOFTWARE. 20 * 21 * The above copyright notice and this permission notice (including the 22 * next paragraph) shall be included in all copies or substantial portions 23 * of the Software. 24 * 25 */ 26 27 #include "amdgpu.h" 28 #include "amdgpu_ip.h" 29 #include "amdgpu_jpeg.h" 30 #include "amdgpu_pm.h" 31 #include "soc15d.h" 32 #include "soc15_common.h" 33 34 #define JPEG_IDLE_TIMEOUT msecs_to_jiffies(1000) 35 36 static void amdgpu_jpeg_idle_work_handler(struct work_struct *work); 37 static void amdgpu_jpeg_reg_dump_fini(struct amdgpu_device *adev); 38 39 int amdgpu_jpeg_sw_init(struct amdgpu_device *adev) 40 { 41 int i, r; 42 43 INIT_DELAYED_WORK(&adev->jpeg.idle_work, amdgpu_jpeg_idle_work_handler); 44 mutex_init(&adev->jpeg.jpeg_pg_lock); 45 atomic_set(&adev->jpeg.total_submission_cnt, 0); 46 47 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && 48 (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG)) 49 adev->jpeg.indirect_sram = true; 50 51 for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) { 52 if (adev->jpeg.harvest_config & (1U << i)) 53 continue; 54 55 if (adev->jpeg.indirect_sram) { 56 r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE, 57 AMDGPU_GEM_DOMAIN_VRAM | 58 AMDGPU_GEM_DOMAIN_GTT, 59 &adev->jpeg.inst[i].dpg_sram_bo, 60 &adev->jpeg.inst[i].dpg_sram_gpu_addr, 61 &adev->jpeg.inst[i].dpg_sram_cpu_addr); 62 if (r) { 63 dev_err(adev->dev, 64 "JPEG %d (%d) failed to allocate DPG bo\n", i, r); 65 return r; 66 } 67 } 68 } 69 70 return 0; 71 } 72 73 int amdgpu_jpeg_sw_fini(struct amdgpu_device *adev) 74 { 75 int i, j; 76 77 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 78 if (adev->jpeg.harvest_config & (1U << i)) 79 continue; 80 81 amdgpu_bo_free_kernel( 82 &adev->jpeg.inst[i].dpg_sram_bo, 83 &adev->jpeg.inst[i].dpg_sram_gpu_addr, 84 (void **)&adev->jpeg.inst[i].dpg_sram_cpu_addr); 85 86 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) 87 amdgpu_ring_fini(&adev->jpeg.inst[i].ring_dec[j]); 88 } 89 90 if (adev->jpeg.reg_list) 91 amdgpu_jpeg_reg_dump_fini(adev); 92 93 mutex_destroy(&adev->jpeg.jpeg_pg_lock); 94 95 return 0; 96 } 97 98 int amdgpu_jpeg_suspend(struct amdgpu_device *adev) 99 { 100 cancel_delayed_work_sync(&adev->jpeg.idle_work); 101 102 return 0; 103 } 104 105 int amdgpu_jpeg_resume(struct amdgpu_device *adev) 106 { 107 return 0; 108 } 109 110 static void amdgpu_jpeg_idle_work_handler(struct work_struct *work) 111 { 112 struct amdgpu_device *adev = 113 container_of(work, struct amdgpu_device, jpeg.idle_work.work); 114 unsigned int fences = 0; 115 unsigned int i, j; 116 117 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 118 if (adev->jpeg.harvest_config & (1U << i)) 119 continue; 120 121 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) 122 fences += amdgpu_fence_count_emitted(&adev->jpeg.inst[i].ring_dec[j]); 123 } 124 125 if (!fences && !atomic_read(&adev->jpeg.total_submission_cnt)) { 126 mutex_lock(&adev->jpeg.jpeg_pg_lock); 127 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG, 128 AMD_PG_STATE_GATE); 129 mutex_unlock(&adev->jpeg.jpeg_pg_lock); 130 } else 131 schedule_delayed_work(&adev->jpeg.idle_work, JPEG_IDLE_TIMEOUT); 132 } 133 134 void amdgpu_jpeg_ring_begin_use(struct amdgpu_ring *ring) 135 { 136 struct amdgpu_device *adev = ring->adev; 137 138 if (!atomic_fetch_inc(&adev->jpeg.total_submission_cnt)) 139 cancel_delayed_work_sync(&adev->jpeg.idle_work); 140 141 mutex_lock(&adev->jpeg.jpeg_pg_lock); 142 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG, 143 AMD_PG_STATE_UNGATE); 144 mutex_unlock(&adev->jpeg.jpeg_pg_lock); 145 } 146 147 void amdgpu_jpeg_ring_end_use(struct amdgpu_ring *ring) 148 { 149 if (atomic_dec_and_test(&ring->adev->jpeg.total_submission_cnt)) 150 schedule_delayed_work(&ring->adev->jpeg.idle_work, 151 JPEG_IDLE_TIMEOUT); 152 } 153 154 int amdgpu_jpeg_dec_ring_test_ring(struct amdgpu_ring *ring) 155 { 156 struct amdgpu_device *adev = ring->adev; 157 uint32_t tmp = 0; 158 unsigned i; 159 int r; 160 161 /* JPEG in SRIOV does not support direct register read/write */ 162 if (amdgpu_sriov_vf(adev)) 163 return 0; 164 165 r = amdgpu_ring_alloc(ring, 3); 166 if (r) 167 return r; 168 169 WREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch[ring->pipe], 0xCAFEDEAD); 170 /* Add a read register to make sure the write register is executed. */ 171 RREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch[ring->pipe]); 172 173 amdgpu_ring_write(ring, PACKET0(adev->jpeg.internal.jpeg_pitch[ring->pipe], 0)); 174 amdgpu_ring_write(ring, 0xABADCAFE); 175 amdgpu_ring_commit(ring); 176 177 for (i = 0; i < adev->usec_timeout; i++) { 178 tmp = RREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch[ring->pipe]); 179 if (tmp == 0xABADCAFE) 180 break; 181 udelay(1); 182 } 183 184 if (i >= adev->usec_timeout) 185 r = -ETIMEDOUT; 186 187 return r; 188 } 189 190 static int amdgpu_jpeg_dec_set_reg(struct amdgpu_ring *ring, uint32_t handle, 191 struct dma_fence **fence) 192 { 193 struct amdgpu_device *adev = ring->adev; 194 struct amdgpu_job *job; 195 struct amdgpu_ib *ib; 196 struct dma_fence *f = NULL; 197 const unsigned ib_size_dw = 16; 198 int i, r; 199 200 r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL, ib_size_dw * 4, 201 AMDGPU_IB_POOL_DIRECT, 202 AMDGPU_KERNEL_JOB_ID_VCN_RING_TEST, 203 &job); 204 if (r) 205 return r; 206 207 ib = &job->ibs[0]; 208 209 ib->ptr[0] = PACKETJ(adev->jpeg.internal.jpeg_pitch[ring->pipe], 0, 0, PACKETJ_TYPE0); 210 ib->ptr[1] = 0xDEADBEEF; 211 for (i = 2; i < 16; i += 2) { 212 ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6); 213 ib->ptr[i+1] = 0; 214 } 215 ib->length_dw = 16; 216 217 r = amdgpu_job_submit_direct(job, ring, &f); 218 if (r) 219 goto err; 220 221 if (fence) 222 *fence = dma_fence_get(f); 223 dma_fence_put(f); 224 225 return 0; 226 227 err: 228 amdgpu_job_free(job); 229 return r; 230 } 231 232 int amdgpu_jpeg_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout) 233 { 234 struct amdgpu_device *adev = ring->adev; 235 uint32_t tmp = 0; 236 unsigned i; 237 struct dma_fence *fence = NULL; 238 long r = 0; 239 240 r = amdgpu_jpeg_dec_set_reg(ring, 1, &fence); 241 if (r) 242 goto error; 243 244 r = dma_fence_wait_timeout(fence, false, timeout); 245 if (r == 0) { 246 r = -ETIMEDOUT; 247 goto error; 248 } else if (r < 0) { 249 goto error; 250 } else { 251 r = 0; 252 } 253 254 if (!amdgpu_sriov_vf(adev)) { 255 for (i = 0; i < adev->usec_timeout; i++) { 256 tmp = RREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch[ring->pipe]); 257 if (tmp == 0xDEADBEEF) 258 break; 259 udelay(1); 260 if (amdgpu_emu_mode == 1) 261 udelay(10); 262 } 263 264 if (i >= adev->usec_timeout) 265 r = -ETIMEDOUT; 266 } 267 268 dma_fence_put(fence); 269 error: 270 return r; 271 } 272 273 int amdgpu_jpeg_process_poison_irq(struct amdgpu_device *adev, 274 struct amdgpu_irq_src *source, 275 struct amdgpu_iv_entry *entry) 276 { 277 struct ras_common_if *ras_if = adev->jpeg.ras_if; 278 struct ras_dispatch_if ih_data = { 279 .entry = entry, 280 }; 281 282 if (!ras_if) 283 return 0; 284 285 ih_data.head = *ras_if; 286 amdgpu_ras_interrupt_dispatch(adev, &ih_data); 287 288 return 0; 289 } 290 291 int amdgpu_jpeg_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block) 292 { 293 int r, i; 294 295 r = amdgpu_ras_block_late_init(adev, ras_block); 296 if (r) 297 return r; 298 299 if (amdgpu_ras_is_supported(adev, ras_block->block)) { 300 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 301 if (adev->jpeg.harvest_config & (1 << i) || 302 !adev->jpeg.inst[i].ras_poison_irq.funcs) 303 continue; 304 305 r = amdgpu_irq_get(adev, &adev->jpeg.inst[i].ras_poison_irq, 0); 306 if (r) 307 goto late_fini; 308 } 309 } 310 return 0; 311 312 late_fini: 313 amdgpu_ras_block_late_fini(adev, ras_block); 314 return r; 315 } 316 317 int amdgpu_jpeg_ras_sw_init(struct amdgpu_device *adev) 318 { 319 int err; 320 struct amdgpu_jpeg_ras *ras; 321 322 if (!adev->jpeg.ras) 323 return 0; 324 325 ras = adev->jpeg.ras; 326 err = amdgpu_ras_register_ras_block(adev, &ras->ras_block); 327 if (err) { 328 dev_err(adev->dev, "Failed to register jpeg ras block!\n"); 329 return err; 330 } 331 332 strcpy(ras->ras_block.ras_comm.name, "jpeg"); 333 ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__JPEG; 334 ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__POISON; 335 adev->jpeg.ras_if = &ras->ras_block.ras_comm; 336 337 if (!ras->ras_block.ras_late_init) 338 ras->ras_block.ras_late_init = amdgpu_jpeg_ras_late_init; 339 340 return 0; 341 } 342 343 int amdgpu_jpeg_psp_update_sram(struct amdgpu_device *adev, int inst_idx, 344 enum AMDGPU_UCODE_ID ucode_id) 345 { 346 struct amdgpu_firmware_info ucode = { 347 .ucode_id = AMDGPU_UCODE_ID_JPEG_RAM, 348 .mc_addr = adev->jpeg.inst[inst_idx].dpg_sram_gpu_addr, 349 .ucode_size = ((uintptr_t)adev->jpeg.inst[inst_idx].dpg_sram_curr_addr - 350 (uintptr_t)adev->jpeg.inst[inst_idx].dpg_sram_cpu_addr), 351 }; 352 353 return psp_execute_ip_fw_load(&adev->psp, &ucode); 354 } 355 356 /* 357 * debugfs for to enable/disable jpeg job submission to specific core. 358 */ 359 #if defined(CONFIG_DEBUG_FS) 360 static int amdgpu_debugfs_jpeg_sched_mask_set(void *data, u64 val) 361 { 362 struct amdgpu_device *adev = (struct amdgpu_device *)data; 363 u32 i, j; 364 u64 mask = 0; 365 struct amdgpu_ring *ring; 366 367 if (!adev) 368 return -ENODEV; 369 370 mask = (1ULL << (adev->jpeg.num_jpeg_inst * adev->jpeg.num_jpeg_rings)) - 1; 371 if ((val & mask) == 0) 372 return -EINVAL; 373 374 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 375 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 376 ring = &adev->jpeg.inst[i].ring_dec[j]; 377 if (val & (BIT_ULL((i * adev->jpeg.num_jpeg_rings) + j))) 378 ring->sched.ready = true; 379 else 380 ring->sched.ready = false; 381 } 382 } 383 /* publish sched.ready flag update effective immediately across smp */ 384 smp_rmb(); 385 return 0; 386 } 387 388 static int amdgpu_debugfs_jpeg_sched_mask_get(void *data, u64 *val) 389 { 390 struct amdgpu_device *adev = (struct amdgpu_device *)data; 391 u32 i, j; 392 u64 mask = 0; 393 struct amdgpu_ring *ring; 394 395 if (!adev) 396 return -ENODEV; 397 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 398 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 399 ring = &adev->jpeg.inst[i].ring_dec[j]; 400 if (ring->sched.ready) 401 mask |= 1ULL << ((i * adev->jpeg.num_jpeg_rings) + j); 402 } 403 } 404 *val = mask; 405 return 0; 406 } 407 408 DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_debugfs_jpeg_sched_mask_fops, 409 amdgpu_debugfs_jpeg_sched_mask_get, 410 amdgpu_debugfs_jpeg_sched_mask_set, "%llx\n"); 411 412 #endif 413 414 void amdgpu_debugfs_jpeg_sched_mask_init(struct amdgpu_device *adev) 415 { 416 #if defined(CONFIG_DEBUG_FS) 417 struct drm_minor *minor = adev_to_drm(adev)->primary; 418 struct dentry *root = minor->debugfs_root; 419 char name[32]; 420 421 if (!(adev->jpeg.num_jpeg_inst > 1) && !(adev->jpeg.num_jpeg_rings > 1)) 422 return; 423 sprintf(name, "amdgpu_jpeg_sched_mask"); 424 debugfs_create_file(name, 0600, root, adev, 425 &amdgpu_debugfs_jpeg_sched_mask_fops); 426 #endif 427 } 428 429 static ssize_t amdgpu_get_jpeg_reset_mask(struct device *dev, 430 struct device_attribute *attr, 431 char *buf) 432 { 433 struct drm_device *ddev = dev_get_drvdata(dev); 434 struct amdgpu_device *adev = drm_to_adev(ddev); 435 436 if (!adev) 437 return -ENODEV; 438 439 return amdgpu_show_reset_mask(buf, adev->jpeg.supported_reset); 440 } 441 442 static DEVICE_ATTR(jpeg_reset_mask, 0444, 443 amdgpu_get_jpeg_reset_mask, NULL); 444 445 int amdgpu_jpeg_sysfs_reset_mask_init(struct amdgpu_device *adev) 446 { 447 int r = 0; 448 449 if (adev->jpeg.num_jpeg_inst) { 450 r = device_create_file(adev->dev, &dev_attr_jpeg_reset_mask); 451 if (r) 452 return r; 453 } 454 455 return r; 456 } 457 458 void amdgpu_jpeg_sysfs_reset_mask_fini(struct amdgpu_device *adev) 459 { 460 if (adev->dev->kobj.sd) { 461 if (adev->jpeg.num_jpeg_inst) 462 device_remove_file(adev->dev, &dev_attr_jpeg_reset_mask); 463 } 464 } 465 466 int amdgpu_jpeg_reg_dump_init(struct amdgpu_device *adev, 467 const struct amdgpu_hwip_reg_entry *reg, u32 count) 468 { 469 adev->jpeg.ip_dump = kzalloc_objs(*adev->jpeg.ip_dump, 470 adev->jpeg.num_jpeg_inst * count); 471 if (!adev->jpeg.ip_dump) { 472 dev_err(adev->dev, 473 "Failed to allocate memory for JPEG IP Dump\n"); 474 return -ENOMEM; 475 } 476 adev->jpeg.reg_list = reg; 477 adev->jpeg.reg_count = count; 478 479 return 0; 480 } 481 482 static void amdgpu_jpeg_reg_dump_fini(struct amdgpu_device *adev) 483 { 484 kfree(adev->jpeg.ip_dump); 485 adev->jpeg.reg_list = NULL; 486 adev->jpeg.reg_count = 0; 487 } 488 489 void amdgpu_jpeg_dump_ip_state(struct amdgpu_ip_block *ip_block) 490 { 491 struct amdgpu_device *adev = ip_block->adev; 492 u32 inst_off, inst_id, is_powered; 493 int i, j; 494 495 if (!adev->jpeg.ip_dump) 496 return; 497 498 for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) { 499 if (adev->jpeg.harvest_config & (1 << i)) 500 continue; 501 502 inst_id = GET_INST(JPEG, i); 503 inst_off = i * adev->jpeg.reg_count; 504 /* check power status from UVD_JPEG_POWER_STATUS */ 505 adev->jpeg.ip_dump[inst_off] = 506 RREG32(SOC15_REG_ENTRY_OFFSET_INST(adev->jpeg.reg_list[0], 507 inst_id)); 508 is_powered = ((adev->jpeg.ip_dump[inst_off] & 0x1) != 1); 509 510 if (is_powered) 511 for (j = 1; j < adev->jpeg.reg_count; j++) 512 adev->jpeg.ip_dump[inst_off + j] = 513 RREG32(SOC15_REG_ENTRY_OFFSET_INST(adev->jpeg.reg_list[j], 514 inst_id)); 515 } 516 } 517 518 void amdgpu_jpeg_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) 519 { 520 struct amdgpu_device *adev = ip_block->adev; 521 u32 inst_off, is_powered; 522 int i, j; 523 524 if (!adev->jpeg.ip_dump) 525 return; 526 527 drm_printf(p, "num_instances:%d\n", adev->jpeg.num_jpeg_inst); 528 for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) { 529 if (adev->jpeg.harvest_config & (1 << i)) { 530 drm_printf(p, "\nHarvested Instance:JPEG%d Skipping dump\n", i); 531 continue; 532 } 533 534 inst_off = i * adev->jpeg.reg_count; 535 is_powered = ((adev->jpeg.ip_dump[inst_off] & 0x1) != 1); 536 537 if (is_powered) { 538 drm_printf(p, "Active Instance:JPEG%d\n", i); 539 for (j = 0; j < adev->jpeg.reg_count; j++) 540 drm_printf(p, "%-50s \t 0x%08x\n", adev->jpeg.reg_list[j].reg_name, 541 adev->jpeg.ip_dump[inst_off + j]); 542 } else 543 drm_printf(p, "\nInactive Instance:JPEG%d\n", i); 544 } 545 } 546 547 static inline bool amdgpu_jpeg_reg_valid(u32 reg) 548 { 549 if (reg < JPEG_REG_RANGE_START || reg > JPEG_REG_RANGE_END || 550 (reg >= JPEG_ATOMIC_RANGE_START && reg <= JPEG_ATOMIC_RANGE_END)) 551 return false; 552 else 553 return true; 554 } 555 556 /** 557 * amdgpu_jpeg_dec_parse_cs - command submission parser 558 * 559 * @parser: Command submission parser context 560 * @job: the job to parse 561 * @ib: the IB to parse 562 * 563 * Parse the command stream, return -EINVAL for invalid packet, 564 * 0 otherwise 565 */ 566 567 int amdgpu_jpeg_dec_parse_cs(struct amdgpu_cs_parser *parser, 568 struct amdgpu_job *job, 569 struct amdgpu_ib *ib) 570 { 571 u32 i, reg, res, cond, type; 572 struct amdgpu_device *adev = parser->adev; 573 574 for (i = 0; i < ib->length_dw ; i += 2) { 575 reg = CP_PACKETJ_GET_REG(ib->ptr[i]); 576 res = CP_PACKETJ_GET_RES(ib->ptr[i]); 577 cond = CP_PACKETJ_GET_COND(ib->ptr[i]); 578 type = CP_PACKETJ_GET_TYPE(ib->ptr[i]); 579 580 if (res) /* only support 0 at the moment */ 581 return -EINVAL; 582 583 switch (type) { 584 case PACKETJ_TYPE0: 585 if (cond != PACKETJ_CONDITION_CHECK0 || 586 !amdgpu_jpeg_reg_valid(reg)) { 587 dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]); 588 return -EINVAL; 589 } 590 break; 591 case PACKETJ_TYPE3: 592 if (cond != PACKETJ_CONDITION_CHECK3 || 593 !amdgpu_jpeg_reg_valid(reg)) { 594 dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]); 595 return -EINVAL; 596 } 597 break; 598 case PACKETJ_TYPE6: 599 if (ib->ptr[i] == CP_PACKETJ_NOP) 600 continue; 601 dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]); 602 return -EINVAL; 603 default: 604 dev_err(adev->dev, "Unknown packet type %d !\n", type); 605 return -EINVAL; 606 } 607 } 608 609 return 0; 610 } 611 612 /** 613 * amdgpu_jpeg_is_shared_inv_eng - Check if a ring is a JPEG ring that shares a VM invalidation 614 * engine 615 * @adev: Pointer to the AMDGPU device structure 616 * @ring: Pointer to the ring structure to check 617 * 618 * All decode rings within one JPEG instance share a single VM invalidation 619 * engine (see amdgpu_jpeg_set_shared_inv_eng()). This returns true for every 620 * ring in the instance except the first (ring->pipe == 0), which owns the 621 * engine allocated by amdgpu_gmc_allocate_vm_inv_eng(). 622 */ 623 bool amdgpu_jpeg_is_shared_inv_eng(struct amdgpu_device *adev, struct amdgpu_ring *ring) 624 { 625 return ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG && ring->pipe != 0; 626 } 627 628 /** 629 * amdgpu_jpeg_set_shared_inv_eng - Propagate a VM invalidation engine to the rest of a JPEG 630 * instance 631 * @adev: Pointer to the AMDGPU device structure 632 * @ring: Pointer to the ring that just had a VM invalidation engine allocated 633 * 634 * No-op unless @ring is the owner (ring->pipe == 0) of a JPEG instance. 635 * When it is, mirrors its freshly allocated vm_inv_eng onto the rest of the 636 * rings in that instance, so the whole instance shares one engine instead of 637 * consuming one per ring. 638 */ 639 void amdgpu_jpeg_set_shared_inv_eng(struct amdgpu_device *adev, struct amdgpu_ring *ring) 640 { 641 int j; 642 643 if (ring->funcs->type != AMDGPU_RING_TYPE_VCN_JPEG || ring->pipe != 0) 644 return; 645 646 for (j = 1; j < adev->jpeg.num_jpeg_rings; j++) 647 adev->jpeg.inst[ring->me].ring_dec[j].vm_inv_eng = ring->vm_inv_eng; 648 } 649