1 // SPDX-License-Identifier: GPL-2.0 OR MIT 2 /* 3 * Copyright 2014-2024 Advanced Micro Devices, Inc. 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 #include "amdgpu.h" 25 #include "amdgpu_jpeg.h" 26 #include "amdgpu_pm.h" 27 #include "soc15.h" 28 #include "soc15d.h" 29 #include "jpeg_v4_0_3.h" 30 #include "jpeg_v5_0_1.h" 31 32 #include "vcn/vcn_5_0_0_offset.h" 33 #include "vcn/vcn_5_0_0_sh_mask.h" 34 #include "ivsrcid/vcn/irqsrcs_vcn_5_0.h" 35 36 static void jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device *adev); 37 static void jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device *adev); 38 static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block, 39 enum amd_powergating_state state); 40 static void jpeg_v5_0_1_dec_ring_set_wptr(struct amdgpu_ring *ring); 41 42 static int amdgpu_ih_srcid_jpeg[] = { 43 VCN_5_0__SRCID__JPEG_DECODE, 44 VCN_5_0__SRCID__JPEG1_DECODE, 45 VCN_5_0__SRCID__JPEG2_DECODE, 46 VCN_5_0__SRCID__JPEG3_DECODE, 47 VCN_5_0__SRCID__JPEG4_DECODE, 48 VCN_5_0__SRCID__JPEG5_DECODE, 49 VCN_5_0__SRCID__JPEG6_DECODE, 50 VCN_5_0__SRCID__JPEG7_DECODE, 51 VCN_5_0__SRCID__JPEG8_DECODE, 52 VCN_5_0__SRCID__JPEG9_DECODE, 53 }; 54 55 static int jpeg_v5_0_1_core_reg_offset(u32 pipe) 56 { 57 if (pipe <= AMDGPU_MAX_JPEG_RINGS_4_0_3) 58 return ((0x40 * pipe) - 0xc80); 59 else 60 return ((0x40 * pipe) - 0x440); 61 } 62 63 /** 64 * jpeg_v5_0_1_early_init - set function pointers 65 * 66 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 67 * 68 * Set ring and irq function pointers 69 */ 70 static int jpeg_v5_0_1_early_init(struct amdgpu_ip_block *ip_block) 71 { 72 struct amdgpu_device *adev = ip_block->adev; 73 74 if (!adev->jpeg.num_jpeg_inst || adev->jpeg.num_jpeg_inst > AMDGPU_MAX_JPEG_INSTANCES) 75 return -ENOENT; 76 77 adev->jpeg.num_jpeg_rings = AMDGPU_MAX_JPEG_RINGS; 78 jpeg_v5_0_1_set_dec_ring_funcs(adev); 79 jpeg_v5_0_1_set_irq_funcs(adev); 80 81 return 0; 82 } 83 84 /** 85 * jpeg_v5_0_1_sw_init - sw init for JPEG block 86 * 87 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 88 * 89 * Load firmware and sw initialization 90 */ 91 static int jpeg_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block) 92 { 93 struct amdgpu_device *adev = ip_block->adev; 94 struct amdgpu_ring *ring; 95 int i, j, r, jpeg_inst; 96 97 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 98 /* JPEG TRAP */ 99 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 100 amdgpu_ih_srcid_jpeg[j], &adev->jpeg.inst->irq); 101 if (r) 102 return r; 103 } 104 105 r = amdgpu_jpeg_sw_init(adev); 106 if (r) 107 return r; 108 109 r = amdgpu_jpeg_resume(adev); 110 if (r) 111 return r; 112 113 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 114 jpeg_inst = GET_INST(JPEG, i); 115 116 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 117 ring = &adev->jpeg.inst[i].ring_dec[j]; 118 ring->use_doorbell = false; 119 ring->vm_hub = AMDGPU_MMHUB0(adev->jpeg.inst[i].aid_id); 120 if (!amdgpu_sriov_vf(adev)) { 121 ring->doorbell_index = 122 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 123 1 + j + 11 * jpeg_inst; 124 } else { 125 if (j < 4) 126 ring->doorbell_index = 127 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 128 4 + j + 32 * jpeg_inst; 129 else 130 ring->doorbell_index = 131 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 132 8 + j + 32 * jpeg_inst; 133 } 134 sprintf(ring->name, "jpeg_dec_%d.%d", adev->jpeg.inst[i].aid_id, j); 135 r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0, 136 AMDGPU_RING_PRIO_DEFAULT, NULL); 137 if (r) 138 return r; 139 140 adev->jpeg.internal.jpeg_pitch[j] = 141 regUVD_JRBC0_UVD_JRBC_SCRATCH0_INTERNAL_OFFSET; 142 adev->jpeg.inst[i].external.jpeg_pitch[j] = 143 SOC15_REG_OFFSET1(JPEG, jpeg_inst, regUVD_JRBC_SCRATCH0, 144 (j ? jpeg_v5_0_1_core_reg_offset(j) : 0)); 145 } 146 } 147 148 return 0; 149 } 150 151 /** 152 * jpeg_v5_0_1_sw_fini - sw fini for JPEG block 153 * 154 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 155 * 156 * JPEG suspend and free up sw allocation 157 */ 158 static int jpeg_v5_0_1_sw_fini(struct amdgpu_ip_block *ip_block) 159 { 160 struct amdgpu_device *adev = ip_block->adev; 161 int r; 162 163 r = amdgpu_jpeg_suspend(adev); 164 if (r) 165 return r; 166 167 r = amdgpu_jpeg_sw_fini(adev); 168 169 return r; 170 } 171 172 /** 173 * jpeg_v5_0_1_hw_init - start and test JPEG block 174 * 175 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 176 * 177 */ 178 static int jpeg_v5_0_1_hw_init(struct amdgpu_ip_block *ip_block) 179 { 180 struct amdgpu_device *adev = ip_block->adev; 181 struct amdgpu_ring *ring; 182 int i, j, r, jpeg_inst; 183 184 if (amdgpu_sriov_vf(adev)) { 185 /* jpeg_v5_0_1_start_sriov(adev); */ 186 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 187 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 188 ring = &adev->jpeg.inst[i].ring_dec[j]; 189 ring->wptr = 0; 190 ring->wptr_old = 0; 191 jpeg_v5_0_1_dec_ring_set_wptr(ring); 192 ring->sched.ready = true; 193 } 194 } 195 return 0; 196 } 197 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 198 jpeg_inst = GET_INST(JPEG, i); 199 ring = adev->jpeg.inst[i].ring_dec; 200 if (ring->use_doorbell) 201 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, 202 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 11 * jpeg_inst, 203 adev->jpeg.inst[i].aid_id); 204 205 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 206 ring = &adev->jpeg.inst[i].ring_dec[j]; 207 if (ring->use_doorbell) 208 WREG32_SOC15_OFFSET(VCN, GET_INST(VCN, i), regVCN_JPEG_DB_CTRL, 209 (ring->pipe ? (ring->pipe - 0x15) : 0), 210 ring->doorbell_index << 211 VCN_JPEG_DB_CTRL__OFFSET__SHIFT | 212 VCN_JPEG_DB_CTRL__EN_MASK); 213 r = amdgpu_ring_test_helper(ring); 214 if (r) 215 return r; 216 } 217 } 218 219 return 0; 220 } 221 222 /** 223 * jpeg_v5_0_1_hw_fini - stop the hardware block 224 * 225 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 226 * 227 * Stop the JPEG block, mark ring as not ready any more 228 */ 229 static int jpeg_v5_0_1_hw_fini(struct amdgpu_ip_block *ip_block) 230 { 231 struct amdgpu_device *adev = ip_block->adev; 232 int ret = 0; 233 234 cancel_delayed_work_sync(&adev->jpeg.idle_work); 235 236 if (adev->jpeg.cur_state != AMD_PG_STATE_GATE) 237 ret = jpeg_v5_0_1_set_powergating_state(ip_block, AMD_PG_STATE_GATE); 238 239 return ret; 240 } 241 242 /** 243 * jpeg_v5_0_1_suspend - suspend JPEG block 244 * 245 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 246 * 247 * HW fini and suspend JPEG block 248 */ 249 static int jpeg_v5_0_1_suspend(struct amdgpu_ip_block *ip_block) 250 { 251 struct amdgpu_device *adev = ip_block->adev; 252 int r; 253 254 r = jpeg_v5_0_1_hw_fini(ip_block); 255 if (r) 256 return r; 257 258 r = amdgpu_jpeg_suspend(adev); 259 260 return r; 261 } 262 263 /** 264 * jpeg_v5_0_1_resume - resume JPEG block 265 * 266 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 267 * 268 * Resume firmware and hw init JPEG block 269 */ 270 static int jpeg_v5_0_1_resume(struct amdgpu_ip_block *ip_block) 271 { 272 struct amdgpu_device *adev = ip_block->adev; 273 int r; 274 275 r = amdgpu_jpeg_resume(adev); 276 if (r) 277 return r; 278 279 r = jpeg_v5_0_1_hw_init(ip_block); 280 281 return r; 282 } 283 284 static int jpeg_v5_0_1_disable_antihang(struct amdgpu_device *adev, int inst_idx) 285 { 286 int jpeg_inst; 287 288 jpeg_inst = GET_INST(JPEG, inst_idx); 289 /* disable anti hang mechanism */ 290 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0, 291 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); 292 293 /* keep the JPEG in static PG mode */ 294 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0, 295 ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK); 296 297 return 0; 298 } 299 300 static int jpeg_v5_0_1_enable_antihang(struct amdgpu_device *adev, int inst_idx) 301 { 302 int jpeg_inst; 303 304 jpeg_inst = GET_INST(JPEG, inst_idx); 305 /* enable anti hang mechanism */ 306 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 307 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK, 308 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); 309 310 return 0; 311 } 312 313 /** 314 * jpeg_v5_0_1_start - start JPEG block 315 * 316 * @adev: amdgpu_device pointer 317 * 318 * Setup and start the JPEG block 319 */ 320 static int jpeg_v5_0_1_start(struct amdgpu_device *adev) 321 { 322 struct amdgpu_ring *ring; 323 int i, j, jpeg_inst, r; 324 325 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 326 jpeg_inst = GET_INST(JPEG, i); 327 328 /* disable antihang */ 329 r = jpeg_v5_0_1_disable_antihang(adev, i); 330 if (r) 331 return r; 332 333 /* MJPEG global tiling registers */ 334 WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG, 335 adev->gfx.config.gb_addr_config); 336 337 /* enable JMI channel */ 338 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL), 0, 339 ~UVD_JMI_CNTL__SOFT_RESET_MASK); 340 341 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 342 int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0); 343 u32 reg, data, mask; 344 345 ring = &adev->jpeg.inst[i].ring_dec[j]; 346 347 /* enable System Interrupt for JRBC */ 348 reg = SOC15_REG_OFFSET(JPEG, jpeg_inst, regJPEG_SYS_INT_EN); 349 if (j < AMDGPU_MAX_JPEG_RINGS_4_0_3) { 350 data = JPEG_SYS_INT_EN__DJRBC0_MASK << j; 351 mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << j); 352 WREG32_P(reg, data, mask); 353 } else { 354 data = JPEG_SYS_INT_EN__DJRBC0_MASK << (j+12); 355 mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << (j+12)); 356 WREG32_P(reg, data, mask); 357 } 358 359 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 360 regUVD_LMI_JRBC_RB_VMID, 361 reg_offset, 0); 362 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 363 regUVD_JRBC_RB_CNTL, 364 reg_offset, 365 (0x00000001L | 0x00000002L)); 366 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 367 regUVD_LMI_JRBC_RB_64BIT_BAR_LOW, 368 reg_offset, lower_32_bits(ring->gpu_addr)); 369 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 370 regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, 371 reg_offset, upper_32_bits(ring->gpu_addr)); 372 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 373 regUVD_JRBC_RB_RPTR, 374 reg_offset, 0); 375 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 376 regUVD_JRBC_RB_WPTR, 377 reg_offset, 0); 378 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 379 regUVD_JRBC_RB_CNTL, 380 reg_offset, 0x00000002L); 381 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 382 regUVD_JRBC_RB_SIZE, 383 reg_offset, ring->ring_size / 4); 384 ring->wptr = RREG32_SOC15_OFFSET(JPEG, jpeg_inst, regUVD_JRBC_RB_WPTR, 385 reg_offset); 386 } 387 } 388 389 return 0; 390 } 391 392 /** 393 * jpeg_v5_0_1_stop - stop JPEG block 394 * 395 * @adev: amdgpu_device pointer 396 * 397 * stop the JPEG block 398 */ 399 static int jpeg_v5_0_1_stop(struct amdgpu_device *adev) 400 { 401 int i, jpeg_inst, r; 402 403 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 404 jpeg_inst = GET_INST(JPEG, i); 405 /* reset JMI */ 406 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL), 407 UVD_JMI_CNTL__SOFT_RESET_MASK, 408 ~UVD_JMI_CNTL__SOFT_RESET_MASK); 409 410 /* enable antihang */ 411 r = jpeg_v5_0_1_enable_antihang(adev, i); 412 if (r) 413 return r; 414 } 415 416 return 0; 417 } 418 419 /** 420 * jpeg_v5_0_1_dec_ring_get_rptr - get read pointer 421 * 422 * @ring: amdgpu_ring pointer 423 * 424 * Returns the current hardware read pointer 425 */ 426 static uint64_t jpeg_v5_0_1_dec_ring_get_rptr(struct amdgpu_ring *ring) 427 { 428 struct amdgpu_device *adev = ring->adev; 429 430 return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_RPTR, 431 ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0); 432 } 433 434 /** 435 * jpeg_v5_0_1_dec_ring_get_wptr - get write pointer 436 * 437 * @ring: amdgpu_ring pointer 438 * 439 * Returns the current hardware write pointer 440 */ 441 static uint64_t jpeg_v5_0_1_dec_ring_get_wptr(struct amdgpu_ring *ring) 442 { 443 struct amdgpu_device *adev = ring->adev; 444 445 if (ring->use_doorbell) 446 return adev->wb.wb[ring->wptr_offs]; 447 448 return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_WPTR, 449 ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0); 450 } 451 452 /** 453 * jpeg_v5_0_1_dec_ring_set_wptr - set write pointer 454 * 455 * @ring: amdgpu_ring pointer 456 * 457 * Commits the write pointer to the hardware 458 */ 459 static void jpeg_v5_0_1_dec_ring_set_wptr(struct amdgpu_ring *ring) 460 { 461 struct amdgpu_device *adev = ring->adev; 462 463 if (ring->use_doorbell) { 464 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr); 465 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 466 } else { 467 WREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), 468 regUVD_JRBC_RB_WPTR, 469 (ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0), 470 lower_32_bits(ring->wptr)); 471 } 472 } 473 474 static bool jpeg_v5_0_1_is_idle(void *handle) 475 { 476 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 477 bool ret = false; 478 int i, j; 479 480 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 481 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 482 int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0); 483 484 ret &= ((RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, i), 485 regUVD_JRBC_STATUS, reg_offset) & 486 UVD_JRBC_STATUS__RB_JOB_DONE_MASK) == 487 UVD_JRBC_STATUS__RB_JOB_DONE_MASK); 488 } 489 } 490 491 return ret; 492 } 493 494 static int jpeg_v5_0_1_wait_for_idle(struct amdgpu_ip_block *ip_block) 495 { 496 struct amdgpu_device *adev = ip_block->adev; 497 int ret = 0; 498 int i, j; 499 500 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 501 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 502 int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0); 503 504 ret &= SOC15_WAIT_ON_RREG_OFFSET(JPEG, GET_INST(JPEG, i), 505 regUVD_JRBC_STATUS, reg_offset, 506 UVD_JRBC_STATUS__RB_JOB_DONE_MASK, 507 UVD_JRBC_STATUS__RB_JOB_DONE_MASK); 508 } 509 } 510 return ret; 511 } 512 513 static int jpeg_v5_0_1_set_clockgating_state(struct amdgpu_ip_block *ip_block, 514 enum amd_clockgating_state state) 515 { 516 struct amdgpu_device *adev = ip_block->adev; 517 bool enable = (state == AMD_CG_STATE_GATE) ? true : false; 518 519 int i; 520 521 if (!enable) 522 return 0; 523 524 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 525 if (!jpeg_v5_0_1_is_idle(adev)) 526 return -EBUSY; 527 } 528 529 return 0; 530 } 531 532 static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block, 533 enum amd_powergating_state state) 534 { 535 struct amdgpu_device *adev = ip_block->adev; 536 int ret; 537 538 if (state == adev->jpeg.cur_state) 539 return 0; 540 541 if (state == AMD_PG_STATE_GATE) 542 ret = jpeg_v5_0_1_stop(adev); 543 else 544 ret = jpeg_v5_0_1_start(adev); 545 546 if (!ret) 547 adev->jpeg.cur_state = state; 548 549 return ret; 550 } 551 552 static int jpeg_v5_0_1_set_interrupt_state(struct amdgpu_device *adev, 553 struct amdgpu_irq_src *source, 554 unsigned int type, 555 enum amdgpu_interrupt_state state) 556 { 557 return 0; 558 } 559 560 static int jpeg_v5_0_1_process_interrupt(struct amdgpu_device *adev, 561 struct amdgpu_irq_src *source, 562 struct amdgpu_iv_entry *entry) 563 { 564 u32 i, inst; 565 566 i = node_id_to_phys_map[entry->node_id]; 567 DRM_DEV_DEBUG(adev->dev, "IH: JPEG TRAP\n"); 568 569 for (inst = 0; inst < adev->jpeg.num_jpeg_inst; ++inst) 570 if (adev->jpeg.inst[inst].aid_id == i) 571 break; 572 573 if (inst >= adev->jpeg.num_jpeg_inst) { 574 dev_WARN_ONCE(adev->dev, 1, 575 "Interrupt received for unknown JPEG instance %d", 576 entry->node_id); 577 return 0; 578 } 579 580 switch (entry->src_id) { 581 case VCN_5_0__SRCID__JPEG_DECODE: 582 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[0]); 583 break; 584 case VCN_5_0__SRCID__JPEG1_DECODE: 585 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[1]); 586 break; 587 case VCN_5_0__SRCID__JPEG2_DECODE: 588 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[2]); 589 break; 590 case VCN_5_0__SRCID__JPEG3_DECODE: 591 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[3]); 592 break; 593 case VCN_5_0__SRCID__JPEG4_DECODE: 594 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[4]); 595 break; 596 case VCN_5_0__SRCID__JPEG5_DECODE: 597 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[5]); 598 break; 599 case VCN_5_0__SRCID__JPEG6_DECODE: 600 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[6]); 601 break; 602 case VCN_5_0__SRCID__JPEG7_DECODE: 603 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[7]); 604 break; 605 case VCN_5_0__SRCID__JPEG8_DECODE: 606 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[8]); 607 break; 608 case VCN_5_0__SRCID__JPEG9_DECODE: 609 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[9]); 610 break; 611 default: 612 DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n", 613 entry->src_id, entry->src_data[0]); 614 break; 615 } 616 617 return 0; 618 } 619 620 static const struct amd_ip_funcs jpeg_v5_0_1_ip_funcs = { 621 .name = "jpeg_v5_0_1", 622 .early_init = jpeg_v5_0_1_early_init, 623 .late_init = NULL, 624 .sw_init = jpeg_v5_0_1_sw_init, 625 .sw_fini = jpeg_v5_0_1_sw_fini, 626 .hw_init = jpeg_v5_0_1_hw_init, 627 .hw_fini = jpeg_v5_0_1_hw_fini, 628 .suspend = jpeg_v5_0_1_suspend, 629 .resume = jpeg_v5_0_1_resume, 630 .is_idle = jpeg_v5_0_1_is_idle, 631 .wait_for_idle = jpeg_v5_0_1_wait_for_idle, 632 .check_soft_reset = NULL, 633 .pre_soft_reset = NULL, 634 .soft_reset = NULL, 635 .post_soft_reset = NULL, 636 .set_clockgating_state = jpeg_v5_0_1_set_clockgating_state, 637 .set_powergating_state = jpeg_v5_0_1_set_powergating_state, 638 .dump_ip_state = NULL, 639 .print_ip_state = NULL, 640 }; 641 642 static const struct amdgpu_ring_funcs jpeg_v5_0_1_dec_ring_vm_funcs = { 643 .type = AMDGPU_RING_TYPE_VCN_JPEG, 644 .align_mask = 0xf, 645 .get_rptr = jpeg_v5_0_1_dec_ring_get_rptr, 646 .get_wptr = jpeg_v5_0_1_dec_ring_get_wptr, 647 .set_wptr = jpeg_v5_0_1_dec_ring_set_wptr, 648 .emit_frame_size = 649 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + 650 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + 651 8 + /* jpeg_v5_0_1_dec_ring_emit_vm_flush */ 652 22 + 22 + /* jpeg_v5_0_1_dec_ring_emit_fence x2 vm fence */ 653 8 + 16, 654 .emit_ib_size = 22, /* jpeg_v5_0_1_dec_ring_emit_ib */ 655 .emit_ib = jpeg_v4_0_3_dec_ring_emit_ib, 656 .emit_fence = jpeg_v4_0_3_dec_ring_emit_fence, 657 .emit_vm_flush = jpeg_v4_0_3_dec_ring_emit_vm_flush, 658 .test_ring = amdgpu_jpeg_dec_ring_test_ring, 659 .test_ib = amdgpu_jpeg_dec_ring_test_ib, 660 .insert_nop = jpeg_v4_0_3_dec_ring_nop, 661 .insert_start = jpeg_v4_0_3_dec_ring_insert_start, 662 .insert_end = jpeg_v4_0_3_dec_ring_insert_end, 663 .pad_ib = amdgpu_ring_generic_pad_ib, 664 .begin_use = amdgpu_jpeg_ring_begin_use, 665 .end_use = amdgpu_jpeg_ring_end_use, 666 .emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg, 667 .emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait, 668 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 669 }; 670 671 static void jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device *adev) 672 { 673 int i, j, jpeg_inst; 674 675 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 676 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 677 adev->jpeg.inst[i].ring_dec[j].funcs = &jpeg_v5_0_1_dec_ring_vm_funcs; 678 adev->jpeg.inst[i].ring_dec[j].me = i; 679 adev->jpeg.inst[i].ring_dec[j].pipe = j; 680 } 681 jpeg_inst = GET_INST(JPEG, i); 682 adev->jpeg.inst[i].aid_id = 683 jpeg_inst / adev->jpeg.num_inst_per_aid; 684 } 685 } 686 687 static const struct amdgpu_irq_src_funcs jpeg_v5_0_1_irq_funcs = { 688 .set = jpeg_v5_0_1_set_interrupt_state, 689 .process = jpeg_v5_0_1_process_interrupt, 690 }; 691 692 static void jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device *adev) 693 { 694 int i; 695 696 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) 697 adev->jpeg.inst->irq.num_types += adev->jpeg.num_jpeg_rings; 698 699 adev->jpeg.inst->irq.funcs = &jpeg_v5_0_1_irq_funcs; 700 } 701 702 const struct amdgpu_ip_block_version jpeg_v5_0_1_ip_block = { 703 .type = AMD_IP_BLOCK_TYPE_JPEG, 704 .major = 5, 705 .minor = 0, 706 .rev = 1, 707 .funcs = &jpeg_v5_0_1_ip_funcs, 708 }; 709