diff options
author | Junwei Zhang <Jerry.Zhang@amd.com> | 2016-06-17 05:07:56 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-07-07 15:02:04 -0400 |
commit | 5a3f25dbcb583760e1a6e4e1bffd3d2e09a5c657 (patch) | |
tree | bb819aa756a577fdf0e943a4d0a132cbf09fb00c /drivers/gpu/drm/amd/amdgpu | |
parent | 9ecbe7f506d36f7dfb7ce06b2c35b252fa6d6ed8 (diff) |
drm/amdgpu/dce8: fix flash with white screen on monitor
Fixed mc stop and resume hardware programming sequence.
Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 67 |
1 files changed, 7 insertions, 60 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 300ff4aab0fd..4fdfab1e9200 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | |||
@@ -526,36 +526,16 @@ static void dce_v8_0_stop_mc_access(struct amdgpu_device *adev, | |||
526 | crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]), | 526 | crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]), |
527 | CRTC_CONTROL, CRTC_MASTER_EN); | 527 | CRTC_CONTROL, CRTC_MASTER_EN); |
528 | if (crtc_enabled) { | 528 | if (crtc_enabled) { |
529 | #if 0 | 529 | #if 1 |
530 | u32 frame_count; | ||
531 | int j; | ||
532 | |||
533 | save->crtc_enabled[i] = true; | 530 | save->crtc_enabled[i] = true; |
534 | tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]); | 531 | tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]); |
535 | if (REG_GET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN) == 0) { | 532 | if (REG_GET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN) == 0) { |
536 | amdgpu_display_vblank_wait(adev, i); | 533 | /*it is correct only for RGB ; black is 0*/ |
537 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1); | 534 | WREG32(mmCRTC_BLANK_DATA_COLOR + crtc_offsets[i], 0); |
538 | tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1); | 535 | tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1); |
539 | WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp); | 536 | WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp); |
540 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0); | ||
541 | } | ||
542 | /* wait for the next frame */ | ||
543 | frame_count = amdgpu_display_vblank_get_counter(adev, i); | ||
544 | for (j = 0; j < adev->usec_timeout; j++) { | ||
545 | if (amdgpu_display_vblank_get_counter(adev, i) != frame_count) | ||
546 | break; | ||
547 | udelay(1); | ||
548 | } | ||
549 | tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]); | ||
550 | if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK) == 0) { | ||
551 | tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 1); | ||
552 | WREG32(mmGRPH_UPDATE + crtc_offsets[i], tmp); | ||
553 | } | ||
554 | tmp = RREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i]); | ||
555 | if (REG_GET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK) == 0) { | ||
556 | tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK, 1); | ||
557 | WREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i], tmp); | ||
558 | } | 537 | } |
538 | mdelay(20); | ||
559 | #else | 539 | #else |
560 | /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ | 540 | /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ |
561 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1); | 541 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1); |
@@ -575,55 +555,22 @@ static void dce_v8_0_stop_mc_access(struct amdgpu_device *adev, | |||
575 | static void dce_v8_0_resume_mc_access(struct amdgpu_device *adev, | 555 | static void dce_v8_0_resume_mc_access(struct amdgpu_device *adev, |
576 | struct amdgpu_mode_mc_save *save) | 556 | struct amdgpu_mode_mc_save *save) |
577 | { | 557 | { |
578 | u32 tmp, frame_count; | 558 | u32 tmp; |
579 | int i, j; | 559 | int i; |
580 | 560 | ||
581 | /* update crtc base addresses */ | 561 | /* update crtc base addresses */ |
582 | for (i = 0; i < adev->mode_info.num_crtc; i++) { | 562 | for (i = 0; i < adev->mode_info.num_crtc; i++) { |
583 | WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], | 563 | WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], |
584 | upper_32_bits(adev->mc.vram_start)); | 564 | upper_32_bits(adev->mc.vram_start)); |
585 | WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], | ||
586 | upper_32_bits(adev->mc.vram_start)); | ||
587 | WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i], | 565 | WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i], |
588 | (u32)adev->mc.vram_start); | 566 | (u32)adev->mc.vram_start); |
589 | WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], | ||
590 | (u32)adev->mc.vram_start); | ||
591 | 567 | ||
592 | if (save->crtc_enabled[i]) { | 568 | if (save->crtc_enabled[i]) { |
593 | tmp = RREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i]); | ||
594 | if (REG_GET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE) != 3) { | ||
595 | tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE, 3); | ||
596 | WREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i], tmp); | ||
597 | } | ||
598 | tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]); | ||
599 | if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK)) { | ||
600 | tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 0); | ||
601 | WREG32(mmGRPH_UPDATE + crtc_offsets[i], tmp); | ||
602 | } | ||
603 | tmp = RREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i]); | ||
604 | if (REG_GET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK)) { | ||
605 | tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK, 0); | ||
606 | WREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i], tmp); | ||
607 | } | ||
608 | for (j = 0; j < adev->usec_timeout; j++) { | ||
609 | tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]); | ||
610 | if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_SURFACE_UPDATE_PENDING) == 0) | ||
611 | break; | ||
612 | udelay(1); | ||
613 | } | ||
614 | tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]); | 569 | tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]); |
615 | tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 0); | 570 | tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 0); |
616 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1); | ||
617 | WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp); | 571 | WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp); |
618 | WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0); | ||
619 | /* wait for the next frame */ | ||
620 | frame_count = amdgpu_display_vblank_get_counter(adev, i); | ||
621 | for (j = 0; j < adev->usec_timeout; j++) { | ||
622 | if (amdgpu_display_vblank_get_counter(adev, i) != frame_count) | ||
623 | break; | ||
624 | udelay(1); | ||
625 | } | ||
626 | } | 572 | } |
573 | mdelay(20); | ||
627 | } | 574 | } |
628 | 575 | ||
629 | WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start)); | 576 | WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start)); |