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