1/* $NetBSD: amdgpu_jpeg_v2_0.c,v 1.3 2021/12/19 12:02:39 riastradh Exp $ */ 2 3/* 4 * Copyright 2019 Advanced Micro Devices, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 */ 25 26#include <sys/cdefs.h> 27__KERNEL_RCSID(0, "$NetBSD: amdgpu_jpeg_v2_0.c,v 1.3 2021/12/19 12:02:39 riastradh Exp $"); 28 29#include "amdgpu.h" 30#include "amdgpu_jpeg.h" 31#include "amdgpu_pm.h" 32#include "soc15.h" 33#include "soc15d.h" 34 35#include "vcn/vcn_2_0_0_offset.h" 36#include "vcn/vcn_2_0_0_sh_mask.h" 37#include "ivsrcid/vcn/irqsrcs_vcn_2_0.h" 38 39#define mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET 0x1bfff 40#define mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET 0x4029 41#define mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET 0x402a 42#define mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET 0x402b 43#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ea 44#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40eb 45#define mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET 0x40cf 46#define mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET 0x40d1 47#define mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40e8 48#define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40e9 49#define mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET 0x4082 50#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ec 51#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40ed 52#define mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET 0x4085 53#define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET 0x4084 54#define mmUVD_JRBC_STATUS_INTERNAL_OFFSET 0x4089 55#define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f 56 57#define JRBC_DEC_EXTERNAL_REG_WRITE_ADDR 0x18000 58 59static void jpeg_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev); 60static void jpeg_v2_0_set_irq_funcs(struct amdgpu_device *adev); 61static int jpeg_v2_0_set_powergating_state(void *handle, 62 enum amd_powergating_state state); 63 64/** 65 * jpeg_v2_0_early_init - set function pointers 66 * 67 * @handle: amdgpu_device pointer 68 * 69 * Set ring and irq function pointers 70 */ 71static int jpeg_v2_0_early_init(void *handle) 72{ 73 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 74 75 adev->jpeg.num_jpeg_inst = 1; 76 77 jpeg_v2_0_set_dec_ring_funcs(adev); 78 jpeg_v2_0_set_irq_funcs(adev); 79 80 return 0; 81} 82 83/** 84 * jpeg_v2_0_sw_init - sw init for JPEG block 85 * 86 * @handle: amdgpu_device pointer 87 * 88 * Load firmware and sw initialization 89 */ 90static int jpeg_v2_0_sw_init(void *handle) 91{ 92 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 93 struct amdgpu_ring *ring; 94 int r; 95 96 /* JPEG TRAP */ 97 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 98 VCN_2_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq); 99 if (r) 100 return r; 101 102 r = amdgpu_jpeg_sw_init(adev); 103 if (r) 104 return r; 105 106 r = amdgpu_jpeg_resume(adev); 107 if (r) 108 return r; 109 110 ring = &adev->jpeg.inst->ring_dec; 111 ring->use_doorbell = true; 112 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1; 113 snprintf(ring->name, sizeof(ring->name), "jpeg_dec"); 114 r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0); 115 if (r) 116 return r; 117 118 adev->jpeg.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET; 119 adev->jpeg.inst->external.jpeg_pitch = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH); 120 121 return 0; 122} 123 124/** 125 * jpeg_v2_0_sw_fini - sw fini for JPEG block 126 * 127 * @handle: amdgpu_device pointer 128 * 129 * JPEG suspend and free up sw allocation 130 */ 131static int jpeg_v2_0_sw_fini(void *handle) 132{ 133 int r; 134 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 135 136 r = amdgpu_jpeg_suspend(adev); 137 if (r) 138 return r; 139 140 r = amdgpu_jpeg_sw_fini(adev); 141 142 return r; 143} 144 145/** 146 * jpeg_v2_0_hw_init - start and test JPEG block 147 * 148 * @handle: amdgpu_device pointer 149 * 150 */ 151static int jpeg_v2_0_hw_init(void *handle) 152{ 153 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 154 struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec; 155 int r; 156 157 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, 158 (adev->doorbell_index.vcn.vcn_ring0_1 << 1), 0); 159 160 r = amdgpu_ring_test_helper(ring); 161 if (!r) 162 DRM_INFO("JPEG decode initialized successfully.\n"); 163 164 return r; 165} 166 167/** 168 * jpeg_v2_0_hw_fini - stop the hardware block 169 * 170 * @handle: amdgpu_device pointer 171 * 172 * Stop the JPEG block, mark ring as not ready any more 173 */ 174static int jpeg_v2_0_hw_fini(void *handle) 175{ 176 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 177 struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec; 178 179 if (adev->jpeg.cur_state != AMD_PG_STATE_GATE && 180 RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS)) 181 jpeg_v2_0_set_powergating_state(adev, AMD_PG_STATE_GATE); 182 183 ring->sched.ready = false; 184 185 return 0; 186} 187 188/** 189 * jpeg_v2_0_suspend - suspend JPEG block 190 * 191 * @handle: amdgpu_device pointer 192 * 193 * HW fini and suspend JPEG block 194 */ 195static int jpeg_v2_0_suspend(void *handle) 196{ 197 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 198 int r; 199 200 r = jpeg_v2_0_hw_fini(adev); 201 if (r) 202 return r; 203 204 r = amdgpu_jpeg_suspend(adev); 205 206 return r; 207} 208 209/** 210 * jpeg_v2_0_resume - resume JPEG block 211 * 212 * @handle: amdgpu_device pointer 213 * 214 * Resume firmware and hw init JPEG block 215 */ 216static int jpeg_v2_0_resume(void *handle) 217{ 218 int r; 219 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 220 221 r = amdgpu_jpeg_resume(adev); 222 if (r) 223 return r; 224 225 r = jpeg_v2_0_hw_init(adev); 226 227 return r; 228} 229 230static int jpeg_v2_0_disable_power_gating(struct amdgpu_device *adev) 231{ 232 uint32_t data; 233 int r = 0; 234 235 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) { 236 data = 1 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT; 237 WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_PGFSM_CONFIG), data); 238 239 SOC15_WAIT_ON_RREG(JPEG, 0, 240 mmUVD_PGFSM_STATUS, UVD_PGFSM_STATUS_UVDJ_PWR_ON, 241 UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK, r); 242 243 if (r) { 244 DRM_ERROR("amdgpu: JPEG disable power gating failed\n"); 245 return r; 246 } 247 } 248 249 /* Removing the anti hang mechanism to indicate the UVDJ tile is ON */ 250 data = RREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS)) & ~0x1; 251 WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS), data); 252 253 return 0; 254} 255 256static int jpeg_v2_0_enable_power_gating(struct amdgpu_device* adev) 257{ 258 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) { 259 uint32_t data; 260 int r = 0; 261 262 data = RREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS)); 263 data &= ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK; 264 data |= 0x1; //UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_TILES_OFF; 265 WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS), data); 266 267 data = 2 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT; 268 WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_PGFSM_CONFIG), data); 269 270 SOC15_WAIT_ON_RREG(JPEG, 0, mmUVD_PGFSM_STATUS, 271 (2 << UVD_PGFSM_STATUS__UVDJ_PWR_STATUS__SHIFT), 272 UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK, r); 273 274 if (r) { 275 DRM_ERROR("amdgpu: JPEG enable power gating failed\n"); 276 return r; 277 } 278 } 279 280 return 0; 281} 282 283static void jpeg_v2_0_disable_clock_gating(struct amdgpu_device* adev) 284{ 285 uint32_t data; 286 287 data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL); 288 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) 289 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 290 else 291 data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 292 293 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 294 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 295 WREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL, data); 296 297 data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE); 298 data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK 299 | JPEG_CGC_GATE__JPEG2_DEC_MASK 300 | JPEG_CGC_GATE__JPEG_ENC_MASK 301 | JPEG_CGC_GATE__JMCIF_MASK 302 | JPEG_CGC_GATE__JRBBM_MASK); 303 WREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE, data); 304} 305 306static void jpeg_v2_0_enable_clock_gating(struct amdgpu_device* adev) 307{ 308 uint32_t data; 309 310 data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL); 311 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) 312 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 313 else 314 data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 315 316 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 317 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 318 WREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL, data); 319 320 data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE); 321 data |= (JPEG_CGC_GATE__JPEG_DEC_MASK 322 |JPEG_CGC_GATE__JPEG2_DEC_MASK 323 |JPEG_CGC_GATE__JPEG_ENC_MASK 324 |JPEG_CGC_GATE__JMCIF_MASK 325 |JPEG_CGC_GATE__JRBBM_MASK); 326 WREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE, data); 327} 328 329/** 330 * jpeg_v2_0_start - start JPEG block 331 * 332 * @adev: amdgpu_device pointer 333 * 334 * Setup and start the JPEG block 335 */ 336static int jpeg_v2_0_start(struct amdgpu_device *adev) 337{ 338 struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec; 339 int r; 340 341 if (adev->pm.dpm_enabled) 342 amdgpu_dpm_enable_jpeg(adev, true); 343 344 /* disable power gating */ 345 r = jpeg_v2_0_disable_power_gating(adev); 346 if (r) 347 return r; 348 349 /* JPEG disable CGC */ 350 jpeg_v2_0_disable_clock_gating(adev); 351 352 WREG32_SOC15(JPEG, 0, mmJPEG_DEC_GFX10_ADDR_CONFIG, adev->gfx.config.gb_addr_config); 353 354 /* enable JMI channel */ 355 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JMI_CNTL), 0, 356 ~UVD_JMI_CNTL__SOFT_RESET_MASK); 357 358 /* enable System Interrupt for JRBC */ 359 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmJPEG_SYS_INT_EN), 360 JPEG_SYS_INT_EN__DJRBC_MASK, 361 ~JPEG_SYS_INT_EN__DJRBC_MASK); 362 363 WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0); 364 WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L)); 365 WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, 366 lower_32_bits(ring->gpu_addr)); 367 WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, 368 upper_32_bits(ring->gpu_addr)); 369 WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR, 0); 370 WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, 0); 371 WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, 0x00000002L); 372 WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4); 373 ring->wptr = RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR); 374 375 return 0; 376} 377 378/** 379 * jpeg_v2_0_stop - stop JPEG block 380 * 381 * @adev: amdgpu_device pointer 382 * 383 * stop the JPEG block 384 */ 385static int jpeg_v2_0_stop(struct amdgpu_device *adev) 386{ 387 int r; 388 389 /* reset JMI */ 390 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JMI_CNTL), 391 UVD_JMI_CNTL__SOFT_RESET_MASK, 392 ~UVD_JMI_CNTL__SOFT_RESET_MASK); 393 394 /* enable JPEG CGC */ 395 jpeg_v2_0_enable_clock_gating(adev); 396 397 /* enable power gating */ 398 r = jpeg_v2_0_enable_power_gating(adev); 399 if (r) 400 return r; 401 402 if (adev->pm.dpm_enabled) 403 amdgpu_dpm_enable_jpeg(adev, false); 404 405 return 0; 406} 407 408/** 409 * jpeg_v2_0_dec_ring_get_rptr - get read pointer 410 * 411 * @ring: amdgpu_ring pointer 412 * 413 * Returns the current hardware read pointer 414 */ 415static uint64_t jpeg_v2_0_dec_ring_get_rptr(struct amdgpu_ring *ring) 416{ 417 struct amdgpu_device *adev = ring->adev; 418 419 return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR); 420} 421 422/** 423 * jpeg_v2_0_dec_ring_get_wptr - get write pointer 424 * 425 * @ring: amdgpu_ring pointer 426 * 427 * Returns the current hardware write pointer 428 */ 429static uint64_t jpeg_v2_0_dec_ring_get_wptr(struct amdgpu_ring *ring) 430{ 431 struct amdgpu_device *adev = ring->adev; 432 433 if (ring->use_doorbell) 434 return adev->wb.wb[ring->wptr_offs]; 435 else 436 return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR); 437} 438 439/** 440 * jpeg_v2_0_dec_ring_set_wptr - set write pointer 441 * 442 * @ring: amdgpu_ring pointer 443 * 444 * Commits the write pointer to the hardware 445 */ 446static void jpeg_v2_0_dec_ring_set_wptr(struct amdgpu_ring *ring) 447{ 448 struct amdgpu_device *adev = ring->adev; 449 450 if (ring->use_doorbell) { 451 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr); 452 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 453 } else { 454 WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); 455 } 456} 457 458/** 459 * jpeg_v2_0_dec_ring_insert_start - insert a start command 460 * 461 * @ring: amdgpu_ring pointer 462 * 463 * Write a start command to the ring. 464 */ 465void jpeg_v2_0_dec_ring_insert_start(struct amdgpu_ring *ring) 466{ 467 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, 468 0, 0, PACKETJ_TYPE0)); 469 amdgpu_ring_write(ring, 0x68e04); 470 471 amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 472 0, 0, PACKETJ_TYPE0)); 473 amdgpu_ring_write(ring, 0x80010000); 474} 475 476/** 477 * jpeg_v2_0_dec_ring_insert_end - insert a end command 478 * 479 * @ring: amdgpu_ring pointer 480 * 481 * Write a end command to the ring. 482 */ 483void jpeg_v2_0_dec_ring_insert_end(struct amdgpu_ring *ring) 484{ 485 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, 486 0, 0, PACKETJ_TYPE0)); 487 amdgpu_ring_write(ring, 0x68e04); 488 489 amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 490 0, 0, PACKETJ_TYPE0)); 491 amdgpu_ring_write(ring, 0x00010000); 492} 493 494/** 495 * jpeg_v2_0_dec_ring_emit_fence - emit an fence & trap command 496 * 497 * @ring: amdgpu_ring pointer 498 * @fence: fence to emit 499 * 500 * Write a fence and a trap command to the ring. 501 */ 502void jpeg_v2_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, 503 unsigned flags) 504{ 505 WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); 506 507 amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET, 508 0, 0, PACKETJ_TYPE0)); 509 amdgpu_ring_write(ring, seq); 510 511 amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET, 512 0, 0, PACKETJ_TYPE0)); 513 amdgpu_ring_write(ring, seq); 514 515 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET, 516 0, 0, PACKETJ_TYPE0)); 517 amdgpu_ring_write(ring, lower_32_bits(addr)); 518 519 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET, 520 0, 0, PACKETJ_TYPE0)); 521 amdgpu_ring_write(ring, upper_32_bits(addr)); 522 523 amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET, 524 0, 0, PACKETJ_TYPE0)); 525 amdgpu_ring_write(ring, 0x8); 526 527 amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET, 528 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4)); 529 amdgpu_ring_write(ring, 0); 530 531 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, 532 0, 0, PACKETJ_TYPE0)); 533 amdgpu_ring_write(ring, 0x3fbc); 534 535 amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 536 0, 0, PACKETJ_TYPE0)); 537 amdgpu_ring_write(ring, 0x1); 538 539 amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7)); 540 amdgpu_ring_write(ring, 0); 541} 542 543/** 544 * jpeg_v2_0_dec_ring_emit_ib - execute indirect buffer 545 * 546 * @ring: amdgpu_ring pointer 547 * @ib: indirect buffer to execute 548 * 549 * Write ring commands to execute the indirect buffer. 550 */ 551void jpeg_v2_0_dec_ring_emit_ib(struct amdgpu_ring *ring, 552 struct amdgpu_job *job, 553 struct amdgpu_ib *ib, 554 uint32_t flags) 555{ 556 unsigned vmid = AMDGPU_JOB_GET_VMID(job); 557 558 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET, 559 0, 0, PACKETJ_TYPE0)); 560 amdgpu_ring_write(ring, (vmid | (vmid << 4))); 561 562 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET, 563 0, 0, PACKETJ_TYPE0)); 564 amdgpu_ring_write(ring, (vmid | (vmid << 4))); 565 566 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET, 567 0, 0, PACKETJ_TYPE0)); 568 amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); 569 570 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET, 571 0, 0, PACKETJ_TYPE0)); 572 amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); 573 574 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET, 575 0, 0, PACKETJ_TYPE0)); 576 amdgpu_ring_write(ring, ib->length_dw); 577 578 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET, 579 0, 0, PACKETJ_TYPE0)); 580 amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr)); 581 582 amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET, 583 0, 0, PACKETJ_TYPE0)); 584 amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr)); 585 586 amdgpu_ring_write(ring, PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2)); 587 amdgpu_ring_write(ring, 0); 588 589 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET, 590 0, 0, PACKETJ_TYPE0)); 591 amdgpu_ring_write(ring, 0x01400200); 592 593 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET, 594 0, 0, PACKETJ_TYPE0)); 595 amdgpu_ring_write(ring, 0x2); 596 597 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_STATUS_INTERNAL_OFFSET, 598 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3)); 599 amdgpu_ring_write(ring, 0x2); 600} 601 602void jpeg_v2_0_dec_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg, 603 uint32_t val, uint32_t mask) 604{ 605 uint32_t reg_offset = (reg << 2); 606 607 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET, 608 0, 0, PACKETJ_TYPE0)); 609 amdgpu_ring_write(ring, 0x01400200); 610 611 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET, 612 0, 0, PACKETJ_TYPE0)); 613 amdgpu_ring_write(ring, val); 614 615 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, 616 0, 0, PACKETJ_TYPE0)); 617 if (reg_offset >= 0x10000 && reg_offset <= 0x105ff) { 618 amdgpu_ring_write(ring, 0); 619 amdgpu_ring_write(ring, 620 PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3)); 621 } else { 622 amdgpu_ring_write(ring, reg_offset); 623 amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 624 0, 0, PACKETJ_TYPE3)); 625 } 626 amdgpu_ring_write(ring, mask); 627} 628 629void jpeg_v2_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring, 630 unsigned vmid, uint64_t pd_addr) 631{ 632 struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub]; 633 uint32_t data0, data1, mask; 634 635 pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr); 636 637 /* wait for register write */ 638 data0 = hub->ctx0_ptb_addr_lo32 + vmid * 2; 639 data1 = lower_32_bits(pd_addr); 640 mask = 0xffffffff; 641 jpeg_v2_0_dec_ring_emit_reg_wait(ring, data0, data1, mask); 642} 643 644void jpeg_v2_0_dec_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_t val) 645{ 646 uint32_t reg_offset = (reg << 2); 647 648 amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, 649 0, 0, PACKETJ_TYPE0)); 650 if (reg_offset >= 0x10000 && reg_offset <= 0x105ff) { 651 amdgpu_ring_write(ring, 0); 652 amdgpu_ring_write(ring, 653 PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0)); 654 } else { 655 amdgpu_ring_write(ring, reg_offset); 656 amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 657 0, 0, PACKETJ_TYPE0)); 658 } 659 amdgpu_ring_write(ring, val); 660} 661 662void jpeg_v2_0_dec_ring_nop(struct amdgpu_ring *ring, uint32_t count) 663{ 664 int i; 665 666 WARN_ON(ring->wptr % 2 || count % 2); 667 668 for (i = 0; i < count / 2; i++) { 669 amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6)); 670 amdgpu_ring_write(ring, 0); 671 } 672} 673 674static bool jpeg_v2_0_is_idle(void *handle) 675{ 676 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 677 678 return ((RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS) & 679 UVD_JRBC_STATUS__RB_JOB_DONE_MASK) == 680 UVD_JRBC_STATUS__RB_JOB_DONE_MASK); 681} 682 683static int jpeg_v2_0_wait_for_idle(void *handle) 684{ 685 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 686 int ret = 0; 687 688 SOC15_WAIT_ON_RREG(JPEG, 0, mmUVD_JRBC_STATUS, UVD_JRBC_STATUS__RB_JOB_DONE_MASK, 689 UVD_JRBC_STATUS__RB_JOB_DONE_MASK, ret); 690 691 return ret; 692} 693 694static int jpeg_v2_0_set_clockgating_state(void *handle, 695 enum amd_clockgating_state state) 696{ 697 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 698 bool enable = (state == AMD_CG_STATE_GATE); 699 700 if (enable) { 701 if (jpeg_v2_0_is_idle(handle)) 702 return -EBUSY; 703 jpeg_v2_0_enable_clock_gating(adev); 704 } else { 705 jpeg_v2_0_disable_clock_gating(adev); 706 } 707 708 return 0; 709} 710 711static int jpeg_v2_0_set_powergating_state(void *handle, 712 enum amd_powergating_state state) 713{ 714 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 715 int ret; 716 717 if (state == adev->jpeg.cur_state) 718 return 0; 719 720 if (state == AMD_PG_STATE_GATE) 721 ret = jpeg_v2_0_stop(adev); 722 else 723 ret = jpeg_v2_0_start(adev); 724 725 if (!ret) 726 adev->jpeg.cur_state = state; 727 728 return ret; 729} 730 731static int jpeg_v2_0_set_interrupt_state(struct amdgpu_device *adev, 732 struct amdgpu_irq_src *source, 733 unsigned type, 734 enum amdgpu_interrupt_state state) 735{ 736 return 0; 737} 738 739static int jpeg_v2_0_process_interrupt(struct amdgpu_device *adev, 740 struct amdgpu_irq_src *source, 741 struct amdgpu_iv_entry *entry) 742{ 743 DRM_DEBUG("IH: JPEG TRAP\n"); 744 745 switch (entry->src_id) { 746 case VCN_2_0__SRCID__JPEG_DECODE: 747 amdgpu_fence_process(&adev->jpeg.inst->ring_dec); 748 break; 749 default: 750 DRM_ERROR("Unhandled interrupt: %d %d\n", 751 entry->src_id, entry->src_data[0]); 752 break; 753 } 754 755 return 0; 756} 757 758static const struct amd_ip_funcs jpeg_v2_0_ip_funcs = { 759 .name = "jpeg_v2_0", 760 .early_init = jpeg_v2_0_early_init, 761 .late_init = NULL, 762 .sw_init = jpeg_v2_0_sw_init, 763 .sw_fini = jpeg_v2_0_sw_fini, 764 .hw_init = jpeg_v2_0_hw_init, 765 .hw_fini = jpeg_v2_0_hw_fini, 766 .suspend = jpeg_v2_0_suspend, 767 .resume = jpeg_v2_0_resume, 768 .is_idle = jpeg_v2_0_is_idle, 769 .wait_for_idle = jpeg_v2_0_wait_for_idle, 770 .check_soft_reset = NULL, 771 .pre_soft_reset = NULL, 772 .soft_reset = NULL, 773 .post_soft_reset = NULL, 774 .set_clockgating_state = jpeg_v2_0_set_clockgating_state, 775 .set_powergating_state = jpeg_v2_0_set_powergating_state, 776}; 777 778static const struct amdgpu_ring_funcs jpeg_v2_0_dec_ring_vm_funcs = { 779 .type = AMDGPU_RING_TYPE_VCN_JPEG, 780 .align_mask = 0xf, 781 .vmhub = AMDGPU_MMHUB_0, 782 .get_rptr = jpeg_v2_0_dec_ring_get_rptr, 783 .get_wptr = jpeg_v2_0_dec_ring_get_wptr, 784 .set_wptr = jpeg_v2_0_dec_ring_set_wptr, 785 .emit_frame_size = 786 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + 787 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + 788 8 + /* jpeg_v2_0_dec_ring_emit_vm_flush */ 789 18 + 18 + /* jpeg_v2_0_dec_ring_emit_fence x2 vm fence */ 790 8 + 16, 791 .emit_ib_size = 22, /* jpeg_v2_0_dec_ring_emit_ib */ 792 .emit_ib = jpeg_v2_0_dec_ring_emit_ib, 793 .emit_fence = jpeg_v2_0_dec_ring_emit_fence, 794 .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush, 795 .test_ring = amdgpu_jpeg_dec_ring_test_ring, 796 .test_ib = amdgpu_jpeg_dec_ring_test_ib, 797 .insert_nop = jpeg_v2_0_dec_ring_nop, 798 .insert_start = jpeg_v2_0_dec_ring_insert_start, 799 .insert_end = jpeg_v2_0_dec_ring_insert_end, 800 .pad_ib = amdgpu_ring_generic_pad_ib, 801 .begin_use = amdgpu_jpeg_ring_begin_use, 802 .end_use = amdgpu_jpeg_ring_end_use, 803 .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg, 804 .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait, 805 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 806}; 807 808static void jpeg_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev) 809{ 810 adev->jpeg.inst->ring_dec.funcs = &jpeg_v2_0_dec_ring_vm_funcs; 811 DRM_INFO("JPEG decode is enabled in VM mode\n"); 812} 813 814static const struct amdgpu_irq_src_funcs jpeg_v2_0_irq_funcs = { 815 .set = jpeg_v2_0_set_interrupt_state, 816 .process = jpeg_v2_0_process_interrupt, 817}; 818 819static void jpeg_v2_0_set_irq_funcs(struct amdgpu_device *adev) 820{ 821 adev->jpeg.inst->irq.num_types = 1; 822 adev->jpeg.inst->irq.funcs = &jpeg_v2_0_irq_funcs; 823} 824 825const struct amdgpu_ip_block_version jpeg_v2_0_ip_block = 826{ 827 .type = AMD_IP_BLOCK_TYPE_JPEG, 828 .major = 2, 829 .minor = 0, 830 .rev = 0, 831 .funcs = &jpeg_v2_0_ip_funcs, 832}; 833