1 /* 2 * Copyright 2023 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 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 31 #include "vcn/vcn_5_0_0_offset.h" 32 #include "vcn/vcn_5_0_0_sh_mask.h" 33 #include "ivsrcid/vcn/irqsrcs_vcn_4_0.h" 34 #include "jpeg_v5_0_0.h" 35 36 static void jpeg_v5_0_0_set_dec_ring_funcs(struct amdgpu_device *adev); 37 static void jpeg_v5_0_0_set_irq_funcs(struct amdgpu_device *adev); 38 static int jpeg_v5_0_0_set_powergating_state(void *handle, 39 enum amd_powergating_state state); 40 41 /** 42 * jpeg_v5_0_0_early_init - set function pointers 43 * 44 * @handle: amdgpu_device pointer 45 * 46 * Set ring and irq function pointers 47 */ 48 static int jpeg_v5_0_0_early_init(void *handle) 49 { 50 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 51 52 adev->jpeg.num_jpeg_inst = 1; 53 adev->jpeg.num_jpeg_rings = 1; 54 55 jpeg_v5_0_0_set_dec_ring_funcs(adev); 56 jpeg_v5_0_0_set_irq_funcs(adev); 57 58 return 0; 59 } 60 61 /** 62 * jpeg_v5_0_0_sw_init - sw init for JPEG block 63 * 64 * @handle: amdgpu_device pointer 65 * 66 * Load firmware and sw initialization 67 */ 68 static int jpeg_v5_0_0_sw_init(void *handle) 69 { 70 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 71 struct amdgpu_ring *ring; 72 int r; 73 74 /* JPEG TRAP */ 75 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 76 VCN_4_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq); 77 if (r) 78 return r; 79 80 r = amdgpu_jpeg_sw_init(adev); 81 if (r) 82 return r; 83 84 r = amdgpu_jpeg_resume(adev); 85 if (r) 86 return r; 87 88 ring = adev->jpeg.inst->ring_dec; 89 ring->use_doorbell = true; 90 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1; 91 ring->vm_hub = AMDGPU_MMHUB0(0); 92 93 sprintf(ring->name, "jpeg_dec"); 94 r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0, 95 AMDGPU_RING_PRIO_DEFAULT, NULL); 96 if (r) 97 return r; 98 99 adev->jpeg.internal.jpeg_pitch[0] = regUVD_JPEG_PITCH_INTERNAL_OFFSET; 100 adev->jpeg.inst->external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_PITCH); 101 102 return 0; 103 } 104 105 /** 106 * jpeg_v5_0_0_sw_fini - sw fini for JPEG block 107 * 108 * @handle: amdgpu_device pointer 109 * 110 * JPEG suspend and free up sw allocation 111 */ 112 static int jpeg_v5_0_0_sw_fini(void *handle) 113 { 114 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 115 int r; 116 117 r = amdgpu_jpeg_suspend(adev); 118 if (r) 119 return r; 120 121 r = amdgpu_jpeg_sw_fini(adev); 122 123 return r; 124 } 125 126 /** 127 * jpeg_v5_0_0_hw_init - start and test JPEG block 128 * 129 * @handle: amdgpu_device pointer 130 * 131 */ 132 static int jpeg_v5_0_0_hw_init(void *handle) 133 { 134 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 135 struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec; 136 int r; 137 138 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, 139 (adev->doorbell_index.vcn.vcn_ring0_1 << 1), 0); 140 141 /* Skip ring test because pause DPG is not implemented. */ 142 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) 143 return 0; 144 145 r = amdgpu_ring_test_helper(ring); 146 if (r) 147 return r; 148 149 return 0; 150 } 151 152 /** 153 * jpeg_v5_0_0_hw_fini - stop the hardware block 154 * 155 * @handle: amdgpu_device pointer 156 * 157 * Stop the JPEG block, mark ring as not ready any more 158 */ 159 static int jpeg_v5_0_0_hw_fini(void *handle) 160 { 161 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 162 163 cancel_delayed_work_sync(&adev->vcn.idle_work); 164 165 if (adev->jpeg.cur_state != AMD_PG_STATE_GATE && 166 RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS)) 167 jpeg_v5_0_0_set_powergating_state(adev, AMD_PG_STATE_GATE); 168 169 return 0; 170 } 171 172 /** 173 * jpeg_v5_0_0_suspend - suspend JPEG block 174 * 175 * @handle: amdgpu_device pointer 176 * 177 * HW fini and suspend JPEG block 178 */ 179 static int jpeg_v5_0_0_suspend(void *handle) 180 { 181 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 182 int r; 183 184 r = jpeg_v5_0_0_hw_fini(adev); 185 if (r) 186 return r; 187 188 r = amdgpu_jpeg_suspend(adev); 189 190 return r; 191 } 192 193 /** 194 * jpeg_v5_0_0_resume - resume JPEG block 195 * 196 * @handle: amdgpu_device pointer 197 * 198 * Resume firmware and hw init JPEG block 199 */ 200 static int jpeg_v5_0_0_resume(void *handle) 201 { 202 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 203 int r; 204 205 r = amdgpu_jpeg_resume(adev); 206 if (r) 207 return r; 208 209 r = jpeg_v5_0_0_hw_init(adev); 210 211 return r; 212 } 213 214 static void jpeg_v5_0_0_disable_clock_gating(struct amdgpu_device *adev) 215 { 216 uint32_t data = 0; 217 218 WREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE, data); 219 220 data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL); 221 data &= ~(JPEG_CGC_CTRL__JPEG0_DEC_MODE_MASK 222 | JPEG_CGC_CTRL__JPEG_ENC_MODE_MASK); 223 WREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL, data); 224 } 225 226 static void jpeg_v5_0_0_enable_clock_gating(struct amdgpu_device *adev) 227 { 228 uint32_t data = 0; 229 230 data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL); 231 232 data |= 1 << JPEG_CGC_CTRL__JPEG0_DEC_MODE__SHIFT; 233 WREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL, data); 234 235 data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE); 236 data |= (JPEG_CGC_GATE__JPEG0_DEC_MASK 237 |JPEG_CGC_GATE__JPEG_ENC_MASK 238 |JPEG_CGC_GATE__JMCIF_MASK 239 |JPEG_CGC_GATE__JRBBM_MASK); 240 WREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE, data); 241 } 242 243 static int jpeg_v5_0_0_disable_power_gating(struct amdgpu_device *adev) 244 { 245 uint32_t data = 0; 246 247 data = 1 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT; 248 WREG32_SOC15(JPEG, 0, regUVD_IPX_DLDO_CONFIG, data); 249 SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_IPX_DLDO_STATUS, 0, 250 UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK); 251 252 /* disable anti hang mechanism */ 253 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS), 0, 254 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); 255 256 return 0; 257 } 258 259 static int jpeg_v5_0_0_enable_power_gating(struct amdgpu_device *adev) 260 { 261 /* enable anti hang mechanism */ 262 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS), 263 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK, 264 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); 265 266 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) { 267 WREG32(SOC15_REG_OFFSET(JPEG, 0, regUVD_IPX_DLDO_CONFIG), 268 2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT); 269 SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_IPX_DLDO_STATUS, 270 1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT, 271 UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK); 272 } 273 274 return 0; 275 } 276 277 static void jpeg_engine_5_0_0_dpg_clock_gating_mode(struct amdgpu_device *adev, 278 int inst_idx, uint8_t indirect) 279 { 280 uint32_t data = 0; 281 282 // JPEG disable CGC 283 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) 284 data = 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 285 else 286 data = 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 287 288 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 289 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 290 291 if (indirect) { 292 ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_CGC_CTRL, data, indirect); 293 294 // Turn on All JPEG clocks 295 data = 0; 296 ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_CGC_GATE, data, indirect); 297 } else { 298 WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_CGC_CTRL, data, indirect); 299 300 // Turn on All JPEG clocks 301 data = 0; 302 WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_CGC_GATE, data, indirect); 303 } 304 } 305 306 /** 307 * jpeg_v5_0_0_start_dpg_mode - Jpeg start with dpg mode 308 * 309 * @adev: amdgpu_device pointer 310 * @inst_idx: instance number index 311 * @indirect: indirectly write sram 312 * 313 * Start JPEG block with dpg mode 314 */ 315 static int jpeg_v5_0_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect) 316 { 317 struct amdgpu_ring *ring = adev->jpeg.inst[inst_idx].ring_dec; 318 uint32_t reg_data = 0; 319 320 jpeg_v5_0_0_enable_power_gating(adev); 321 322 // enable dynamic power gating mode 323 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS); 324 reg_data |= UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK; 325 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data); 326 327 if (indirect) 328 adev->jpeg.inst[inst_idx].dpg_sram_curr_addr = 329 (uint32_t *)adev->jpeg.inst[inst_idx].dpg_sram_cpu_addr; 330 331 jpeg_engine_5_0_0_dpg_clock_gating_mode(adev, inst_idx, indirect); 332 333 /* MJPEG global tiling registers */ 334 if (indirect) 335 ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_DEC_GFX10_ADDR_CONFIG, 336 adev->gfx.config.gb_addr_config, indirect); 337 else 338 WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_DEC_GFX10_ADDR_CONFIG, 339 adev->gfx.config.gb_addr_config, 1); 340 341 /* enable System Interrupt for JRBC */ 342 if (indirect) 343 ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_SYS_INT_EN, 344 JPEG_SYS_INT_EN__DJRBC0_MASK, indirect); 345 else 346 WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_SYS_INT_EN, 347 JPEG_SYS_INT_EN__DJRBC0_MASK, 1); 348 349 if (indirect) { 350 /* add nop to workaround PSP size check */ 351 ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipUVD_NO_OP, 0, indirect); 352 353 amdgpu_jpeg_psp_update_sram(adev, inst_idx, 0); 354 } 355 356 WREG32_SOC15(VCN, 0, regVCN_JPEG_DB_CTRL, 357 ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT | 358 VCN_JPEG_DB_CTRL__EN_MASK); 359 360 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_VMID, 0); 361 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L)); 362 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW, 363 lower_32_bits(ring->gpu_addr)); 364 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, 365 upper_32_bits(ring->gpu_addr)); 366 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_RPTR, 0); 367 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR, 0); 368 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, 0x00000002L); 369 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_SIZE, ring->ring_size / 4); 370 ring->wptr = RREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR); 371 372 return 0; 373 } 374 375 /** 376 * jpeg_v5_0_0_stop_dpg_mode - Jpeg stop with dpg mode 377 * 378 * @adev: amdgpu_device pointer 379 * @inst_idx: instance number index 380 * 381 * Stop JPEG block with dpg mode 382 */ 383 static void jpeg_v5_0_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx) 384 { 385 uint32_t reg_data = 0; 386 387 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS); 388 reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK; 389 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data); 390 } 391 392 /** 393 * jpeg_v5_0_0_start - start JPEG block 394 * 395 * @adev: amdgpu_device pointer 396 * 397 * Setup and start the JPEG block 398 */ 399 static int jpeg_v5_0_0_start(struct amdgpu_device *adev) 400 { 401 struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec; 402 int r; 403 404 if (adev->pm.dpm_enabled) 405 amdgpu_dpm_enable_jpeg(adev, true); 406 407 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) { 408 r = jpeg_v5_0_0_start_dpg_mode(adev, 0, adev->jpeg.indirect_sram); 409 return r; 410 } 411 412 /* disable power gating */ 413 r = jpeg_v5_0_0_disable_power_gating(adev); 414 if (r) 415 return r; 416 417 /* JPEG disable CGC */ 418 jpeg_v5_0_0_disable_clock_gating(adev); 419 420 /* MJPEG global tiling registers */ 421 WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG, 422 adev->gfx.config.gb_addr_config); 423 424 /* enable JMI channel */ 425 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL), 0, 426 ~UVD_JMI_CNTL__SOFT_RESET_MASK); 427 428 /* enable System Interrupt for JRBC */ 429 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regJPEG_SYS_INT_EN), 430 JPEG_SYS_INT_EN__DJRBC0_MASK, 431 ~JPEG_SYS_INT_EN__DJRBC0_MASK); 432 433 WREG32_SOC15(VCN, 0, regVCN_JPEG_DB_CTRL, 434 ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT | 435 VCN_JPEG_DB_CTRL__EN_MASK); 436 437 WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_VMID, 0); 438 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L)); 439 WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW, 440 lower_32_bits(ring->gpu_addr)); 441 WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, 442 upper_32_bits(ring->gpu_addr)); 443 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_RPTR, 0); 444 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR, 0); 445 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_CNTL, 0x00000002L); 446 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_SIZE, ring->ring_size / 4); 447 ring->wptr = RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR); 448 449 return 0; 450 } 451 452 /** 453 * jpeg_v5_0_0_stop - stop JPEG block 454 * 455 * @adev: amdgpu_device pointer 456 * 457 * stop the JPEG block 458 */ 459 static int jpeg_v5_0_0_stop(struct amdgpu_device *adev) 460 { 461 int r; 462 463 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) { 464 jpeg_v5_0_0_stop_dpg_mode(adev, 0); 465 } else { 466 467 /* reset JMI */ 468 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL), 469 UVD_JMI_CNTL__SOFT_RESET_MASK, 470 ~UVD_JMI_CNTL__SOFT_RESET_MASK); 471 472 jpeg_v5_0_0_enable_clock_gating(adev); 473 474 /* enable power gating */ 475 r = jpeg_v5_0_0_enable_power_gating(adev); 476 if (r) 477 return r; 478 } 479 480 if (adev->pm.dpm_enabled) 481 amdgpu_dpm_enable_jpeg(adev, false); 482 483 return 0; 484 } 485 486 /** 487 * jpeg_v5_0_0_dec_ring_get_rptr - get read pointer 488 * 489 * @ring: amdgpu_ring pointer 490 * 491 * Returns the current hardware read pointer 492 */ 493 static uint64_t jpeg_v5_0_0_dec_ring_get_rptr(struct amdgpu_ring *ring) 494 { 495 struct amdgpu_device *adev = ring->adev; 496 497 return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_RPTR); 498 } 499 500 /** 501 * jpeg_v5_0_0_dec_ring_get_wptr - get write pointer 502 * 503 * @ring: amdgpu_ring pointer 504 * 505 * Returns the current hardware write pointer 506 */ 507 static uint64_t jpeg_v5_0_0_dec_ring_get_wptr(struct amdgpu_ring *ring) 508 { 509 struct amdgpu_device *adev = ring->adev; 510 511 if (ring->use_doorbell) 512 return *ring->wptr_cpu_addr; 513 else 514 return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR); 515 } 516 517 /** 518 * jpeg_v5_0_0_dec_ring_set_wptr - set write pointer 519 * 520 * @ring: amdgpu_ring pointer 521 * 522 * Commits the write pointer to the hardware 523 */ 524 static void jpeg_v5_0_0_dec_ring_set_wptr(struct amdgpu_ring *ring) 525 { 526 struct amdgpu_device *adev = ring->adev; 527 528 if (ring->use_doorbell) { 529 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr); 530 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 531 } else { 532 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); 533 } 534 } 535 536 static bool jpeg_v5_0_0_is_idle(void *handle) 537 { 538 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 539 int ret = 1; 540 541 ret &= (((RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS) & 542 UVD_JRBC_STATUS__RB_JOB_DONE_MASK) == 543 UVD_JRBC_STATUS__RB_JOB_DONE_MASK)); 544 545 return ret; 546 } 547 548 static int jpeg_v5_0_0_wait_for_idle(void *handle) 549 { 550 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 551 552 return SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_JRBC_STATUS, 553 UVD_JRBC_STATUS__RB_JOB_DONE_MASK, 554 UVD_JRBC_STATUS__RB_JOB_DONE_MASK); 555 } 556 557 static int jpeg_v5_0_0_set_clockgating_state(void *handle, 558 enum amd_clockgating_state state) 559 { 560 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 561 bool enable = (state == AMD_CG_STATE_GATE) ? true : false; 562 563 if (enable) { 564 if (!jpeg_v5_0_0_is_idle(handle)) 565 return -EBUSY; 566 jpeg_v5_0_0_enable_clock_gating(adev); 567 } else { 568 jpeg_v5_0_0_disable_clock_gating(adev); 569 } 570 571 return 0; 572 } 573 574 static int jpeg_v5_0_0_set_powergating_state(void *handle, 575 enum amd_powergating_state state) 576 { 577 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 578 int ret; 579 580 if (state == adev->jpeg.cur_state) 581 return 0; 582 583 if (state == AMD_PG_STATE_GATE) 584 ret = jpeg_v5_0_0_stop(adev); 585 else 586 ret = jpeg_v5_0_0_start(adev); 587 588 if (!ret) 589 adev->jpeg.cur_state = state; 590 591 return ret; 592 } 593 594 static int jpeg_v5_0_0_set_interrupt_state(struct amdgpu_device *adev, 595 struct amdgpu_irq_src *source, 596 unsigned int type, 597 enum amdgpu_interrupt_state state) 598 { 599 return 0; 600 } 601 602 static int jpeg_v5_0_0_process_interrupt(struct amdgpu_device *adev, 603 struct amdgpu_irq_src *source, 604 struct amdgpu_iv_entry *entry) 605 { 606 DRM_DEBUG("IH: JPEG TRAP\n"); 607 608 switch (entry->src_id) { 609 case VCN_4_0__SRCID__JPEG_DECODE: 610 amdgpu_fence_process(adev->jpeg.inst->ring_dec); 611 break; 612 default: 613 DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n", 614 entry->src_id, entry->src_data[0]); 615 break; 616 } 617 618 return 0; 619 } 620 621 static const struct amd_ip_funcs jpeg_v5_0_0_ip_funcs = { 622 .name = "jpeg_v5_0_0", 623 .early_init = jpeg_v5_0_0_early_init, 624 .late_init = NULL, 625 .sw_init = jpeg_v5_0_0_sw_init, 626 .sw_fini = jpeg_v5_0_0_sw_fini, 627 .hw_init = jpeg_v5_0_0_hw_init, 628 .hw_fini = jpeg_v5_0_0_hw_fini, 629 .suspend = jpeg_v5_0_0_suspend, 630 .resume = jpeg_v5_0_0_resume, 631 .is_idle = jpeg_v5_0_0_is_idle, 632 .wait_for_idle = jpeg_v5_0_0_wait_for_idle, 633 .check_soft_reset = NULL, 634 .pre_soft_reset = NULL, 635 .soft_reset = NULL, 636 .post_soft_reset = NULL, 637 .set_clockgating_state = jpeg_v5_0_0_set_clockgating_state, 638 .set_powergating_state = jpeg_v5_0_0_set_powergating_state, 639 .dump_ip_state = NULL, 640 .print_ip_state = NULL, 641 }; 642 643 static const struct amdgpu_ring_funcs jpeg_v5_0_0_dec_ring_vm_funcs = { 644 .type = AMDGPU_RING_TYPE_VCN_JPEG, 645 .align_mask = 0xf, 646 .get_rptr = jpeg_v5_0_0_dec_ring_get_rptr, 647 .get_wptr = jpeg_v5_0_0_dec_ring_get_wptr, 648 .set_wptr = jpeg_v5_0_0_dec_ring_set_wptr, 649 .emit_frame_size = 650 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + 651 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + 652 8 + /* jpeg_v5_0_0_dec_ring_emit_vm_flush */ 653 22 + 22 + /* jpeg_v5_0_0_dec_ring_emit_fence x2 vm fence */ 654 8 + 16, 655 .emit_ib_size = 22, /* jpeg_v5_0_0_dec_ring_emit_ib */ 656 .emit_ib = jpeg_v4_0_3_dec_ring_emit_ib, 657 .emit_fence = jpeg_v4_0_3_dec_ring_emit_fence, 658 .emit_vm_flush = jpeg_v4_0_3_dec_ring_emit_vm_flush, 659 .test_ring = amdgpu_jpeg_dec_ring_test_ring, 660 .test_ib = amdgpu_jpeg_dec_ring_test_ib, 661 .insert_nop = jpeg_v4_0_3_dec_ring_nop, 662 .insert_start = jpeg_v4_0_3_dec_ring_insert_start, 663 .insert_end = jpeg_v4_0_3_dec_ring_insert_end, 664 .pad_ib = amdgpu_ring_generic_pad_ib, 665 .begin_use = amdgpu_jpeg_ring_begin_use, 666 .end_use = amdgpu_jpeg_ring_end_use, 667 .emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg, 668 .emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait, 669 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 670 }; 671 672 static void jpeg_v5_0_0_set_dec_ring_funcs(struct amdgpu_device *adev) 673 { 674 adev->jpeg.inst->ring_dec->funcs = &jpeg_v5_0_0_dec_ring_vm_funcs; 675 } 676 677 static const struct amdgpu_irq_src_funcs jpeg_v5_0_0_irq_funcs = { 678 .set = jpeg_v5_0_0_set_interrupt_state, 679 .process = jpeg_v5_0_0_process_interrupt, 680 }; 681 682 static void jpeg_v5_0_0_set_irq_funcs(struct amdgpu_device *adev) 683 { 684 adev->jpeg.inst->irq.num_types = 1; 685 adev->jpeg.inst->irq.funcs = &jpeg_v5_0_0_irq_funcs; 686 } 687 688 const struct amdgpu_ip_block_version jpeg_v5_0_0_ip_block = { 689 .type = AMD_IP_BLOCK_TYPE_JPEG, 690 .major = 5, 691 .minor = 0, 692 .rev = 0, 693 .funcs = &jpeg_v5_0_0_ip_funcs, 694 }; 695