aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorMonk Liu <Monk.Liu@amd.com>2017-02-23 23:06:22 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-03-29 23:55:39 -0400
commitca82a746b0e20a70fc39101ca376a90d26dd1b28 (patch)
tree9276818ace0483b687cb03715dd238385821fa69 /drivers/gpu/drm/amd
parente09706f46ebecf3ae39996772c0ece12e91d8c45 (diff)
drm/amdgpu:change sequence of SDMA v4 init
must set minor_update.enable before write smaller value to wptr/doorbell, so for sriov we need set that register bit in hw_init period. this could fix the SDMA ring test fail after guest reboot Signed-off-by: Monk Liu <Monk.Liu@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')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 46d45cb69070..f8eb53b70315 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -560,8 +560,14 @@ static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
560 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_BASE_HI), ring->gpu_addr >> 40); 560 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_BASE_HI), ring->gpu_addr >> 40);
561 561
562 ring->wptr = 0; 562 ring->wptr = 0;
563 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR), lower_32_bits(ring->wptr) << 2); 563
564 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_HI), upper_32_bits(ring->wptr) << 2); 564 /* before programing wptr to a less value, need set minor_ptr_update first */
565 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_MINOR_PTR_UPDATE), 1);
566
567 if (!amdgpu_sriov_vf(adev)) { /* only bare-metal use register write for wptr */
568 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR), lower_32_bits(ring->wptr) << 2);
569 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_HI), upper_32_bits(ring->wptr) << 2);
570 }
565 571
566 doorbell = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_DOORBELL)); 572 doorbell = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_DOORBELL));
567 doorbell_offset = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_DOORBELL_OFFSET)); 573 doorbell_offset = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_DOORBELL_OFFSET));
@@ -577,15 +583,23 @@ static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
577 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_DOORBELL_OFFSET), doorbell_offset); 583 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_DOORBELL_OFFSET), doorbell_offset);
578 nbio_v6_1_sdma_doorbell_range(adev, i, ring->use_doorbell, ring->doorbell_index); 584 nbio_v6_1_sdma_doorbell_range(adev, i, ring->use_doorbell, ring->doorbell_index);
579 585
586 if (amdgpu_sriov_vf(adev))
587 sdma_v4_0_ring_set_wptr(ring);
588
589 /* set minor_ptr_update to 0 after wptr programed */
590 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_MINOR_PTR_UPDATE), 0);
591
580 /* set utc l1 enable flag always to 1 */ 592 /* set utc l1 enable flag always to 1 */
581 temp = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_CNTL)); 593 temp = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_CNTL));
582 temp = REG_SET_FIELD(temp, SDMA0_CNTL, UTC_L1_ENABLE, 1); 594 temp = REG_SET_FIELD(temp, SDMA0_CNTL, UTC_L1_ENABLE, 1);
583 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_CNTL), temp); 595 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_CNTL), temp);
584 596
585 /* unhalt engine */ 597 if (!amdgpu_sriov_vf(adev)) {
586 temp = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_F32_CNTL)); 598 /* unhalt engine */
587 temp = REG_SET_FIELD(temp, SDMA0_F32_CNTL, HALT, 0); 599 temp = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_F32_CNTL));
588 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_F32_CNTL), temp); 600 temp = REG_SET_FIELD(temp, SDMA0_F32_CNTL, HALT, 0);
601 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_F32_CNTL), temp);
602 }
589 603
590 /* enable DMA RB */ 604 /* enable DMA RB */
591 rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 1); 605 rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 1);
@@ -601,6 +615,11 @@ static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
601 615
602 ring->ready = true; 616 ring->ready = true;
603 617
618 if (amdgpu_sriov_vf(adev)) { /* bare-metal sequence doesn't need below to lines */
619 sdma_v4_0_ctx_switch_enable(adev, true);
620 sdma_v4_0_enable(adev, true);
621 }
622
604 r = amdgpu_ring_test_ring(ring); 623 r = amdgpu_ring_test_ring(ring);
605 if (r) { 624 if (r) {
606 ring->ready = false; 625 ring->ready = false;
@@ -671,8 +690,6 @@ static int sdma_v4_0_load_microcode(struct amdgpu_device *adev)
671 (adev->sdma.instance[i].fw->data + 690 (adev->sdma.instance[i].fw->data +
672 le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 691 le32_to_cpu(hdr->header.ucode_array_offset_bytes));
673 692
674 sdma_v4_0_print_ucode_regs(adev);
675
676 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_UCODE_ADDR), 0); 693 WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_UCODE_ADDR), 0);
677 694
678 695
@@ -699,10 +716,10 @@ static int sdma_v4_0_load_microcode(struct amdgpu_device *adev)
699 */ 716 */
700static int sdma_v4_0_start(struct amdgpu_device *adev) 717static int sdma_v4_0_start(struct amdgpu_device *adev)
701{ 718{
702 int r; 719 int r = 0;
703 720
704 if (amdgpu_sriov_vf(adev)) { 721 if (amdgpu_sriov_vf(adev)) {
705 /* disable RB and halt engine */ 722 sdma_v4_0_ctx_switch_enable(adev, false);
706 sdma_v4_0_enable(adev, false); 723 sdma_v4_0_enable(adev, false);
707 724
708 /* set RB registers */ 725 /* set RB registers */