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

drm/amdgpu: add JPEG3.0 support for Sienna_Cichlid

With basic IP block functions and ring functions

Signed-off-by: Leo Liu <leo.liu@amd.com>
Reviewed-by: James Zhu <James.Zhu@amd.com>
Acked-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
dfd57dbf b8f10585

+515 -1
+2 -1
drivers/gpu/drm/amd/amdgpu/Makefile
··· 159 159 amdgpu_jpeg.o \ 160 160 jpeg_v1_0.o \ 161 161 jpeg_v2_0.o \ 162 - jpeg_v2_5.o 162 + jpeg_v2_5.o \ 163 + jpeg_v3_0.o 163 164 164 165 # add ATHUB block 165 166 amdgpu-y += \
+484
drivers/gpu/drm/amd/amdgpu/jpeg_v3_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 + #include "jpeg_v2_0.h" 30 + 31 + #include "vcn/vcn_3_0_0_offset.h" 32 + #include "vcn/vcn_3_0_0_sh_mask.h" 33 + #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h" 34 + 35 + #define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f 36 + 37 + static void jpeg_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev); 38 + static void jpeg_v3_0_set_irq_funcs(struct amdgpu_device *adev); 39 + static int jpeg_v3_0_set_powergating_state(void *handle, 40 + enum amd_powergating_state state); 41 + 42 + /** 43 + * jpeg_v3_0_early_init - set function pointers 44 + * 45 + * @handle: amdgpu_device pointer 46 + * 47 + * Set ring and irq function pointers 48 + */ 49 + static int jpeg_v3_0_early_init(void *handle) 50 + { 51 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 52 + if (adev->asic_type == CHIP_SIENNA_CICHLID) { 53 + u32 harvest = RREG32_SOC15(JPEG, 0, mmCC_UVD_HARVESTING); 54 + 55 + if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK) 56 + return -ENOENT; 57 + } 58 + adev->jpeg.num_jpeg_inst = 1; 59 + 60 + jpeg_v3_0_set_dec_ring_funcs(adev); 61 + jpeg_v3_0_set_irq_funcs(adev); 62 + 63 + return 0; 64 + } 65 + 66 + /** 67 + * jpeg_v3_0_sw_init - sw init for JPEG block 68 + * 69 + * @handle: amdgpu_device pointer 70 + * 71 + * Load firmware and sw initialization 72 + */ 73 + static int jpeg_v3_0_sw_init(void *handle) 74 + { 75 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 76 + struct amdgpu_ring *ring; 77 + int r; 78 + 79 + /* JPEG TRAP */ 80 + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 81 + VCN_2_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq); 82 + if (r) 83 + return r; 84 + 85 + r = amdgpu_jpeg_sw_init(adev); 86 + if (r) 87 + return r; 88 + 89 + r = amdgpu_jpeg_resume(adev); 90 + if (r) 91 + return r; 92 + 93 + ring = &adev->jpeg.inst->ring_dec; 94 + ring->use_doorbell = true; 95 + ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1; 96 + sprintf(ring->name, "jpeg_dec"); 97 + r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0, 98 + AMDGPU_RING_PRIO_DEFAULT); 99 + if (r) 100 + return r; 101 + 102 + adev->jpeg.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET; 103 + adev->jpeg.inst->external.jpeg_pitch = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH); 104 + 105 + return 0; 106 + } 107 + 108 + /** 109 + * jpeg_v3_0_sw_fini - sw fini for JPEG block 110 + * 111 + * @handle: amdgpu_device pointer 112 + * 113 + * JPEG suspend and free up sw allocation 114 + */ 115 + static int jpeg_v3_0_sw_fini(void *handle) 116 + { 117 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 118 + int r; 119 + 120 + r = amdgpu_jpeg_suspend(adev); 121 + if (r) 122 + return r; 123 + 124 + r = amdgpu_jpeg_sw_fini(adev); 125 + 126 + return r; 127 + } 128 + 129 + /** 130 + * jpeg_v3_0_hw_init - start and test JPEG block 131 + * 132 + * @handle: amdgpu_device pointer 133 + * 134 + */ 135 + static int jpeg_v3_0_hw_init(void *handle) 136 + { 137 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 138 + struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec; 139 + int r; 140 + 141 + adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, 142 + (adev->doorbell_index.vcn.vcn_ring0_1 << 1), 0); 143 + 144 + r = amdgpu_ring_test_helper(ring); 145 + if (r) 146 + return r; 147 + 148 + DRM_INFO("JPEG decode initialized successfully.\n"); 149 + 150 + return 0; 151 + } 152 + 153 + /** 154 + * jpeg_v3_0_hw_fini - stop the hardware block 155 + * 156 + * @handle: amdgpu_device pointer 157 + * 158 + * Stop the JPEG block, mark ring as not ready any more 159 + */ 160 + static int jpeg_v3_0_hw_fini(void *handle) 161 + { 162 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 163 + struct amdgpu_ring *ring; 164 + 165 + ring = &adev->jpeg.inst->ring_dec; 166 + if (adev->jpeg.cur_state != AMD_PG_STATE_GATE && 167 + RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS)) 168 + jpeg_v3_0_set_powergating_state(adev, AMD_PG_STATE_GATE); 169 + 170 + ring->sched.ready = false; 171 + 172 + return 0; 173 + } 174 + 175 + /** 176 + * jpeg_v3_0_suspend - suspend JPEG block 177 + * 178 + * @handle: amdgpu_device pointer 179 + * 180 + * HW fini and suspend JPEG block 181 + */ 182 + static int jpeg_v3_0_suspend(void *handle) 183 + { 184 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 185 + int r; 186 + 187 + r = jpeg_v3_0_hw_fini(adev); 188 + if (r) 189 + return r; 190 + 191 + r = amdgpu_jpeg_suspend(adev); 192 + 193 + return r; 194 + } 195 + 196 + /** 197 + * jpeg_v3_0_resume - resume JPEG block 198 + * 199 + * @handle: amdgpu_device pointer 200 + * 201 + * Resume firmware and hw init JPEG block 202 + */ 203 + static int jpeg_v3_0_resume(void *handle) 204 + { 205 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 206 + int r; 207 + 208 + r = amdgpu_jpeg_resume(adev); 209 + if (r) 210 + return r; 211 + 212 + r = jpeg_v3_0_hw_init(adev); 213 + 214 + return r; 215 + } 216 + 217 + /** 218 + * jpeg_v3_0_start - start JPEG block 219 + * 220 + * @adev: amdgpu_device pointer 221 + * 222 + * Setup and start the JPEG block 223 + */ 224 + static int jpeg_v3_0_start(struct amdgpu_device *adev) 225 + { 226 + struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec; 227 + 228 + if (adev->pm.dpm_enabled) 229 + amdgpu_dpm_enable_jpeg(adev, true); 230 + 231 + /* MJPEG global tiling registers */ 232 + WREG32_SOC15(JPEG, 0, mmJPEG_DEC_GFX10_ADDR_CONFIG, 233 + adev->gfx.config.gb_addr_config); 234 + WREG32_SOC15(JPEG, 0, mmJPEG_ENC_GFX10_ADDR_CONFIG, 235 + adev->gfx.config.gb_addr_config); 236 + 237 + /* enable JMI channel */ 238 + WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JMI_CNTL), 0, 239 + ~UVD_JMI_CNTL__SOFT_RESET_MASK); 240 + 241 + /* enable System Interrupt for JRBC */ 242 + WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmJPEG_SYS_INT_EN), 243 + JPEG_SYS_INT_EN__DJRBC_MASK, 244 + ~JPEG_SYS_INT_EN__DJRBC_MASK); 245 + 246 + WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0); 247 + WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L)); 248 + WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, 249 + lower_32_bits(ring->gpu_addr)); 250 + WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, 251 + upper_32_bits(ring->gpu_addr)); 252 + WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR, 0); 253 + WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, 0); 254 + WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, 0x00000002L); 255 + WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4); 256 + ring->wptr = RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR); 257 + 258 + return 0; 259 + } 260 + 261 + /** 262 + * jpeg_v3_0_stop - stop JPEG block 263 + * 264 + * @adev: amdgpu_device pointer 265 + * 266 + * stop the JPEG block 267 + */ 268 + static int jpeg_v3_0_stop(struct amdgpu_device *adev) 269 + { 270 + /* reset JMI */ 271 + WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JMI_CNTL), 272 + UVD_JMI_CNTL__SOFT_RESET_MASK, 273 + ~UVD_JMI_CNTL__SOFT_RESET_MASK); 274 + 275 + if (adev->pm.dpm_enabled) 276 + amdgpu_dpm_enable_jpeg(adev, false); 277 + 278 + return 0; 279 + } 280 + 281 + /** 282 + * jpeg_v3_0_dec_ring_get_rptr - get read pointer 283 + * 284 + * @ring: amdgpu_ring pointer 285 + * 286 + * Returns the current hardware read pointer 287 + */ 288 + static uint64_t jpeg_v3_0_dec_ring_get_rptr(struct amdgpu_ring *ring) 289 + { 290 + struct amdgpu_device *adev = ring->adev; 291 + 292 + return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR); 293 + } 294 + 295 + /** 296 + * jpeg_v3_0_dec_ring_get_wptr - get write pointer 297 + * 298 + * @ring: amdgpu_ring pointer 299 + * 300 + * Returns the current hardware write pointer 301 + */ 302 + static uint64_t jpeg_v3_0_dec_ring_get_wptr(struct amdgpu_ring *ring) 303 + { 304 + struct amdgpu_device *adev = ring->adev; 305 + 306 + if (ring->use_doorbell) 307 + return adev->wb.wb[ring->wptr_offs]; 308 + else 309 + return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR); 310 + } 311 + 312 + /** 313 + * jpeg_v3_0_dec_ring_set_wptr - set write pointer 314 + * 315 + * @ring: amdgpu_ring pointer 316 + * 317 + * Commits the write pointer to the hardware 318 + */ 319 + static void jpeg_v3_0_dec_ring_set_wptr(struct amdgpu_ring *ring) 320 + { 321 + struct amdgpu_device *adev = ring->adev; 322 + 323 + if (ring->use_doorbell) { 324 + adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr); 325 + WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr)); 326 + } else { 327 + WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr)); 328 + } 329 + } 330 + 331 + static bool jpeg_v3_0_is_idle(void *handle) 332 + { 333 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 334 + int ret = 1; 335 + 336 + ret &= (((RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS) & 337 + UVD_JRBC_STATUS__RB_JOB_DONE_MASK) == 338 + UVD_JRBC_STATUS__RB_JOB_DONE_MASK)); 339 + 340 + return ret; 341 + } 342 + 343 + static int jpeg_v3_0_wait_for_idle(void *handle) 344 + { 345 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 346 + int ret = 0; 347 + 348 + SOC15_WAIT_ON_RREG(JPEG, 0, mmUVD_JRBC_STATUS, 349 + UVD_JRBC_STATUS__RB_JOB_DONE_MASK, 350 + UVD_JRBC_STATUS__RB_JOB_DONE_MASK, ret); 351 + if (ret) 352 + return ret; 353 + 354 + return ret; 355 + } 356 + 357 + static int jpeg_v3_0_set_clockgating_state(void *handle, 358 + enum amd_clockgating_state state) 359 + { 360 + return 0; 361 + } 362 + 363 + static int jpeg_v3_0_set_powergating_state(void *handle, 364 + enum amd_powergating_state state) 365 + { 366 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 367 + int ret; 368 + 369 + if(state == adev->jpeg.cur_state) 370 + return 0; 371 + 372 + if (state == AMD_PG_STATE_GATE) 373 + ret = jpeg_v3_0_stop(adev); 374 + else 375 + ret = jpeg_v3_0_start(adev); 376 + 377 + if(!ret) 378 + adev->jpeg.cur_state = state; 379 + 380 + return ret; 381 + } 382 + 383 + static int jpeg_v3_0_set_interrupt_state(struct amdgpu_device *adev, 384 + struct amdgpu_irq_src *source, 385 + unsigned type, 386 + enum amdgpu_interrupt_state state) 387 + { 388 + return 0; 389 + } 390 + 391 + static int jpeg_v3_0_process_interrupt(struct amdgpu_device *adev, 392 + struct amdgpu_irq_src *source, 393 + struct amdgpu_iv_entry *entry) 394 + { 395 + DRM_DEBUG("IH: JPEG TRAP\n"); 396 + 397 + switch (entry->src_id) { 398 + case VCN_2_0__SRCID__JPEG_DECODE: 399 + amdgpu_fence_process(&adev->jpeg.inst->ring_dec); 400 + break; 401 + default: 402 + DRM_ERROR("Unhandled interrupt: %d %d\n", 403 + entry->src_id, entry->src_data[0]); 404 + break; 405 + } 406 + 407 + return 0; 408 + } 409 + 410 + static const struct amd_ip_funcs jpeg_v3_0_ip_funcs = { 411 + .name = "jpeg_v3_0", 412 + .early_init = jpeg_v3_0_early_init, 413 + .late_init = NULL, 414 + .sw_init = jpeg_v3_0_sw_init, 415 + .sw_fini = jpeg_v3_0_sw_fini, 416 + .hw_init = jpeg_v3_0_hw_init, 417 + .hw_fini = jpeg_v3_0_hw_fini, 418 + .suspend = jpeg_v3_0_suspend, 419 + .resume = jpeg_v3_0_resume, 420 + .is_idle = jpeg_v3_0_is_idle, 421 + .wait_for_idle = jpeg_v3_0_wait_for_idle, 422 + .check_soft_reset = NULL, 423 + .pre_soft_reset = NULL, 424 + .soft_reset = NULL, 425 + .post_soft_reset = NULL, 426 + .set_clockgating_state = jpeg_v3_0_set_clockgating_state, 427 + .set_powergating_state = jpeg_v3_0_set_powergating_state, 428 + }; 429 + 430 + static const struct amdgpu_ring_funcs jpeg_v3_0_dec_ring_vm_funcs = { 431 + .type = AMDGPU_RING_TYPE_VCN_JPEG, 432 + .align_mask = 0xf, 433 + .vmhub = AMDGPU_MMHUB_0, 434 + .get_rptr = jpeg_v3_0_dec_ring_get_rptr, 435 + .get_wptr = jpeg_v3_0_dec_ring_get_wptr, 436 + .set_wptr = jpeg_v3_0_dec_ring_set_wptr, 437 + .emit_frame_size = 438 + SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 + 439 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 + 440 + 8 + /* jpeg_v3_0_dec_ring_emit_vm_flush */ 441 + 18 + 18 + /* jpeg_v3_0_dec_ring_emit_fence x2 vm fence */ 442 + 8 + 16, 443 + .emit_ib_size = 22, /* jpeg_v3_0_dec_ring_emit_ib */ 444 + .emit_ib = jpeg_v2_0_dec_ring_emit_ib, 445 + .emit_fence = jpeg_v2_0_dec_ring_emit_fence, 446 + .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush, 447 + .test_ring = amdgpu_jpeg_dec_ring_test_ring, 448 + .test_ib = amdgpu_jpeg_dec_ring_test_ib, 449 + .insert_nop = jpeg_v2_0_dec_ring_nop, 450 + .insert_start = jpeg_v2_0_dec_ring_insert_start, 451 + .insert_end = jpeg_v2_0_dec_ring_insert_end, 452 + .pad_ib = amdgpu_ring_generic_pad_ib, 453 + .begin_use = amdgpu_jpeg_ring_begin_use, 454 + .end_use = amdgpu_jpeg_ring_end_use, 455 + .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg, 456 + .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait, 457 + .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, 458 + }; 459 + 460 + static void jpeg_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev) 461 + { 462 + adev->jpeg.inst->ring_dec.funcs = &jpeg_v3_0_dec_ring_vm_funcs; 463 + DRM_INFO("JPEG decode is enabled in VM mode\n"); 464 + } 465 + 466 + static const struct amdgpu_irq_src_funcs jpeg_v3_0_irq_funcs = { 467 + .set = jpeg_v3_0_set_interrupt_state, 468 + .process = jpeg_v3_0_process_interrupt, 469 + }; 470 + 471 + static void jpeg_v3_0_set_irq_funcs(struct amdgpu_device *adev) 472 + { 473 + adev->jpeg.inst->irq.num_types = 1; 474 + adev->jpeg.inst->irq.funcs = &jpeg_v3_0_irq_funcs; 475 + } 476 + 477 + const struct amdgpu_ip_block_version jpeg_v3_0_ip_block = 478 + { 479 + .type = AMD_IP_BLOCK_TYPE_JPEG, 480 + .major = 3, 481 + .minor = 0, 482 + .rev = 0, 483 + .funcs = &jpeg_v3_0_ip_funcs, 484 + };
+29
drivers/gpu/drm/amd/amdgpu/jpeg_v3_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_V3_0_H__ 25 + #define __JPEG_V3_0_H__ 26 + 27 + extern const struct amdgpu_ip_block_version jpeg_v3_0_ip_block; 28 + 29 + #endif /* __JPEG_V3_0_H__ */