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

drm/amdgpu: modify sdma start sequence

should fist halt engine, and then doing the register
programing, and later unhalt engine, and finally run
ring_test.

this help fix reloading driver hang issue of SDMA
ring

original sequence is wrong for it programing engine
after unhalt, which will lead to fault behavior when
doing driver reloading after unloaded.

Signed-off-by: Monk Liu <Monk.Liu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Monk Liu and committed by
Alex Deucher
505dfe76 d72f7c06

+24 -8
+7 -2
drivers/gpu/drm/amd/amdgpu/cik_sdma.c
··· 448 448 WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); 449 449 450 450 ring->ready = true; 451 + } 451 452 453 + cik_sdma_enable(adev, true); 454 + 455 + for (i = 0; i < adev->sdma.num_instances; i++) { 456 + ring = &adev->sdma.instance[i].ring; 452 457 r = amdgpu_ring_test_ring(ring); 453 458 if (r) { 454 459 ring->ready = false; ··· 536 531 if (r) 537 532 return r; 538 533 539 - /* unhalt the MEs */ 540 - cik_sdma_enable(adev, true); 534 + /* halt the engine before programing */ 535 + cik_sdma_enable(adev, false); 541 536 542 537 /* start the gfx rings and rlc compute queues */ 543 538 r = cik_sdma_gfx_resume(adev);
+6 -2
drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
··· 491 491 WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); 492 492 493 493 ring->ready = true; 494 + } 494 495 496 + sdma_v2_4_enable(adev, true); 497 + for (i = 0; i < adev->sdma.num_instances; i++) { 498 + ring = &adev->sdma.instance[i].ring; 495 499 r = amdgpu_ring_test_ring(ring); 496 500 if (r) { 497 501 ring->ready = false; ··· 586 582 return -EINVAL; 587 583 } 588 584 589 - /* unhalt the MEs */ 590 - sdma_v2_4_enable(adev, true); 585 + /* halt the engine before programing */ 586 + sdma_v2_4_enable(adev, false); 591 587 592 588 /* start the gfx rings and rlc compute queues */ 593 589 r = sdma_v2_4_gfx_resume(adev);
+11 -4
drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
··· 713 713 WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); 714 714 715 715 ring->ready = true; 716 + } 716 717 718 + /* unhalt the MEs */ 719 + sdma_v3_0_enable(adev, true); 720 + /* enable sdma ring preemption */ 721 + sdma_v3_0_ctx_switch_enable(adev, true); 722 + 723 + for (i = 0; i < adev->sdma.num_instances; i++) { 724 + ring = &adev->sdma.instance[i].ring; 717 725 r = amdgpu_ring_test_ring(ring); 718 726 if (r) { 719 727 ring->ready = false; ··· 814 806 } 815 807 } 816 808 817 - /* unhalt the MEs */ 818 - sdma_v3_0_enable(adev, true); 819 - /* enable sdma ring preemption */ 820 - sdma_v3_0_ctx_switch_enable(adev, true); 809 + /* disble sdma engine before programing it */ 810 + sdma_v3_0_ctx_switch_enable(adev, false); 811 + sdma_v3_0_enable(adev, false); 821 812 822 813 /* start the gfx rings and rlc compute queues */ 823 814 r = sdma_v3_0_gfx_resume(adev);