diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 261 |
1 files changed, 259 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 121915bbc3b6..3d5913926436 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | |||
@@ -279,6 +279,234 @@ static void uvd_v6_0_mc_resume(struct amdgpu_device *adev) | |||
279 | WREG32(mmUVD_VCPU_CACHE_SIZE2, size); | 279 | WREG32(mmUVD_VCPU_CACHE_SIZE2, size); |
280 | } | 280 | } |
281 | 281 | ||
282 | static void cz_set_uvd_clock_gating_branches(struct amdgpu_device *adev, | ||
283 | bool enable) | ||
284 | { | ||
285 | u32 data, data1; | ||
286 | |||
287 | data = RREG32(mmUVD_CGC_GATE); | ||
288 | data1 = RREG32(mmUVD_SUVD_CGC_GATE); | ||
289 | if (enable) { | ||
290 | data |= UVD_CGC_GATE__SYS_MASK | | ||
291 | UVD_CGC_GATE__UDEC_MASK | | ||
292 | UVD_CGC_GATE__MPEG2_MASK | | ||
293 | UVD_CGC_GATE__RBC_MASK | | ||
294 | UVD_CGC_GATE__LMI_MC_MASK | | ||
295 | UVD_CGC_GATE__IDCT_MASK | | ||
296 | UVD_CGC_GATE__MPRD_MASK | | ||
297 | UVD_CGC_GATE__MPC_MASK | | ||
298 | UVD_CGC_GATE__LBSI_MASK | | ||
299 | UVD_CGC_GATE__LRBBM_MASK | | ||
300 | UVD_CGC_GATE__UDEC_RE_MASK | | ||
301 | UVD_CGC_GATE__UDEC_CM_MASK | | ||
302 | UVD_CGC_GATE__UDEC_IT_MASK | | ||
303 | UVD_CGC_GATE__UDEC_DB_MASK | | ||
304 | UVD_CGC_GATE__UDEC_MP_MASK | | ||
305 | UVD_CGC_GATE__WCB_MASK | | ||
306 | UVD_CGC_GATE__VCPU_MASK | | ||
307 | UVD_CGC_GATE__SCPU_MASK; | ||
308 | data1 |= UVD_SUVD_CGC_GATE__SRE_MASK | | ||
309 | UVD_SUVD_CGC_GATE__SIT_MASK | | ||
310 | UVD_SUVD_CGC_GATE__SMP_MASK | | ||
311 | UVD_SUVD_CGC_GATE__SCM_MASK | | ||
312 | UVD_SUVD_CGC_GATE__SDB_MASK | | ||
313 | UVD_SUVD_CGC_GATE__SRE_H264_MASK | | ||
314 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK | | ||
315 | UVD_SUVD_CGC_GATE__SIT_H264_MASK | | ||
316 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK | | ||
317 | UVD_SUVD_CGC_GATE__SCM_H264_MASK | | ||
318 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK | | ||
319 | UVD_SUVD_CGC_GATE__SDB_H264_MASK | | ||
320 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK; | ||
321 | } else { | ||
322 | data &= ~(UVD_CGC_GATE__SYS_MASK | | ||
323 | UVD_CGC_GATE__UDEC_MASK | | ||
324 | UVD_CGC_GATE__MPEG2_MASK | | ||
325 | UVD_CGC_GATE__RBC_MASK | | ||
326 | UVD_CGC_GATE__LMI_MC_MASK | | ||
327 | UVD_CGC_GATE__LMI_UMC_MASK | | ||
328 | UVD_CGC_GATE__IDCT_MASK | | ||
329 | UVD_CGC_GATE__MPRD_MASK | | ||
330 | UVD_CGC_GATE__MPC_MASK | | ||
331 | UVD_CGC_GATE__LBSI_MASK | | ||
332 | UVD_CGC_GATE__LRBBM_MASK | | ||
333 | UVD_CGC_GATE__UDEC_RE_MASK | | ||
334 | UVD_CGC_GATE__UDEC_CM_MASK | | ||
335 | UVD_CGC_GATE__UDEC_IT_MASK | | ||
336 | UVD_CGC_GATE__UDEC_DB_MASK | | ||
337 | UVD_CGC_GATE__UDEC_MP_MASK | | ||
338 | UVD_CGC_GATE__WCB_MASK | | ||
339 | UVD_CGC_GATE__VCPU_MASK | | ||
340 | UVD_CGC_GATE__SCPU_MASK); | ||
341 | data1 &= ~(UVD_SUVD_CGC_GATE__SRE_MASK | | ||
342 | UVD_SUVD_CGC_GATE__SIT_MASK | | ||
343 | UVD_SUVD_CGC_GATE__SMP_MASK | | ||
344 | UVD_SUVD_CGC_GATE__SCM_MASK | | ||
345 | UVD_SUVD_CGC_GATE__SDB_MASK | | ||
346 | UVD_SUVD_CGC_GATE__SRE_H264_MASK | | ||
347 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK | | ||
348 | UVD_SUVD_CGC_GATE__SIT_H264_MASK | | ||
349 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK | | ||
350 | UVD_SUVD_CGC_GATE__SCM_H264_MASK | | ||
351 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK | | ||
352 | UVD_SUVD_CGC_GATE__SDB_H264_MASK | | ||
353 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK); | ||
354 | } | ||
355 | WREG32(mmUVD_CGC_GATE, data); | ||
356 | WREG32(mmUVD_SUVD_CGC_GATE, data1); | ||
357 | } | ||
358 | |||
359 | static void tonga_set_uvd_clock_gating_branches(struct amdgpu_device *adev, | ||
360 | bool enable) | ||
361 | { | ||
362 | u32 data, data1; | ||
363 | |||
364 | data = RREG32(mmUVD_CGC_GATE); | ||
365 | data1 = RREG32(mmUVD_SUVD_CGC_GATE); | ||
366 | if (enable) { | ||
367 | data |= UVD_CGC_GATE__SYS_MASK | | ||
368 | UVD_CGC_GATE__UDEC_MASK | | ||
369 | UVD_CGC_GATE__MPEG2_MASK | | ||
370 | UVD_CGC_GATE__RBC_MASK | | ||
371 | UVD_CGC_GATE__LMI_MC_MASK | | ||
372 | UVD_CGC_GATE__IDCT_MASK | | ||
373 | UVD_CGC_GATE__MPRD_MASK | | ||
374 | UVD_CGC_GATE__MPC_MASK | | ||
375 | UVD_CGC_GATE__LBSI_MASK | | ||
376 | UVD_CGC_GATE__LRBBM_MASK | | ||
377 | UVD_CGC_GATE__UDEC_RE_MASK | | ||
378 | UVD_CGC_GATE__UDEC_CM_MASK | | ||
379 | UVD_CGC_GATE__UDEC_IT_MASK | | ||
380 | UVD_CGC_GATE__UDEC_DB_MASK | | ||
381 | UVD_CGC_GATE__UDEC_MP_MASK | | ||
382 | UVD_CGC_GATE__WCB_MASK | | ||
383 | UVD_CGC_GATE__VCPU_MASK | | ||
384 | UVD_CGC_GATE__SCPU_MASK; | ||
385 | data1 |= UVD_SUVD_CGC_GATE__SRE_MASK | | ||
386 | UVD_SUVD_CGC_GATE__SIT_MASK | | ||
387 | UVD_SUVD_CGC_GATE__SMP_MASK | | ||
388 | UVD_SUVD_CGC_GATE__SCM_MASK | | ||
389 | UVD_SUVD_CGC_GATE__SDB_MASK; | ||
390 | } else { | ||
391 | data &= ~(UVD_CGC_GATE__SYS_MASK | | ||
392 | UVD_CGC_GATE__UDEC_MASK | | ||
393 | UVD_CGC_GATE__MPEG2_MASK | | ||
394 | UVD_CGC_GATE__RBC_MASK | | ||
395 | UVD_CGC_GATE__LMI_MC_MASK | | ||
396 | UVD_CGC_GATE__LMI_UMC_MASK | | ||
397 | UVD_CGC_GATE__IDCT_MASK | | ||
398 | UVD_CGC_GATE__MPRD_MASK | | ||
399 | UVD_CGC_GATE__MPC_MASK | | ||
400 | UVD_CGC_GATE__LBSI_MASK | | ||
401 | UVD_CGC_GATE__LRBBM_MASK | | ||
402 | UVD_CGC_GATE__UDEC_RE_MASK | | ||
403 | UVD_CGC_GATE__UDEC_CM_MASK | | ||
404 | UVD_CGC_GATE__UDEC_IT_MASK | | ||
405 | UVD_CGC_GATE__UDEC_DB_MASK | | ||
406 | UVD_CGC_GATE__UDEC_MP_MASK | | ||
407 | UVD_CGC_GATE__WCB_MASK | | ||
408 | UVD_CGC_GATE__VCPU_MASK | | ||
409 | UVD_CGC_GATE__SCPU_MASK); | ||
410 | data1 &= ~(UVD_SUVD_CGC_GATE__SRE_MASK | | ||
411 | UVD_SUVD_CGC_GATE__SIT_MASK | | ||
412 | UVD_SUVD_CGC_GATE__SMP_MASK | | ||
413 | UVD_SUVD_CGC_GATE__SCM_MASK | | ||
414 | UVD_SUVD_CGC_GATE__SDB_MASK); | ||
415 | } | ||
416 | WREG32(mmUVD_CGC_GATE, data); | ||
417 | WREG32(mmUVD_SUVD_CGC_GATE, data1); | ||
418 | } | ||
419 | |||
420 | static void uvd_v6_0_set_uvd_dynamic_clock_mode(struct amdgpu_device *adev, | ||
421 | bool swmode) | ||
422 | { | ||
423 | u32 data, data1 = 0, data2; | ||
424 | |||
425 | /* Always un-gate UVD REGS bit */ | ||
426 | data = RREG32(mmUVD_CGC_GATE); | ||
427 | data &= ~(UVD_CGC_GATE__REGS_MASK); | ||
428 | WREG32(mmUVD_CGC_GATE, data); | ||
429 | |||
430 | data = RREG32(mmUVD_CGC_CTRL); | ||
431 | data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK | | ||
432 | UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK); | ||
433 | data |= UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK | | ||
434 | 1 << REG_FIELD_SHIFT(UVD_CGC_CTRL, CLK_GATE_DLY_TIMER) | | ||
435 | 4 << REG_FIELD_SHIFT(UVD_CGC_CTRL, CLK_OFF_DELAY); | ||
436 | |||
437 | data2 = RREG32(mmUVD_SUVD_CGC_CTRL); | ||
438 | if (swmode) { | ||
439 | data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK | | ||
440 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK | | ||
441 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK | | ||
442 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK | | ||
443 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK | | ||
444 | UVD_CGC_CTRL__SYS_MODE_MASK | | ||
445 | UVD_CGC_CTRL__UDEC_MODE_MASK | | ||
446 | UVD_CGC_CTRL__MPEG2_MODE_MASK | | ||
447 | UVD_CGC_CTRL__REGS_MODE_MASK | | ||
448 | UVD_CGC_CTRL__RBC_MODE_MASK | | ||
449 | UVD_CGC_CTRL__LMI_MC_MODE_MASK | | ||
450 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK | | ||
451 | UVD_CGC_CTRL__IDCT_MODE_MASK | | ||
452 | UVD_CGC_CTRL__MPRD_MODE_MASK | | ||
453 | UVD_CGC_CTRL__MPC_MODE_MASK | | ||
454 | UVD_CGC_CTRL__LBSI_MODE_MASK | | ||
455 | UVD_CGC_CTRL__LRBBM_MODE_MASK | | ||
456 | UVD_CGC_CTRL__WCB_MODE_MASK | | ||
457 | UVD_CGC_CTRL__VCPU_MODE_MASK | | ||
458 | UVD_CGC_CTRL__JPEG_MODE_MASK | | ||
459 | UVD_CGC_CTRL__SCPU_MODE_MASK); | ||
460 | data1 |= UVD_CGC_CTRL2__DYN_OCLK_RAMP_EN_MASK | | ||
461 | UVD_CGC_CTRL2__DYN_RCLK_RAMP_EN_MASK; | ||
462 | data1 &= ~UVD_CGC_CTRL2__GATER_DIV_ID_MASK; | ||
463 | data1 |= 7 << REG_FIELD_SHIFT(UVD_CGC_CTRL2, GATER_DIV_ID); | ||
464 | data2 &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK | | ||
465 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK | | ||
466 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK | | ||
467 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK | | ||
468 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK); | ||
469 | } else { | ||
470 | data |= UVD_CGC_CTRL__UDEC_RE_MODE_MASK | | ||
471 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK | | ||
472 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK | | ||
473 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK | | ||
474 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK | | ||
475 | UVD_CGC_CTRL__SYS_MODE_MASK | | ||
476 | UVD_CGC_CTRL__UDEC_MODE_MASK | | ||
477 | UVD_CGC_CTRL__MPEG2_MODE_MASK | | ||
478 | UVD_CGC_CTRL__REGS_MODE_MASK | | ||
479 | UVD_CGC_CTRL__RBC_MODE_MASK | | ||
480 | UVD_CGC_CTRL__LMI_MC_MODE_MASK | | ||
481 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK | | ||
482 | UVD_CGC_CTRL__IDCT_MODE_MASK | | ||
483 | UVD_CGC_CTRL__MPRD_MODE_MASK | | ||
484 | UVD_CGC_CTRL__MPC_MODE_MASK | | ||
485 | UVD_CGC_CTRL__LBSI_MODE_MASK | | ||
486 | UVD_CGC_CTRL__LRBBM_MODE_MASK | | ||
487 | UVD_CGC_CTRL__WCB_MODE_MASK | | ||
488 | UVD_CGC_CTRL__VCPU_MODE_MASK | | ||
489 | UVD_CGC_CTRL__SCPU_MODE_MASK; | ||
490 | data2 |= UVD_SUVD_CGC_CTRL__SRE_MODE_MASK | | ||
491 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK | | ||
492 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK | | ||
493 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK | | ||
494 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK; | ||
495 | } | ||
496 | WREG32(mmUVD_CGC_CTRL, data); | ||
497 | WREG32(mmUVD_SUVD_CGC_CTRL, data2); | ||
498 | |||
499 | data = RREG32_UVD_CTX(ixUVD_CGC_CTRL2); | ||
500 | data &= ~(REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_OCLK_RAMP_EN) | | ||
501 | REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_RCLK_RAMP_EN) | | ||
502 | REG_FIELD_MASK(UVD_CGC_CTRL2, GATER_DIV_ID)); | ||
503 | data1 &= (REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_OCLK_RAMP_EN) | | ||
504 | REG_FIELD_MASK(UVD_CGC_CTRL2, DYN_RCLK_RAMP_EN) | | ||
505 | REG_FIELD_MASK(UVD_CGC_CTRL2, GATER_DIV_ID)); | ||
506 | data |= data1; | ||
507 | WREG32_UVD_CTX(ixUVD_CGC_CTRL2, data); | ||
508 | } | ||
509 | |||
282 | /** | 510 | /** |
283 | * uvd_v6_0_start - start UVD block | 511 | * uvd_v6_0_start - start UVD block |
284 | * | 512 | * |
@@ -303,8 +531,19 @@ static int uvd_v6_0_start(struct amdgpu_device *adev) | |||
303 | 531 | ||
304 | uvd_v6_0_mc_resume(adev); | 532 | uvd_v6_0_mc_resume(adev); |
305 | 533 | ||
306 | /* disable clock gating */ | 534 | /* Set dynamic clock gating in S/W control mode */ |
307 | WREG32(mmUVD_CGC_GATE, 0); | 535 | if (adev->cg_flags & AMDGPU_CG_SUPPORT_UVD_MGCG) { |
536 | if (adev->flags & AMD_IS_APU) | ||
537 | cz_set_uvd_clock_gating_branches(adev, false); | ||
538 | else | ||
539 | tonga_set_uvd_clock_gating_branches(adev, false); | ||
540 | uvd_v6_0_set_uvd_dynamic_clock_mode(adev, true); | ||
541 | } else { | ||
542 | /* disable clock gating */ | ||
543 | uint32_t data = RREG32(mmUVD_CGC_CTRL); | ||
544 | data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; | ||
545 | WREG32(mmUVD_CGC_CTRL, data); | ||
546 | } | ||
308 | 547 | ||
309 | /* disable interupt */ | 548 | /* disable interupt */ |
310 | WREG32_P(mmUVD_MASTINT_EN, 0, ~(1 << 1)); | 549 | WREG32_P(mmUVD_MASTINT_EN, 0, ~(1 << 1)); |
@@ -758,6 +997,24 @@ static int uvd_v6_0_process_interrupt(struct amdgpu_device *adev, | |||
758 | static int uvd_v6_0_set_clockgating_state(void *handle, | 997 | static int uvd_v6_0_set_clockgating_state(void *handle, |
759 | enum amd_clockgating_state state) | 998 | enum amd_clockgating_state state) |
760 | { | 999 | { |
1000 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1001 | bool enable = (state == AMD_CG_STATE_GATE) ? true : false; | ||
1002 | |||
1003 | if (!(adev->cg_flags & AMDGPU_CG_SUPPORT_UVD_MGCG)) | ||
1004 | return 0; | ||
1005 | |||
1006 | if (enable) { | ||
1007 | if (adev->flags & AMD_IS_APU) | ||
1008 | cz_set_uvd_clock_gating_branches(adev, enable); | ||
1009 | else | ||
1010 | tonga_set_uvd_clock_gating_branches(adev, enable); | ||
1011 | uvd_v6_0_set_uvd_dynamic_clock_mode(adev, true); | ||
1012 | } else { | ||
1013 | uint32_t data = RREG32(mmUVD_CGC_CTRL); | ||
1014 | data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; | ||
1015 | WREG32(mmUVD_CGC_CTRL, data); | ||
1016 | } | ||
1017 | |||
761 | return 0; | 1018 | return 0; |
762 | } | 1019 | } |
763 | 1020 | ||