Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: add JPEG v2.0 function supports

It got separated from VCN2.0 with a new jpeg_v2_0_ip_block

Signed-off-by: Leo Liu <leo.liu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Leo Liu and committed by
Alex Deucher
6ac27241 2eb16729

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