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

drm/amdgpu/jpeg5: Add support for DPG mode

Add DPG support for JPEG 5.0

Signed-off-by: Sonny Jiang <sonjiang@amd.com>
Acked-by: Saleemkhan Jamadar <saleemkhan.jamadar@amd.com>
Reviewed-by: David (Ming Qiang) Wu <David.Wu3@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Sonny Jiang and committed by
Alex Deucher
d4b8386c 291af3f5

+180 -17
+31
drivers/gpu/drm/amd/amdgpu/amdgpu_jpeg.h
··· 60 60 RREG32_SOC15(JPEG, inst_idx, mmUVD_DPG_LMA_DATA); \ 61 61 }) 62 62 63 + #define WREG32_SOC24_JPEG_DPG_MODE(inst_idx, offset, value, indirect) \ 64 + do { \ 65 + WREG32_SOC15(JPEG, GET_INST(JPEG, inst_idx), \ 66 + regUVD_DPG_LMA_DATA, value); \ 67 + WREG32_SOC15(JPEG, GET_INST(JPEG, inst_idx), \ 68 + regUVD_DPG_LMA_MASK, 0xFFFFFFFF); \ 69 + WREG32_SOC15( \ 70 + JPEG, GET_INST(JPEG, inst_idx), \ 71 + regUVD_DPG_LMA_CTL, \ 72 + (UVD_DPG_LMA_CTL__READ_WRITE_MASK | \ 73 + offset << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT | \ 74 + indirect << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT)); \ 75 + } while (0) 76 + 77 + #define RREG32_SOC24_JPEG_DPG_MODE(inst_idx, offset, mask_en) \ 78 + do { \ 79 + WREG32_SOC15(JPEG, GET_INST(JPEG, inst_idx), \ 80 + regUVD_DPG_LMA_MASK, 0xFFFFFFFF); \ 81 + WREG32_SOC15(JPEG, GET_INST(JPEG, inst_idx), \ 82 + regUVD_DPG_LMA_CTL, \ 83 + (UVD_DPG_LMA_CTL__MASK_EN_MASK | \ 84 + offset << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT)); \ 85 + RREG32_SOC15(JPEG, inst_idx, regUVD_DPG_LMA_DATA); \ 86 + } while (0) 87 + 88 + #define ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, offset, value, indirect) \ 89 + do { \ 90 + *adev->jpeg.inst[inst_idx].dpg_sram_curr_addr++ = offset; \ 91 + *adev->jpeg.inst[inst_idx].dpg_sram_curr_addr++ = value; \ 92 + } while (0) 93 + 63 94 struct amdgpu_jpeg_reg{ 64 95 unsigned jpeg_pitch[AMDGPU_MAX_JPEG_RINGS]; 65 96 };
+142 -17
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c
··· 31 31 #include "vcn/vcn_5_0_0_offset.h" 32 32 #include "vcn/vcn_5_0_0_sh_mask.h" 33 33 #include "ivsrcid/vcn/irqsrcs_vcn_4_0.h" 34 + #include "jpeg_v5_0_0.h" 34 35 35 36 static void jpeg_v5_0_0_set_dec_ring_funcs(struct amdgpu_device *adev); 36 37 static void jpeg_v5_0_0_set_irq_funcs(struct amdgpu_device *adev); ··· 138 137 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell, 139 138 (adev->doorbell_index.vcn.vcn_ring0_1 << 1), 0); 140 139 140 + /* Skip ring test because pause DPG is not implemented. */ 141 + if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) 142 + return 0; 143 + 141 144 r = amdgpu_ring_test_helper(ring); 142 145 if (r) 143 146 return r; ··· 240 235 WREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE, data); 241 236 } 242 237 243 - static int jpeg_v5_0_0_disable_static_power_gating(struct amdgpu_device *adev) 238 + static int jpeg_v5_0_0_disable_power_gating(struct amdgpu_device *adev) 244 239 { 245 240 uint32_t data = 0; 246 241 ··· 253 248 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS), 0, 254 249 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK); 255 250 256 - /* keep the JPEG in static PG mode */ 257 - WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS), 0, 258 - ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK); 259 - 260 251 return 0; 261 252 } 262 253 263 - static int jpeg_v5_0_0_enable_static_power_gating(struct amdgpu_device *adev) 254 + static int jpeg_v5_0_0_enable_power_gating(struct amdgpu_device *adev) 264 255 { 265 256 /* enable anti hang mechanism */ 266 257 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS), ··· 274 273 return 0; 275 274 } 276 275 276 + static void jpeg_engine_5_0_0_dpg_clock_gating_mode(struct amdgpu_device *adev, 277 + int inst_idx, uint8_t indirect) 278 + { 279 + uint32_t data = 0; 280 + 281 + // JPEG disable CGC 282 + if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) 283 + data = 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 284 + else 285 + data = 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; 286 + 287 + data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; 288 + data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT; 289 + 290 + if (indirect) { 291 + ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_CGC_CTRL, data, indirect); 292 + 293 + // Turn on All JPEG clocks 294 + data = 0; 295 + ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_CGC_GATE, data, indirect); 296 + } else { 297 + WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_CGC_CTRL, data, indirect); 298 + 299 + // Turn on All JPEG clocks 300 + data = 0; 301 + WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_CGC_GATE, data, indirect); 302 + } 303 + } 304 + 305 + /** 306 + * jpeg_v5_0_0_start_dpg_mode - Jpeg start with dpg mode 307 + * 308 + * @adev: amdgpu_device pointer 309 + * @inst_idx: instance number index 310 + * @indirect: indirectly write sram 311 + * 312 + * Start JPEG block with dpg mode 313 + */ 314 + static int jpeg_v5_0_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect) 315 + { 316 + struct amdgpu_ring *ring = adev->jpeg.inst[inst_idx].ring_dec; 317 + uint32_t reg_data = 0; 318 + 319 + jpeg_v5_0_0_enable_power_gating(adev); 320 + 321 + // enable dynamic power gating mode 322 + reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS); 323 + reg_data |= UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK; 324 + WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data); 325 + 326 + if (indirect) 327 + adev->jpeg.inst[inst_idx].dpg_sram_curr_addr = 328 + (uint32_t *)adev->jpeg.inst[inst_idx].dpg_sram_cpu_addr; 329 + 330 + jpeg_engine_5_0_0_dpg_clock_gating_mode(adev, inst_idx, indirect); 331 + 332 + /* MJPEG global tiling registers */ 333 + if (indirect) 334 + ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_DEC_GFX10_ADDR_CONFIG, 335 + adev->gfx.config.gb_addr_config, indirect); 336 + else 337 + WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_DEC_GFX10_ADDR_CONFIG, 338 + adev->gfx.config.gb_addr_config, 1); 339 + 340 + /* enable System Interrupt for JRBC */ 341 + if (indirect) 342 + ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_SYS_INT_EN, 343 + JPEG_SYS_INT_EN__DJRBC0_MASK, indirect); 344 + else 345 + WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_SYS_INT_EN, 346 + JPEG_SYS_INT_EN__DJRBC0_MASK, 1); 347 + 348 + if (indirect) { 349 + /* add nop to workaround PSP size check */ 350 + ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipUVD_NO_OP, 0, indirect); 351 + 352 + amdgpu_jpeg_psp_update_sram(adev, inst_idx, 0); 353 + } 354 + 355 + WREG32_SOC15(VCN, 0, regVCN_JPEG_DB_CTRL, 356 + ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT | 357 + VCN_JPEG_DB_CTRL__EN_MASK); 358 + 359 + WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_VMID, 0); 360 + WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L)); 361 + WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW, 362 + lower_32_bits(ring->gpu_addr)); 363 + WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, 364 + upper_32_bits(ring->gpu_addr)); 365 + WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_RPTR, 0); 366 + WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR, 0); 367 + WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, 0x00000002L); 368 + WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_SIZE, ring->ring_size / 4); 369 + ring->wptr = RREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR); 370 + 371 + return 0; 372 + } 373 + 374 + /** 375 + * jpeg_v5_0_0_stop_dpg_mode - Jpeg stop with dpg mode 376 + * 377 + * @adev: amdgpu_device pointer 378 + * @inst_idx: instance number index 379 + * 380 + * Stop JPEG block with dpg mode 381 + */ 382 + static void jpeg_v5_0_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx) 383 + { 384 + uint32_t reg_data = 0; 385 + 386 + reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS); 387 + reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK; 388 + WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data); 389 + } 390 + 277 391 /** 278 392 * jpeg_v5_0_0_start - start JPEG block 279 393 * ··· 404 288 if (adev->pm.dpm_enabled) 405 289 amdgpu_dpm_enable_jpeg(adev, true); 406 290 291 + if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) { 292 + r = jpeg_v5_0_0_start_dpg_mode(adev, 0, adev->jpeg.indirect_sram); 293 + return r; 294 + } 295 + 407 296 /* disable power gating */ 408 - r = jpeg_v5_0_0_disable_static_power_gating(adev); 297 + r = jpeg_v5_0_0_disable_power_gating(adev); 409 298 if (r) 410 299 return r; 411 300 ··· 420 299 /* MJPEG global tiling registers */ 421 300 WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG, 422 301 adev->gfx.config.gb_addr_config); 423 - 424 302 425 303 /* enable JMI channel */ 426 304 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL), 0, ··· 460 340 { 461 341 int r; 462 342 463 - /* reset JMI */ 464 - WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL), 465 - UVD_JMI_CNTL__SOFT_RESET_MASK, 466 - ~UVD_JMI_CNTL__SOFT_RESET_MASK); 343 + if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) { 344 + jpeg_v5_0_0_stop_dpg_mode(adev, 0); 345 + } else { 467 346 468 - jpeg_v5_0_0_enable_clock_gating(adev); 347 + /* reset JMI */ 348 + WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL), 349 + UVD_JMI_CNTL__SOFT_RESET_MASK, 350 + ~UVD_JMI_CNTL__SOFT_RESET_MASK); 469 351 470 - /* enable power gating */ 471 - r = jpeg_v5_0_0_enable_static_power_gating(adev); 472 - if (r) 473 - return r; 352 + jpeg_v5_0_0_enable_clock_gating(adev); 353 + 354 + /* enable power gating */ 355 + r = jpeg_v5_0_0_enable_power_gating(adev); 356 + if (r) 357 + return r; 358 + } 474 359 475 360 if (adev->pm.dpm_enabled) 476 361 amdgpu_dpm_enable_jpeg(adev, false);
+6
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.h
··· 24 24 #ifndef __JPEG_V5_0_0_H__ 25 25 #define __JPEG_V5_0_0_H__ 26 26 27 + #define vcnipJPEG_CGC_GATE 0x4160 28 + #define vcnipJPEG_CGC_CTRL 0x4161 29 + #define vcnipJPEG_SYS_INT_EN 0x4141 30 + #define vcnipUVD_NO_OP 0x0029 31 + #define vcnipJPEG_DEC_GFX10_ADDR_CONFIG 0x404A 32 + 27 33 extern const struct amdgpu_ip_block_version jpeg_v5_0_0_ip_block; 28 34 29 35 #endif /* __JPEG_V5_0_0_H__ */
+1
drivers/gpu/drm/amd/amdgpu/soc24.c
··· 428 428 429 429 adev->pg_flags = AMD_PG_SUPPORT_VCN | 430 430 AMD_PG_SUPPORT_JPEG | 431 + AMD_PG_SUPPORT_JPEG_DPG | 431 432 AMD_PG_SUPPORT_VCN_DPG; 432 433 adev->external_rev_id = adev->rev_id + 0x50; 433 434 break;