aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong Zhao <Yong.Zhao@amd.com>2019-02-05 15:17:40 -0500
committerAlex Deucher <alexander.deucher@amd.com>2019-02-13 17:51:02 -0500
commit74b9b3ea0cb355d668eb0309d1ab57f403d52c69 (patch)
treecea92b3a1675e39cea67e41d9e8460af190c76f6
parent2d086fded1021d6b482dfc705bab8f085d10a496 (diff)
drm/amdgpu: Fix bugs in setting CP RB/MEC DOORBELL_RANGE registers
CP_RB_DOORBELL_RANGE_LOWER/UPPER and CP_MEC_DOORBELL_RANGE_LOWER/UPPER are used for waking up an idle scheduler and for power gating support. Usually the first few doorbells in pci doorbell bar are used for RB and all leftover for MEC. This patch fixes the incorrect settings. Theoretically, gfx ring doorbells should come before all MEC doorbells to be consistent with the design. However, since the doorbell allocations are agreed by all and we are not free to change them, also considering the kernel MEC ring doorbells which are before gfx ring doorbells are not used often, we compromise by leaving the doorbell allocations unchanged. Signed-off-by: Yong Zhao <Yong.Zhao@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c19
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c19
2 files changed, 29 insertions, 9 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index b8e50a34bdb3..41cf9d0224d9 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -4223,8 +4223,8 @@ static void gfx_v8_0_set_cpg_door_bell(struct amdgpu_device *adev, struct amdgpu
4223 adev->doorbell_index.gfx_ring0); 4223 adev->doorbell_index.gfx_ring0);
4224 WREG32(mmCP_RB_DOORBELL_RANGE_LOWER, tmp); 4224 WREG32(mmCP_RB_DOORBELL_RANGE_LOWER, tmp);
4225 4225
4226 WREG32(mmCP_RB_DOORBELL_RANGE_UPPER, 4226 /* There is only one GFX queue */
4227 CP_RB_DOORBELL_RANGE_UPPER__DOORBELL_RANGE_UPPER_MASK); 4227 WREG32(mmCP_RB_DOORBELL_RANGE_UPPER, tmp);
4228} 4228}
4229 4229
4230static int gfx_v8_0_cp_gfx_resume(struct amdgpu_device *adev) 4230static int gfx_v8_0_cp_gfx_resume(struct amdgpu_device *adev)
@@ -4646,8 +4646,19 @@ static int gfx_v8_0_kcq_init_queue(struct amdgpu_ring *ring)
4646static void gfx_v8_0_set_mec_doorbell_range(struct amdgpu_device *adev) 4646static void gfx_v8_0_set_mec_doorbell_range(struct amdgpu_device *adev)
4647{ 4647{
4648 if (adev->asic_type > CHIP_TONGA) { 4648 if (adev->asic_type > CHIP_TONGA) {
4649 WREG32(mmCP_MEC_DOORBELL_RANGE_LOWER, adev->doorbell_index.kiq << 2); 4649 /* The first few doorbells in pci doorbell bar are for GFX RB
4650 WREG32(mmCP_MEC_DOORBELL_RANGE_UPPER, adev->doorbell_index.mec_ring7 << 2); 4650 * rings and all the leftover for MEC.
4651 * So CP_MEC_DOORBELL_RANGE_LOWER should be set one index after
4652 * CP_RB_DOORBELL_RANGE_UPPER, as we assume there is only one
4653 * GFX RB rings.
4654 */
4655 u32 tmp = REG_SET_FIELD(0, CP_MEC_DOORBELL_RANGE_LOWER,
4656 DOORBELL_RANGE_LOWER,
4657 adev->gfx.gfx_ring[0].doorbell_index + 1);
4658
4659 WREG32(mmCP_MEC_DOORBELL_RANGE_LOWER, tmp);
4660 WREG32(mmCP_MEC_DOORBELL_RANGE_UPPER,
4661 CP_MEC_DOORBELL_RANGE_UPPER__DOORBELL_RANGE_UPPER_MASK);
4651 } 4662 }
4652 /* enable doorbells */ 4663 /* enable doorbells */
4653 WREG32_FIELD(CP_PQ_STATUS, DOORBELL_ENABLE, 1); 4664 WREG32_FIELD(CP_PQ_STATUS, DOORBELL_ENABLE, 1);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 5533f6e4f4a4..36f417fd6ba9 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -2631,8 +2631,8 @@ static int gfx_v9_0_cp_gfx_resume(struct amdgpu_device *adev)
2631 DOORBELL_RANGE_LOWER, ring->doorbell_index); 2631 DOORBELL_RANGE_LOWER, ring->doorbell_index);
2632 WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_LOWER, tmp); 2632 WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_LOWER, tmp);
2633 2633
2634 WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_UPPER, 2634 /* There is only one GFX queue */
2635 CP_RB_DOORBELL_RANGE_UPPER__DOORBELL_RANGE_UPPER_MASK); 2635 WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_UPPER, tmp);
2636 2636
2637 2637
2638 /* start the ring */ 2638 /* start the ring */
@@ -2995,10 +2995,19 @@ static int gfx_v9_0_kiq_init_register(struct amdgpu_ring *ring)
2995 2995
2996 /* enable the doorbell if requested */ 2996 /* enable the doorbell if requested */
2997 if (ring->use_doorbell) { 2997 if (ring->use_doorbell) {
2998 WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_LOWER, 2998 /* The first few doorbells in pci doorbell bar are for GFX RB
2999 (adev->doorbell_index.kiq * 2) << 2); 2999 * rings and all the leftover for MEC.
3000 * So CP_MEC_DOORBELL_RANGE_LOWER should be set one index after
3001 * CP_RB_DOORBELL_RANGE_UPPER, as we assume there is only one
3002 * GFX RB rings.
3003 */
3004 u32 tmp = REG_SET_FIELD(0, CP_MEC_DOORBELL_RANGE_LOWER,
3005 DOORBELL_RANGE_LOWER,
3006 adev->gfx.gfx_ring[0].doorbell_index + 2);
3007
3008 WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_LOWER, tmp);
3000 WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_UPPER, 3009 WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_UPPER,
3001 (adev->doorbell_index.userqueue_end * 2) << 2); 3010 CP_MEC_DOORBELL_RANGE_UPPER__DOORBELL_RANGE_UPPER_MASK);
3002 } 3011 }
3003 3012
3004 WREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL, 3013 WREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL,