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_v2_0.h" 30 #include "jpeg_v4_0_5.h" 31 #include "mmsch_v4_0.h" 32 33 #include "vcn/vcn_4_0_5_offset.h" 34 #include "vcn/vcn_4_0_5_sh_mask.h" 35 #include "ivsrcid/vcn/irqsrcs_vcn_4_0.h" 36 37 #define mmUVD_DPG_LMA_CTL regUVD_DPG_LMA_CTL 38 #define mmUVD_DPG_LMA_CTL_BASE_IDX regUVD_DPG_LMA_CTL_BASE_IDX 39 #define mmUVD_DPG_LMA_DATA regUVD_DPG_LMA_DATA 40 #define mmUVD_DPG_LMA_DATA_BASE_IDX regUVD_DPG_LMA_DATA_BASE_IDX 41 42 #define regUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f 43 #define regJPEG_DEC_GFX10_ADDR_CONFIG_INTERNAL_OFFSET 0x4026 44 #define regJPEG_SYS_INT_EN_INTERNAL_OFFSET 0x4141 45 #define regJPEG_CGC_CTRL_INTERNAL_OFFSET 0x4161 46 #define regJPEG_CGC_GATE_INTERNAL_OFFSET 0x4160 47 #define regUVD_NO_OP_INTERNAL_OFFSET 0x0029 48 49 static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev); 50 static void jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device *adev); 51 static int jpeg_v4_0_5_set_powergating_state(void *handle, 52 enum amd_powergating_state state); 53 54 static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring); 55 56 /** 57 * jpeg_v4_0_5_early_init - set function pointers 58 * 59 * @handle: amdgpu_device pointer 60 * 61 * Set ring and irq function pointers 62 */ 63 static int jpeg_v4_0_5_early_init(void *handle) 64 { 65 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 66 67 68 adev->jpeg.num_jpeg_inst = 1; 69 adev->jpeg.num_jpeg_rings = 1; 70 71 jpeg_v4_0_5_set_dec_ring_funcs(adev); 72 jpeg_v4_0_5_set_irq_funcs(adev); 73 74 return 0; 75 } 76 77 /** 78 * jpeg_v4_0_5_sw_init - sw init for JPEG block 79 * 80 * @handle: amdgpu_device pointer 81 * 82 * Load firmware and sw initialization 83 */ 84 static int jpeg_v4_0_5_sw_init(void *handle) 85 { 86 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 87 struct amdgpu_ring *ring; 88 int r; 89 90 /* JPEG TRAP */ 91 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 92 VCN_4_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq); 93 if (r) 94 return r; 95 96 /* JPEG DJPEG POISON EVENT */ 97 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 98 VCN_4_0__SRCID_DJPEG0_POISON, &adev->jpeg.inst->irq); 99 if (r) 100 return r; 101 102 /* JPEG EJPEG POISON EVENT */ 103 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 104 VCN_4_0__SRCID_EJPEG0_POISON, &adev->jpeg.inst->irq); 105 if (r) 106 return r; 107 108 r = amdgpu_jpeg_sw_init(adev); 109 if (r) 110 return r; 111 112 r = amdgpu_jpeg_resume(adev); 113 if (r) 114 return r; 115 116 ring = adev->jpeg.inst->ring_dec; 117 ring->use_doorbell = true; 118 ring->doorbell_index = amdgpu_sriov_vf(adev) ? 119 (((adev->doorbell_index.vcn.vcn_ring0_1) << 1) + 4) : 120 ((adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1); 121 ring->vm_hub = AMDGPU_MMHUB0(0); 122 123 sprintf(ring->name, "jpeg_dec"); 124 r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0, 125 AMDGPU_RING_PRIO_DEFAULT, NULL); 126 if (r) 127 return r; 128 129 adev->jpeg.internal.jpeg_pitch[0] = regUVD_JPEG_PITCH_INTERNAL_OFFSET; 130 adev->jpeg.inst->external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_PITCH); 131 132 return 0; 133 } 134 135 /** 136 * jpeg_v4_0_5_sw_fini - sw fini for JPEG block 137 * 138 * @handle: amdgpu_device pointer 139 * 140 * JPEG suspend and free up sw allocation 141 */ 142 static int jpeg_v4_0_5_sw_fini(void *handle) 143 { 144 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 145 int r; 146 147 r = amdgpu_jpeg_suspend(adev); 148 if (r) 149 return r; 150 151 r = amdgpu_jpeg_sw_fini(adev); 152 153 return r; 154 } 155 156 /** 157 * jpeg_v4_0_5_hw_init - start and test JPEG block 158 * 159 * @handle: amdgpu_device pointer 160 * 161 */ 162 static int jpeg_v4_0_5_hw_init(void *handle) 163 { 164 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 165 struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec; 166 int r; 167 168 // TODO: Enable ring test with DPG support 169 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) { 170 DRM_DEV_INFO(adev->dev, "JPEG decode initialized successfully under DPG Mode"); 171 return 0; 172 } 173 174 r = amdgpu_ring_test_helper(ring); 175 if (r) 176 return r; 177 178 if (!r) 179 DRM_INFO("JPEG decode initialized successfully under SPG Mode\n"); 180 181 return 0; 182 } 183 184 /** 185 * jpeg_v4_0_5_hw_fini - stop the hardware block 186 * 187 * @handle: amdgpu_device pointer 188 * 189 * Stop the JPEG block, mark ring as not ready any more 190 */ 191 static int jpeg_v4_0_5_hw_fini(void *handle) 192 { 193 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 194 195 cancel_delayed_work_sync(&adev->vcn.idle_work); 196 if (!amdgpu_sriov_vf(adev)) { 197 if (adev->jpeg.cur_state != AMD_PG_STATE_GATE && 198 RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS)) 199 jpeg_v4_0_5_set_powergating_state(adev, AMD_PG_STATE_GATE); 200 } 201 202 return 0; 203 } 204 205 /** 206 * jpeg_v4_0_5_suspend - suspend JPEG block 207 * 208 * @handle: amdgpu_device pointer 209 * 210 * HW fini and suspend JPEG block 211 */ 212 static int jpeg_v4_0_5_suspend(void *handle) 213 { 214 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 215 int r; 216 217 r = jpeg_v4_0_5_hw_fini(adev); 218 if (r) 219 return r; 220 221 r = amdgpu_jpeg_suspend(adev); 222 223 return r; 224 } 225 226 /** 227 * jpeg_v4_0_5_resume - resume JPEG block 228 * 229 * @handle: amdgpu_device pointer 230 * 231 * Resume firmware and hw init JPEG block 232 */ 233 static int jpeg_v4_0_5_resume(void *handle) 234 { 235 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 236 int r; 237 238 r = amdgpu_jpeg_resume(adev); 239 if (r) 240 return r; 241 242 r = jpeg_v4_0_5_hw_init(adev); 243 244 return r; 245 } 246 247 static void jpeg_v4_0_5_disable_clock_gating(struct amdgpu_device *adev, int inst) 248 { 249 uint32_t data = 0; 250 251 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL); 252 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) { 253 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 254 data &= (~JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK); 255 } else { 256 data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 257 } 258 259 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 260 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 261 WREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL, data); 262 263 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE); 264 data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK 265 | JPEG_CGC_GATE__JPEG2_DEC_MASK 266 | JPEG_CGC_GATE__JMCIF_MASK 267 | JPEG_CGC_GATE__JRBBM_MASK); 268 WREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE, data); 269 } 270 271 static void jpeg_v4_0_5_enable_clock_gating(struct amdgpu_device *adev, int inst) 272 { 273 uint32_t data = 0; 274 275 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL); 276 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) { 277 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 278 data |= JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK; 279 } else { 280 data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 281 } 282 283 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 284 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 285 WREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL, data); 286 287 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE); 288 data |= (JPEG_CGC_GATE__JPEG_DEC_MASK 289 |JPEG_CGC_GATE__JPEG2_DEC_MASK 290 |JPEG_CGC_GATE__JMCIF_MASK 291 |JPEG_CGC_GATE__JRBBM_MASK); 292 WREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE, data); 293 } 294 295 static void jpeg_engine_4_0_5_dpg_clock_gating_mode(struct amdgpu_device *adev, 296 int inst_idx, uint8_t indirect) 297 { 298 uint32_t data = 0; 299 300 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) 301 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 302 else 303 data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 304 305 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 306 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 307 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_CGC_CTRL_INTERNAL_OFFSET, data, indirect); 308 309 data = 0; 310 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_CGC_GATE_INTERNAL_OFFSET, 311 data, indirect); 312 } 313 314 static int jpeg_v4_0_5_disable_static_power_gating(struct amdgpu_device *adev, int inst) 315 { 316 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) { 317 WREG32(SOC15_REG_OFFSET(JPEG, inst, regUVD_IPX_DLDO_CONFIG), 318 1 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT); 319 SOC15_WAIT_ON_RREG(JPEG, inst, regUVD_IPX_DLDO_STATUS, 320 0, UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK); 321 } 322 323 /* disable anti hang mechanism */ 324 WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS), 0, 325 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); 326 327 /* keep the JPEG in static PG mode */ 328 WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS), 0, 329 ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK); 330 331 return 0; 332 } 333 334 static int jpeg_v4_0_5_enable_static_power_gating(struct amdgpu_device *adev, int inst) 335 { 336 /* enable anti hang mechanism */ 337 WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS), 338 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK, 339 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); 340 341 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) { 342 WREG32(SOC15_REG_OFFSET(JPEG, inst, regUVD_IPX_DLDO_CONFIG), 343 2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT); 344 SOC15_WAIT_ON_RREG(JPEG, inst, regUVD_IPX_DLDO_STATUS, 345 1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT, 346 UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK); 347 } 348 349 return 0; 350 } 351 352 /** 353 * jpeg_v4_0_5_start_dpg_mode - Jpeg start with dpg mode 354 * 355 * @adev: amdgpu_device pointer 356 * @inst_idx: instance number index 357 * @indirect: indirectly write sram 358 * 359 * Start JPEG block with dpg mode 360 */ 361 static void jpeg_v4_0_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect) 362 { 363 struct amdgpu_ring *ring = adev->jpeg.inst[inst_idx].ring_dec; 364 uint32_t reg_data = 0; 365 366 /* enable anti hang mechanism */ 367 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS); 368 reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK; 369 reg_data |= 0x1; 370 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data); 371 372 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) { 373 WREG32(SOC15_REG_OFFSET(JPEG, inst_idx, regUVD_IPX_DLDO_CONFIG), 374 2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT); 375 SOC15_WAIT_ON_RREG(JPEG, inst_idx, regUVD_IPX_DLDO_STATUS, 376 1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT, 377 UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK); 378 } 379 380 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS); 381 reg_data |= UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK; 382 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data); 383 384 if (indirect) 385 adev->jpeg.inst[inst_idx].dpg_sram_curr_addr = 386 (uint32_t *)adev->jpeg.inst[inst_idx].dpg_sram_cpu_addr; 387 388 jpeg_engine_4_0_5_dpg_clock_gating_mode(adev, inst_idx, indirect); 389 390 /* MJPEG global tiling registers */ 391 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_DEC_GFX10_ADDR_CONFIG_INTERNAL_OFFSET, 392 adev->gfx.config.gb_addr_config, indirect); 393 /* enable System Interrupt for JRBC */ 394 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_SYS_INT_EN_INTERNAL_OFFSET, 395 JPEG_SYS_INT_EN__DJRBC_MASK, indirect); 396 397 /* add nop to workaround PSP size check */ 398 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regUVD_NO_OP_INTERNAL_OFFSET, 0, indirect); 399 400 if (indirect) 401 amdgpu_jpeg_psp_update_sram(adev, inst_idx, 0); 402 403 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_VMID, 0); 404 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L)); 405 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW, 406 lower_32_bits(ring->gpu_addr)); 407 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, 408 upper_32_bits(ring->gpu_addr)); 409 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_RPTR, 0); 410 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR, 0); 411 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, 0x00000002L); 412 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_SIZE, ring->ring_size / 4); 413 ring->wptr = RREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR); 414 } 415 416 /** 417 * jpeg_v4_0_5_stop_dpg_mode - Jpeg stop with dpg mode 418 * 419 * @adev: amdgpu_device pointer 420 * @inst_idx: instance number index 421 * 422 * Stop JPEG block with dpg mode 423 */ 424 static void jpeg_v4_0_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx) 425 { 426 uint32_t reg_data = 0; 427 428 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS); 429 reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK; 430 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data); 431 432 } 433 434 /** 435 * jpeg_v4_0_5_start - start JPEG block 436 * 437 * @adev: amdgpu_device pointer 438 * 439 * Setup and start the JPEG block 440 */ 441 static int jpeg_v4_0_5_start(struct amdgpu_device *adev) 442 { 443 struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec; 444 int r, i; 445 446 if (adev->pm.dpm_enabled) 447 amdgpu_dpm_enable_jpeg(adev, true); 448 449 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 450 /* doorbell programming is done for every playback */ 451 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, 452 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i, i); 453 454 WREG32_SOC15(VCN, i, regVCN_JPEG_DB_CTRL, 455 ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT | 456 VCN_JPEG_DB_CTRL__EN_MASK); 457 458 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) { 459 jpeg_v4_0_5_start_dpg_mode(adev, i, adev->jpeg.indirect_sram); 460 continue; 461 } 462 463 /* disable power gating */ 464 r = jpeg_v4_0_5_disable_static_power_gating(adev, i); 465 if (r) 466 return r; 467 468 /* JPEG disable CGC */ 469 jpeg_v4_0_5_disable_clock_gating(adev, i); 470 471 /* MJPEG global tiling registers */ 472 WREG32_SOC15(JPEG, i, regJPEG_DEC_GFX10_ADDR_CONFIG, 473 adev->gfx.config.gb_addr_config); 474 475 /* enable JMI channel */ 476 WREG32_P(SOC15_REG_OFFSET(JPEG, i, regUVD_JMI_CNTL), 0, 477 ~UVD_JMI_CNTL__SOFT_RESET_MASK); 478 479 /* enable System Interrupt for JRBC */ 480 WREG32_P(SOC15_REG_OFFSET(JPEG, i, regJPEG_SYS_INT_EN), 481 JPEG_SYS_INT_EN__DJRBC_MASK, 482 ~JPEG_SYS_INT_EN__DJRBC_MASK); 483 484 WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_VMID, 0); 485 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L)); 486 WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW, 487 lower_32_bits(ring->gpu_addr)); 488 WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, 489 upper_32_bits(ring->gpu_addr)); 490 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_RPTR, 0); 491 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_WPTR, 0); 492 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_CNTL, 0x00000002L); 493 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_SIZE, ring->ring_size / 4); 494 ring->wptr = RREG32_SOC15(JPEG, i, regUVD_JRBC_RB_WPTR); 495 } 496 497 return 0; 498 } 499 500 /** 501 * jpeg_v4_0_5_stop - stop JPEG block 502 * 503 * @adev: amdgpu_device pointer 504 * 505 * stop the JPEG block 506 */ 507 static int jpeg_v4_0_5_stop(struct amdgpu_device *adev) 508 { 509 int r, i; 510 511 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 512 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) { 513 514 jpeg_v4_0_5_stop_dpg_mode(adev, i); 515 continue; 516 } 517 /* reset JMI */ 518 WREG32_P(SOC15_REG_OFFSET(JPEG, i, regUVD_JMI_CNTL), 519 UVD_JMI_CNTL__SOFT_RESET_MASK, 520 ~UVD_JMI_CNTL__SOFT_RESET_MASK); 521 522 jpeg_v4_0_5_enable_clock_gating(adev, i); 523 524 /* enable power gating */ 525 r = jpeg_v4_0_5_enable_static_power_gating(adev, i); 526 if (r) 527 return r; 528 } 529 530 if (adev->pm.dpm_enabled) 531 amdgpu_dpm_enable_jpeg(adev, false); 532 533 return 0; 534 } 535 536 /** 537 * jpeg_v4_0_5_dec_ring_get_rptr - get read pointer 538 * 539 * @ring: amdgpu_ring pointer 540 * 541 * Returns the current hardware read pointer 542 */ 543 static uint64_t jpeg_v4_0_5_dec_ring_get_rptr(struct amdgpu_ring *ring) 544 { 545 struct amdgpu_device *adev = ring->adev; 546 547 return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_RPTR); 548 } 549 550 /** 551 * jpeg_v4_0_5_dec_ring_get_wptr - get write pointer 552 * 553 * @ring: amdgpu_ring pointer 554 * 555 * Returns the current hardware write pointer 556 */ 557 static uint64_t jpeg_v4_0_5_dec_ring_get_wptr(struct amdgpu_ring *ring) 558 { 559 struct amdgpu_device *adev = ring->adev; 560 561 if (ring->use_doorbell) 562 return *ring->wptr_cpu_addr; 563 else 564 return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR); 565 } 566 567 /** 568 * jpeg_v4_0_5_dec_ring_set_wptr - set write pointer 569 * 570 * @ring: amdgpu_ring pointer 571 * 572 * Commits the write pointer to the hardware 573 */ 574 static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring) 575 { 576 struct amdgpu_device *adev = ring->adev; 577 578 if (ring->use_doorbell) { 579 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr); 580 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 581 } else { 582 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); 583 } 584 } 585 586 static bool jpeg_v4_0_5_is_idle(void *handle) 587 { 588 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 589 int ret = 1; 590 591 ret &= (((RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS) & 592 UVD_JRBC_STATUS__RB_JOB_DONE_MASK) == 593 UVD_JRBC_STATUS__RB_JOB_DONE_MASK)); 594 595 return ret; 596 } 597 598 static int jpeg_v4_0_5_wait_for_idle(void *handle) 599 { 600 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 601 602 return SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_JRBC_STATUS, 603 UVD_JRBC_STATUS__RB_JOB_DONE_MASK, 604 UVD_JRBC_STATUS__RB_JOB_DONE_MASK); 605 } 606 607 static int jpeg_v4_0_5_set_clockgating_state(void *handle, 608 enum amd_clockgating_state state) 609 { 610 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 611 bool enable = (state == AMD_CG_STATE_GATE) ? true : false; 612 int i; 613 614 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 615 if (adev->jpeg.harvest_config & (1 << i)) 616 continue; 617 618 if (enable) { 619 if (!jpeg_v4_0_5_is_idle(handle)) 620 return -EBUSY; 621 622 jpeg_v4_0_5_enable_clock_gating(adev, i); 623 } else { 624 jpeg_v4_0_5_disable_clock_gating(adev, i); 625 } 626 } 627 628 return 0; 629 } 630 631 static int jpeg_v4_0_5_set_powergating_state(void *handle, 632 enum amd_powergating_state state) 633 { 634 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 635 int ret; 636 637 if (amdgpu_sriov_vf(adev)) { 638 adev->jpeg.cur_state = AMD_PG_STATE_UNGATE; 639 return 0; 640 } 641 642 if (state == adev->jpeg.cur_state) 643 return 0; 644 645 if (state == AMD_PG_STATE_GATE) 646 ret = jpeg_v4_0_5_stop(adev); 647 else 648 ret = jpeg_v4_0_5_start(adev); 649 650 if (!ret) 651 adev->jpeg.cur_state = state; 652 653 return ret; 654 } 655 656 static int jpeg_v4_0_5_process_interrupt(struct amdgpu_device *adev, 657 struct amdgpu_irq_src *source, 658 struct amdgpu_iv_entry *entry) 659 { 660 DRM_DEBUG("IH: JPEG TRAP\n"); 661 662 switch (entry->src_id) { 663 case VCN_4_0__SRCID__JPEG_DECODE: 664 amdgpu_fence_process(adev->jpeg.inst->ring_dec); 665 break; 666 case VCN_4_0__SRCID_DJPEG0_POISON: 667 case VCN_4_0__SRCID_EJPEG0_POISON: 668 amdgpu_jpeg_process_poison_irq(adev, source, entry); 669 break; 670 default: 671 DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n", 672 entry->src_id, entry->src_data[0]); 673 break; 674 } 675 676 return 0; 677 } 678 679 static const struct amd_ip_funcs jpeg_v4_0_5_ip_funcs = { 680 .name = "jpeg_v4_0_5", 681 .early_init = jpeg_v4_0_5_early_init, 682 .late_init = NULL, 683 .sw_init = jpeg_v4_0_5_sw_init, 684 .sw_fini = jpeg_v4_0_5_sw_fini, 685 .hw_init = jpeg_v4_0_5_hw_init, 686 .hw_fini = jpeg_v4_0_5_hw_fini, 687 .suspend = jpeg_v4_0_5_suspend, 688 .resume = jpeg_v4_0_5_resume, 689 .is_idle = jpeg_v4_0_5_is_idle, 690 .wait_for_idle = jpeg_v4_0_5_wait_for_idle, 691 .check_soft_reset = NULL, 692 .pre_soft_reset = NULL, 693 .soft_reset = NULL, 694 .post_soft_reset = NULL, 695 .set_clockgating_state = jpeg_v4_0_5_set_clockgating_state, 696 .set_powergating_state = jpeg_v4_0_5_set_powergating_state, 697 }; 698 699 static const struct amdgpu_ring_funcs jpeg_v4_0_5_dec_ring_vm_funcs = { 700 .type = AMDGPU_RING_TYPE_VCN_JPEG, 701 .align_mask = 0xf, 702 .get_rptr = jpeg_v4_0_5_dec_ring_get_rptr, 703 .get_wptr = jpeg_v4_0_5_dec_ring_get_wptr, 704 .set_wptr = jpeg_v4_0_5_dec_ring_set_wptr, 705 .emit_frame_size = 706 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + 707 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + 708 8 + /* jpeg_v4_0_5_dec_ring_emit_vm_flush */ 709 18 + 18 + /* jpeg_v4_0_5_dec_ring_emit_fence x2 vm fence */ 710 8 + 16, 711 .emit_ib_size = 22, /* jpeg_v4_0_5_dec_ring_emit_ib */ 712 .emit_ib = jpeg_v2_0_dec_ring_emit_ib, 713 .emit_fence = jpeg_v2_0_dec_ring_emit_fence, 714 .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush, 715 .test_ring = amdgpu_jpeg_dec_ring_test_ring, 716 .test_ib = amdgpu_jpeg_dec_ring_test_ib, 717 .insert_nop = jpeg_v2_0_dec_ring_nop, 718 .insert_start = jpeg_v2_0_dec_ring_insert_start, 719 .insert_end = jpeg_v2_0_dec_ring_insert_end, 720 .pad_ib = amdgpu_ring_generic_pad_ib, 721 .begin_use = amdgpu_jpeg_ring_begin_use, 722 .end_use = amdgpu_jpeg_ring_end_use, 723 .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg, 724 .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait, 725 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 726 }; 727 728 static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev) 729 { 730 int i; 731 732 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 733 if (adev->jpeg.harvest_config & (1 << i)) 734 continue; 735 736 adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v4_0_5_dec_ring_vm_funcs; 737 DRM_DEV_INFO(adev->dev, "JPEG%d decode is enabled in VM mode\n", i); 738 } 739 } 740 741 static const struct amdgpu_irq_src_funcs jpeg_v4_0_5_irq_funcs = { 742 .process = jpeg_v4_0_5_process_interrupt, 743 }; 744 745 static void jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device *adev) 746 { 747 int i; 748 749 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 750 if (adev->jpeg.harvest_config & (1 << i)) 751 continue; 752 753 adev->jpeg.inst[i].irq.num_types = 1; 754 adev->jpeg.inst[i].irq.funcs = &jpeg_v4_0_5_irq_funcs; 755 } 756 } 757 758 const struct amdgpu_ip_block_version jpeg_v4_0_5_ip_block = { 759 .type = AMD_IP_BLOCK_TYPE_JPEG, 760 .major = 4, 761 .minor = 0, 762 .rev = 5, 763 .funcs = &jpeg_v4_0_5_ip_funcs, 764 }; 765 766