1 // SPDX-License-Identifier: GPL-2.0 OR MIT 2 /* 3 * Copyright 2025-2026 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_2.h" 31 #include "mmsch_v5_0.h" 32 33 #include "vcn/vcn_5_0_0_offset.h" 34 #include "vcn/vcn_5_0_0_sh_mask.h" 35 #include "ivsrcid/vcn/irqsrcs_vcn_5_0.h" 36 37 static void jpeg_v5_0_2_set_dec_ring_funcs(struct amdgpu_device *adev); 38 static void jpeg_v5_0_2_set_irq_funcs(struct amdgpu_device *adev); 39 static int jpeg_v5_0_2_set_powergating_state(struct amdgpu_ip_block *ip_block, 40 enum amd_powergating_state state); 41 static void jpeg_v5_0_2_dec_ring_set_wptr(struct amdgpu_ring *ring); 42 43 static int amdgpu_ih_srcid_jpeg[] = { 44 VCN_5_0__SRCID__JPEG_DECODE, 45 VCN_5_0__SRCID__JPEG1_DECODE, 46 VCN_5_0__SRCID__JPEG2_DECODE, 47 VCN_5_0__SRCID__JPEG3_DECODE, 48 VCN_5_0__SRCID__JPEG4_DECODE, 49 VCN_5_0__SRCID__JPEG5_DECODE, 50 VCN_5_0__SRCID__JPEG6_DECODE, 51 VCN_5_0__SRCID__JPEG7_DECODE, 52 VCN_5_0__SRCID__JPEG8_DECODE, 53 VCN_5_0__SRCID__JPEG9_DECODE, 54 }; 55 56 static const struct amdgpu_hwip_reg_entry jpeg_reg_list_5_0_2[] = { 57 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS), 58 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT), 59 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_RPTR), 60 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_WPTR), 61 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_STATUS), 62 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE), 63 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG), 64 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE), 65 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE), 66 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH), 67 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH), 68 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_RPTR), 69 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_WPTR), 70 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_STATUS), 71 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_RPTR), 72 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_WPTR), 73 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_STATUS), 74 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_RPTR), 75 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_WPTR), 76 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_STATUS), 77 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_RPTR), 78 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_WPTR), 79 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_STATUS), 80 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_RPTR), 81 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_WPTR), 82 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_STATUS), 83 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_RPTR), 84 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_WPTR), 85 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_STATUS), 86 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_RPTR), 87 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_WPTR), 88 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_STATUS), 89 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_RB_RPTR), 90 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_RB_WPTR), 91 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_STATUS), 92 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_RB_RPTR), 93 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_RB_WPTR), 94 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_STATUS), 95 }; 96 97 static int jpeg_v5_0_2_core_reg_offset(u32 pipe) 98 { 99 if (pipe <= AMDGPU_MAX_JPEG_RINGS_4_0_3) 100 return ((0x40 * pipe) - 0xc80); 101 else 102 return ((0x40 * pipe) - 0x440); 103 } 104 105 /** 106 * jpeg_v5_0_2_early_init - set function pointers 107 * 108 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 109 * 110 * Set ring and irq function pointers 111 */ 112 static int jpeg_v5_0_2_early_init(struct amdgpu_ip_block *ip_block) 113 { 114 struct amdgpu_device *adev = ip_block->adev; 115 116 if (!adev->jpeg.num_jpeg_inst || adev->jpeg.num_jpeg_inst > AMDGPU_MAX_JPEG_INSTANCES) 117 return -ENOENT; 118 119 adev->jpeg.num_jpeg_rings = AMDGPU_MAX_JPEG_RINGS; 120 jpeg_v5_0_2_set_dec_ring_funcs(adev); 121 jpeg_v5_0_2_set_irq_funcs(adev); 122 123 return 0; 124 } 125 126 /** 127 * jpeg_v5_0_2_sw_init - sw init for JPEG block 128 * 129 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 130 * 131 * Load firmware and sw initialization 132 */ 133 static int jpeg_v5_0_2_sw_init(struct amdgpu_ip_block *ip_block) 134 { 135 struct amdgpu_device *adev = ip_block->adev; 136 struct amdgpu_ring *ring; 137 int i, j, r, jpeg_inst; 138 139 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 140 /* JPEG TRAP */ 141 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 142 amdgpu_ih_srcid_jpeg[j], &adev->jpeg.inst->irq); 143 if (r) 144 return r; 145 } 146 147 r = amdgpu_jpeg_sw_init(adev); 148 if (r) 149 return r; 150 151 r = amdgpu_jpeg_resume(adev); 152 if (r) 153 return r; 154 155 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 156 jpeg_inst = GET_INST(JPEG, i); 157 158 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 159 ring = &adev->jpeg.inst[i].ring_dec[j]; 160 ring->use_doorbell = false; 161 ring->vm_hub = AMDGPU_MMHUB0(adev->jpeg.inst[i].aid_id); 162 ring->doorbell_index = 163 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 164 1 + j + 11 * jpeg_inst; 165 sprintf(ring->name, "jpeg_dec_%d.%d", adev->jpeg.inst[i].aid_id, j); 166 r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0, 167 AMDGPU_RING_PRIO_DEFAULT, NULL); 168 if (r) 169 return r; 170 171 adev->jpeg.internal.jpeg_pitch[j] = 172 regUVD_JRBC0_UVD_JRBC_SCRATCH0_INTERNAL_OFFSET; 173 adev->jpeg.inst[i].external.jpeg_pitch[j] = 174 SOC15_REG_OFFSET1(JPEG, jpeg_inst, regUVD_JRBC_SCRATCH0, 175 (j ? jpeg_v5_0_2_core_reg_offset(j) : 0)); 176 } 177 } 178 179 r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_5_0_2, ARRAY_SIZE(jpeg_reg_list_5_0_2)); 180 if (r) 181 return r; 182 183 adev->jpeg.supported_reset = 184 amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]); 185 adev->jpeg.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; 186 r = amdgpu_jpeg_sysfs_reset_mask_init(adev); 187 188 return r; 189 } 190 191 /** 192 * jpeg_v5_0_2_sw_fini - sw fini for JPEG block 193 * 194 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 195 * 196 * JPEG suspend and free up sw allocation 197 */ 198 static int jpeg_v5_0_2_sw_fini(struct amdgpu_ip_block *ip_block) 199 { 200 struct amdgpu_device *adev = ip_block->adev; 201 int r; 202 203 r = amdgpu_jpeg_suspend(adev); 204 if (r) 205 return r; 206 207 amdgpu_jpeg_sysfs_reset_mask_fini(adev); 208 209 r = amdgpu_jpeg_sw_fini(adev); 210 211 return r; 212 } 213 214 /** 215 * jpeg_v5_0_2_hw_init - start and test JPEG block 216 * 217 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 218 * 219 */ 220 static int jpeg_v5_0_2_hw_init(struct amdgpu_ip_block *ip_block) 221 { 222 struct amdgpu_device *adev = ip_block->adev; 223 struct amdgpu_ring *ring; 224 int i, j, r, jpeg_inst, tmp; 225 226 if (RREG32_SOC15(VCN, GET_INST(VCN, 0), regVCN_RRMT_CNTL) & 0x100) 227 adev->jpeg.caps |= AMDGPU_JPEG_CAPS(RRMT_ENABLED); 228 229 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 230 jpeg_inst = GET_INST(JPEG, i); 231 ring = adev->jpeg.inst[i].ring_dec; 232 233 /* Remove JPEG Tile antihang mechanism */ 234 tmp = RREG32_SOC15(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS); 235 tmp &= (~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); 236 WREG32_SOC15(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS, tmp); 237 238 if (ring->use_doorbell) 239 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, 240 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 11 * jpeg_inst, 241 adev->jpeg.inst[i].aid_id); 242 243 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 244 ring = &adev->jpeg.inst[i].ring_dec[j]; 245 if (ring->use_doorbell) 246 WREG32_SOC15_OFFSET(VCN, GET_INST(VCN, i), regVCN_JPEG_DB_CTRL, 247 ring->pipe, 248 ring->doorbell_index << 249 VCN_JPEG_DB_CTRL__OFFSET__SHIFT | 250 VCN_JPEG_DB_CTRL__EN_MASK); 251 r = amdgpu_ring_test_helper(ring); 252 if (r) 253 return r; 254 } 255 } 256 257 return 0; 258 } 259 260 /** 261 * jpeg_v5_0_2_hw_fini - stop the hardware block 262 * 263 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 264 * 265 * Stop the JPEG block, mark ring as not ready any more 266 */ 267 static int jpeg_v5_0_2_hw_fini(struct amdgpu_ip_block *ip_block) 268 { 269 struct amdgpu_device *adev = ip_block->adev; 270 int ret = 0; 271 272 cancel_delayed_work_sync(&adev->jpeg.idle_work); 273 274 if (adev->jpeg.cur_state != AMD_PG_STATE_GATE) 275 ret = jpeg_v5_0_2_set_powergating_state(ip_block, AMD_PG_STATE_GATE); 276 277 return ret; 278 } 279 280 /** 281 * jpeg_v5_0_2_suspend - suspend JPEG block 282 * 283 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 284 * 285 * HW fini and suspend JPEG block 286 */ 287 static int jpeg_v5_0_2_suspend(struct amdgpu_ip_block *ip_block) 288 { 289 struct amdgpu_device *adev = ip_block->adev; 290 int r; 291 292 r = jpeg_v5_0_2_hw_fini(ip_block); 293 if (r) 294 return r; 295 296 r = amdgpu_jpeg_suspend(adev); 297 298 return r; 299 } 300 301 /** 302 * jpeg_v5_0_2_resume - resume JPEG block 303 * 304 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance. 305 * 306 * Resume firmware and hw init JPEG block 307 */ 308 static int jpeg_v5_0_2_resume(struct amdgpu_ip_block *ip_block) 309 { 310 struct amdgpu_device *adev = ip_block->adev; 311 int r; 312 313 r = amdgpu_jpeg_resume(adev); 314 if (r) 315 return r; 316 317 r = jpeg_v5_0_2_hw_init(ip_block); 318 319 return r; 320 } 321 322 static void jpeg_v5_0_2_init_inst(struct amdgpu_device *adev, int i) 323 { 324 int jpeg_inst = GET_INST(JPEG, i); 325 326 /* disable anti hang mechanism */ 327 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0, 328 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); 329 330 /* keep the JPEG in static PG mode */ 331 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0, 332 ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK); 333 334 /* MJPEG global tiling registers */ 335 WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG, 336 adev->gfx.config.gb_addr_config); 337 338 /* enable JMI channel */ 339 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL), 0, 340 ~UVD_JMI_CNTL__SOFT_RESET_MASK); 341 } 342 343 static void jpeg_v5_0_2_deinit_inst(struct amdgpu_device *adev, int i) 344 { 345 int jpeg_inst = GET_INST(JPEG, i); 346 /* reset JMI */ 347 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL), 348 UVD_JMI_CNTL__SOFT_RESET_MASK, 349 ~UVD_JMI_CNTL__SOFT_RESET_MASK); 350 351 /* enable anti hang mechanism */ 352 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 353 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK, 354 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); 355 } 356 357 static void jpeg_v5_0_2_init_jrbc(struct amdgpu_ring *ring) 358 { 359 struct amdgpu_device *adev = ring->adev; 360 u32 reg, data, mask; 361 int jpeg_inst = GET_INST(JPEG, ring->me); 362 int reg_offset = ring->pipe ? jpeg_v5_0_2_core_reg_offset(ring->pipe) : 0; 363 364 /* enable System Interrupt for JRBC */ 365 reg = SOC15_REG_OFFSET(JPEG, jpeg_inst, regJPEG_SYS_INT_EN); 366 if (ring->pipe < AMDGPU_MAX_JPEG_RINGS_4_0_3) { 367 data = JPEG_SYS_INT_EN__DJRBC0_MASK << ring->pipe; 368 mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << ring->pipe); 369 WREG32_P(reg, data, mask); 370 } else { 371 data = JPEG_SYS_INT_EN__DJRBC0_MASK << (ring->pipe+12); 372 mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << (ring->pipe+12)); 373 WREG32_P(reg, data, mask); 374 } 375 376 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 377 regUVD_LMI_JRBC_RB_VMID, 378 reg_offset, 0); 379 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 380 regUVD_JRBC_RB_CNTL, 381 reg_offset, 382 (0x00000001L | 0x00000002L)); 383 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 384 regUVD_LMI_JRBC_RB_64BIT_BAR_LOW, 385 reg_offset, lower_32_bits(ring->gpu_addr)); 386 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 387 regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, 388 reg_offset, upper_32_bits(ring->gpu_addr)); 389 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 390 regUVD_JRBC_RB_RPTR, 391 reg_offset, 0); 392 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 393 regUVD_JRBC_RB_WPTR, 394 reg_offset, 0); 395 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 396 regUVD_JRBC_RB_CNTL, 397 reg_offset, 0x00000002L); 398 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 399 regUVD_JRBC_RB_SIZE, 400 reg_offset, ring->ring_size / 4); 401 ring->wptr = RREG32_SOC15_OFFSET(JPEG, jpeg_inst, regUVD_JRBC_RB_WPTR, 402 reg_offset); 403 } 404 405 /** 406 * jpeg_v5_0_2_start - start JPEG block 407 * 408 * @adev: amdgpu_device pointer 409 * 410 * Setup and start the JPEG block 411 */ 412 static int jpeg_v5_0_2_start(struct amdgpu_device *adev) 413 { 414 struct amdgpu_ring *ring; 415 int i, j; 416 417 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 418 jpeg_v5_0_2_init_inst(adev, i); 419 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 420 ring = &adev->jpeg.inst[i].ring_dec[j]; 421 jpeg_v5_0_2_init_jrbc(ring); 422 } 423 } 424 425 return 0; 426 } 427 428 /** 429 * jpeg_v5_0_2_stop - stop JPEG block 430 * 431 * @adev: amdgpu_device pointer 432 * 433 * stop the JPEG block 434 */ 435 static int jpeg_v5_0_2_stop(struct amdgpu_device *adev) 436 { 437 int i; 438 439 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) 440 jpeg_v5_0_2_deinit_inst(adev, i); 441 442 return 0; 443 } 444 445 /** 446 * jpeg_v5_0_2_dec_ring_get_rptr - get read pointer 447 * 448 * @ring: amdgpu_ring pointer 449 * 450 * Returns the current hardware read pointer 451 */ 452 static uint64_t jpeg_v5_0_2_dec_ring_get_rptr(struct amdgpu_ring *ring) 453 { 454 struct amdgpu_device *adev = ring->adev; 455 456 return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_RPTR, 457 ring->pipe ? jpeg_v5_0_2_core_reg_offset(ring->pipe) : 0); 458 } 459 460 /** 461 * jpeg_v5_0_2_dec_ring_get_wptr - get write pointer 462 * 463 * @ring: amdgpu_ring pointer 464 * 465 * Returns the current hardware write pointer 466 */ 467 static uint64_t jpeg_v5_0_2_dec_ring_get_wptr(struct amdgpu_ring *ring) 468 { 469 struct amdgpu_device *adev = ring->adev; 470 471 if (ring->use_doorbell) 472 return adev->wb.wb[ring->wptr_offs]; 473 474 return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_WPTR, 475 ring->pipe ? jpeg_v5_0_2_core_reg_offset(ring->pipe) : 0); 476 } 477 478 /** 479 * jpeg_v5_0_2_dec_ring_set_wptr - set write pointer 480 * 481 * @ring: amdgpu_ring pointer 482 * 483 * Commits the write pointer to the hardware 484 */ 485 static void jpeg_v5_0_2_dec_ring_set_wptr(struct amdgpu_ring *ring) 486 { 487 struct amdgpu_device *adev = ring->adev; 488 489 if (ring->use_doorbell) { 490 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr); 491 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 492 } else { 493 WREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), 494 regUVD_JRBC_RB_WPTR, 495 (ring->pipe ? jpeg_v5_0_2_core_reg_offset(ring->pipe) : 0), 496 lower_32_bits(ring->wptr)); 497 } 498 } 499 500 static bool jpeg_v5_0_2_is_idle(struct amdgpu_ip_block *ip_block) 501 { 502 struct amdgpu_device *adev = ip_block->adev; 503 bool ret = false; 504 int i, j; 505 506 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 507 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 508 int reg_offset = (j ? jpeg_v5_0_2_core_reg_offset(j) : 0); 509 510 ret &= ((RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, i), 511 regUVD_JRBC_STATUS, reg_offset) & 512 UVD_JRBC_STATUS__RB_JOB_DONE_MASK) == 513 UVD_JRBC_STATUS__RB_JOB_DONE_MASK); 514 } 515 } 516 517 return ret; 518 } 519 520 static int jpeg_v5_0_2_wait_for_idle(struct amdgpu_ip_block *ip_block) 521 { 522 struct amdgpu_device *adev = ip_block->adev; 523 int ret = 0; 524 int i, j; 525 526 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 527 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 528 int reg_offset = (j ? jpeg_v5_0_2_core_reg_offset(j) : 0); 529 530 ret &= SOC15_WAIT_ON_RREG_OFFSET(JPEG, GET_INST(JPEG, i), 531 regUVD_JRBC_STATUS, reg_offset, 532 UVD_JRBC_STATUS__RB_JOB_DONE_MASK, 533 UVD_JRBC_STATUS__RB_JOB_DONE_MASK); 534 } 535 } 536 return ret; 537 } 538 539 static int jpeg_v5_0_2_set_clockgating_state(struct amdgpu_ip_block *ip_block, 540 enum amd_clockgating_state state) 541 { 542 struct amdgpu_device *adev = ip_block->adev; 543 bool enable = state == AMD_CG_STATE_GATE; 544 545 int i; 546 547 if (!enable) 548 return 0; 549 550 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 551 if (!jpeg_v5_0_2_is_idle(ip_block)) 552 return -EBUSY; 553 } 554 555 return 0; 556 } 557 558 static int jpeg_v5_0_2_set_powergating_state(struct amdgpu_ip_block *ip_block, 559 enum amd_powergating_state state) 560 { 561 struct amdgpu_device *adev = ip_block->adev; 562 int ret; 563 564 if (state == adev->jpeg.cur_state) 565 return 0; 566 567 if (state == AMD_PG_STATE_GATE) 568 ret = jpeg_v5_0_2_stop(adev); 569 else 570 ret = jpeg_v5_0_2_start(adev); 571 572 if (!ret) 573 adev->jpeg.cur_state = state; 574 575 return ret; 576 } 577 578 static int jpeg_v5_0_2_set_interrupt_state(struct amdgpu_device *adev, 579 struct amdgpu_irq_src *source, 580 unsigned int type, 581 enum amdgpu_interrupt_state state) 582 { 583 return 0; 584 } 585 586 static int jpeg_v5_0_2_process_interrupt(struct amdgpu_device *adev, 587 struct amdgpu_irq_src *source, 588 struct amdgpu_iv_entry *entry) 589 { 590 u32 i, inst; 591 592 i = node_id_to_phys_map[entry->node_id]; 593 DRM_DEV_DEBUG(adev->dev, "IH: JPEG TRAP\n"); 594 595 for (inst = 0; inst < adev->jpeg.num_jpeg_inst; ++inst) 596 if (adev->jpeg.inst[inst].aid_id == i) 597 break; 598 599 if (inst >= adev->jpeg.num_jpeg_inst) { 600 dev_WARN_ONCE(adev->dev, 1, 601 "Interrupt received for unknown JPEG instance %d", 602 entry->node_id); 603 return 0; 604 } 605 606 switch (entry->src_id) { 607 case VCN_5_0__SRCID__JPEG_DECODE: 608 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[0]); 609 break; 610 case VCN_5_0__SRCID__JPEG1_DECODE: 611 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[1]); 612 break; 613 case VCN_5_0__SRCID__JPEG2_DECODE: 614 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[2]); 615 break; 616 case VCN_5_0__SRCID__JPEG3_DECODE: 617 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[3]); 618 break; 619 case VCN_5_0__SRCID__JPEG4_DECODE: 620 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[4]); 621 break; 622 case VCN_5_0__SRCID__JPEG5_DECODE: 623 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[5]); 624 break; 625 case VCN_5_0__SRCID__JPEG6_DECODE: 626 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[6]); 627 break; 628 case VCN_5_0__SRCID__JPEG7_DECODE: 629 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[7]); 630 break; 631 case VCN_5_0__SRCID__JPEG8_DECODE: 632 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[8]); 633 break; 634 case VCN_5_0__SRCID__JPEG9_DECODE: 635 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[9]); 636 break; 637 default: 638 DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n", 639 entry->src_id, entry->src_data[0]); 640 break; 641 } 642 643 return 0; 644 } 645 646 static void jpeg_v5_0_2_core_stall_reset(struct amdgpu_ring *ring) 647 { 648 struct amdgpu_device *adev = ring->adev; 649 int jpeg_inst = GET_INST(JPEG, ring->me); 650 int reg_offset = ring->pipe ? jpeg_v5_0_2_core_reg_offset(ring->pipe) : 0; 651 652 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 653 regUVD_JMI0_UVD_JMI_CLIENT_STALL, 654 reg_offset, 0x1F); 655 SOC15_WAIT_ON_RREG_OFFSET(JPEG, jpeg_inst, 656 regUVD_JMI0_UVD_JMI_CLIENT_CLEAN_STATUS, 657 reg_offset, 0x1F, 0x1F); 658 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 659 regUVD_JMI0_JPEG_LMI_DROP, 660 reg_offset, 0x1F); 661 WREG32_SOC15(JPEG, jpeg_inst, regJPEG_CORE_RST_CTRL, 1 << ring->pipe); 662 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 663 regUVD_JMI0_UVD_JMI_CLIENT_STALL, 664 reg_offset, 0x00); 665 WREG32_SOC15_OFFSET(JPEG, jpeg_inst, 666 regUVD_JMI0_JPEG_LMI_DROP, 667 reg_offset, 0x00); 668 WREG32_SOC15(JPEG, jpeg_inst, regJPEG_CORE_RST_CTRL, 0x00); 669 } 670 671 static int jpeg_v5_0_2_ring_reset(struct amdgpu_ring *ring, 672 unsigned int vmid, 673 struct amdgpu_fence *timedout_fence) 674 { 675 amdgpu_ring_reset_helper_begin(ring, timedout_fence); 676 jpeg_v5_0_2_core_stall_reset(ring); 677 jpeg_v5_0_2_init_jrbc(ring); 678 return amdgpu_ring_reset_helper_end(ring, timedout_fence); 679 } 680 681 static const struct amd_ip_funcs jpeg_v5_0_2_ip_funcs = { 682 .name = "jpeg_v5_0_2", 683 .early_init = jpeg_v5_0_2_early_init, 684 .late_init = NULL, 685 .sw_init = jpeg_v5_0_2_sw_init, 686 .sw_fini = jpeg_v5_0_2_sw_fini, 687 .hw_init = jpeg_v5_0_2_hw_init, 688 .hw_fini = jpeg_v5_0_2_hw_fini, 689 .suspend = jpeg_v5_0_2_suspend, 690 .resume = jpeg_v5_0_2_resume, 691 .is_idle = jpeg_v5_0_2_is_idle, 692 .wait_for_idle = jpeg_v5_0_2_wait_for_idle, 693 .check_soft_reset = NULL, 694 .pre_soft_reset = NULL, 695 .soft_reset = NULL, 696 .post_soft_reset = NULL, 697 .set_clockgating_state = jpeg_v5_0_2_set_clockgating_state, 698 .set_powergating_state = jpeg_v5_0_2_set_powergating_state, 699 .dump_ip_state = amdgpu_jpeg_dump_ip_state, 700 .print_ip_state = amdgpu_jpeg_print_ip_state, 701 }; 702 703 static const struct amdgpu_ring_funcs jpeg_v5_0_2_dec_ring_vm_funcs = { 704 .type = AMDGPU_RING_TYPE_VCN_JPEG, 705 .align_mask = 0xf, 706 .get_rptr = jpeg_v5_0_2_dec_ring_get_rptr, 707 .get_wptr = jpeg_v5_0_2_dec_ring_get_wptr, 708 .set_wptr = jpeg_v5_0_2_dec_ring_set_wptr, 709 .emit_frame_size = 710 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + 711 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + 712 8 + /* jpeg_v5_0_2_dec_ring_emit_vm_flush */ 713 22 + 22 + /* jpeg_v5_0_2_dec_ring_emit_fence x2 vm fence */ 714 8 + 16, 715 .emit_ib_size = 22, /* jpeg_v5_0_2_dec_ring_emit_ib */ 716 .emit_ib = jpeg_v4_0_3_dec_ring_emit_ib, 717 .emit_fence = jpeg_v4_0_3_dec_ring_emit_fence, 718 .emit_vm_flush = jpeg_v4_0_3_dec_ring_emit_vm_flush, 719 .emit_hdp_flush = jpeg_v4_0_3_ring_emit_hdp_flush, 720 .test_ring = amdgpu_jpeg_dec_ring_test_ring, 721 .test_ib = amdgpu_jpeg_dec_ring_test_ib, 722 .insert_nop = jpeg_v4_0_3_dec_ring_nop, 723 .insert_start = jpeg_v4_0_3_dec_ring_insert_start, 724 .insert_end = jpeg_v4_0_3_dec_ring_insert_end, 725 .pad_ib = amdgpu_ring_generic_pad_ib, 726 .begin_use = amdgpu_jpeg_ring_begin_use, 727 .end_use = amdgpu_jpeg_ring_end_use, 728 .emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg, 729 .emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait, 730 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 731 .reset = jpeg_v5_0_2_ring_reset, 732 }; 733 734 static void jpeg_v5_0_2_set_dec_ring_funcs(struct amdgpu_device *adev) 735 { 736 int i, j, jpeg_inst; 737 738 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { 739 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) { 740 adev->jpeg.inst[i].ring_dec[j].funcs = &jpeg_v5_0_2_dec_ring_vm_funcs; 741 adev->jpeg.inst[i].ring_dec[j].me = i; 742 adev->jpeg.inst[i].ring_dec[j].pipe = j; 743 } 744 jpeg_inst = GET_INST(JPEG, i); 745 adev->jpeg.inst[i].aid_id = 746 jpeg_inst / adev->jpeg.num_inst_per_aid; 747 } 748 } 749 750 static const struct amdgpu_irq_src_funcs jpeg_v5_0_2_irq_funcs = { 751 .set = jpeg_v5_0_2_set_interrupt_state, 752 .process = jpeg_v5_0_2_process_interrupt, 753 }; 754 755 static void jpeg_v5_0_2_set_irq_funcs(struct amdgpu_device *adev) 756 { 757 int i; 758 759 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) 760 adev->jpeg.inst->irq.num_types += adev->jpeg.num_jpeg_rings; 761 762 adev->jpeg.inst->irq.funcs = &jpeg_v5_0_2_irq_funcs; 763 } 764 765 const struct amdgpu_ip_block_version jpeg_v5_0_2_ip_block = { 766 .type = AMD_IP_BLOCK_TYPE_JPEG, 767 .major = 5, 768 .minor = 0, 769 .rev = 2, 770 .funcs = &jpeg_v5_0_2_ip_funcs, 771 }; 772 773 #if 0 774 static int jpeg_v5_0_2_aca_bank_parser(struct aca_handle *handle, struct aca_bank *bank, 775 enum aca_smu_type type, void *data) 776 { 777 struct aca_bank_info info; 778 u64 misc0; 779 int ret; 780 781 ret = aca_bank_info_decode(bank, &info); 782 if (ret) 783 return ret; 784 785 misc0 = bank->regs[ACA_REG_IDX_MISC0]; 786 switch (type) { 787 case ACA_SMU_TYPE_UE: 788 bank->aca_err_type = ACA_ERROR_TYPE_UE; 789 ret = aca_error_cache_log_bank_error(handle, &info, ACA_ERROR_TYPE_UE, 790 1ULL); 791 break; 792 case ACA_SMU_TYPE_CE: 793 bank->aca_err_type = ACA_ERROR_TYPE_CE; 794 ret = aca_error_cache_log_bank_error(handle, &info, bank->aca_err_type, 795 ACA_REG__MISC0__ERRCNT(misc0)); 796 break; 797 default: 798 return -EINVAL; 799 } 800 801 return ret; 802 } 803 804 /* reference to smu driver if header file */ 805 static int jpeg_v5_0_2_err_codes[] = { 806 16, 17, 18, 19, 20, 21, 22, 23, /* JPEG[0-9][S|D] */ 807 24, 25, 26, 27, 28, 29, 30, 31, 808 48, 49, 50, 51, 809 }; 810 811 static bool jpeg_v5_0_2_aca_bank_is_valid(struct aca_handle *handle, struct aca_bank *bank, 812 enum aca_smu_type type, void *data) 813 { 814 u32 instlo; 815 816 instlo = ACA_REG__IPID__INSTANCEIDLO(bank->regs[ACA_REG_IDX_IPID]); 817 instlo &= GENMASK(31, 1); 818 819 if (instlo != mmSMNAID_AID0_MCA_SMU) 820 return false; 821 822 if (aca_bank_check_error_codes(handle->adev, bank, 823 jpeg_v5_0_2_err_codes, 824 ARRAY_SIZE(jpeg_v5_0_2_err_codes))) 825 return false; 826 827 return true; 828 } 829 830 static const struct aca_bank_ops jpeg_v5_0_2_aca_bank_ops = { 831 .aca_bank_parser = jpeg_v5_0_2_aca_bank_parser, 832 .aca_bank_is_valid = jpeg_v5_0_2_aca_bank_is_valid, 833 }; 834 835 static const struct aca_info jpeg_v5_0_2_aca_info = { 836 .hwip = ACA_HWIP_TYPE_SMU, 837 .mask = ACA_ERROR_UE_MASK, 838 .bank_ops = &jpeg_v5_0_2_aca_bank_ops, 839 }; 840 #endif 841