aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1241-drm-amdgpu-Fix-bugs-in-setting-CP-RB-MEC-DOORBELL_RA.patch
blob: 93e6d6b2a9dbdf036deedfa7c158e7b5af220047 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
From 1e8920dd32a6c01cb960d0485a7209d85c9c30bd Mon Sep 17 00:00:00 2001
From: Yong Zhao <Yong.Zhao@amd.com>
Date: Tue, 5 Feb 2019 15:17:40 -0500
Subject: [PATCH 1241/2940] 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.

Change-Id: I402a56ce9a80e6c2ed2f96be431ae71ca88e73a4
Signed-off-by: Yong Zhao <Yong.Zhao@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 19 +++++++++++++++----
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 19 ++++++++++++++-----
 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 e6f66bf7e1f0..a0ee869f5706 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
 					adev->doorbell_index.gfx_ring0);
 	WREG32(mmCP_RB_DOORBELL_RANGE_LOWER, tmp);
 
-	WREG32(mmCP_RB_DOORBELL_RANGE_UPPER,
-		CP_RB_DOORBELL_RANGE_UPPER__DOORBELL_RANGE_UPPER_MASK);
+	/* There is only one GFX queue */
+	WREG32(mmCP_RB_DOORBELL_RANGE_UPPER, tmp);
 }
 
 static 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)
 static void gfx_v8_0_set_mec_doorbell_range(struct amdgpu_device *adev)
 {
 	if (adev->asic_type > CHIP_TONGA) {
-		WREG32(mmCP_MEC_DOORBELL_RANGE_LOWER, adev->doorbell_index.kiq << 2);
-		WREG32(mmCP_MEC_DOORBELL_RANGE_UPPER, adev->doorbell_index.mec_ring7 << 2);
+		/* The first few doorbells in pci doorbell bar are for GFX RB
+		 * rings and all the leftover for MEC.
+		 * So CP_MEC_DOORBELL_RANGE_LOWER should be set one index after
+		 * CP_RB_DOORBELL_RANGE_UPPER, as we assume there is only one
+		 * GFX RB rings.
+		 */
+		u32 tmp = REG_SET_FIELD(0, CP_MEC_DOORBELL_RANGE_LOWER,
+				DOORBELL_RANGE_LOWER,
+				adev->gfx.gfx_ring[0].doorbell_index + 1);
+
+		WREG32(mmCP_MEC_DOORBELL_RANGE_LOWER, tmp);
+		WREG32(mmCP_MEC_DOORBELL_RANGE_UPPER,
+				CP_MEC_DOORBELL_RANGE_UPPER__DOORBELL_RANGE_UPPER_MASK);
 	}
 	/* enable doorbells */
 	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 1478e784cff0..54d5e788dffa 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -2635,8 +2635,8 @@ static int gfx_v9_0_cp_gfx_resume(struct amdgpu_device *adev)
 			DOORBELL_RANGE_LOWER, ring->doorbell_index);
 	WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_LOWER, tmp);
 
-	WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_UPPER,
-		       CP_RB_DOORBELL_RANGE_UPPER__DOORBELL_RANGE_UPPER_MASK);
+	/* There is only one GFX queue */
+	WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_UPPER, tmp);
 
 
 	/* start the ring */
@@ -2999,10 +2999,19 @@ static int gfx_v9_0_kiq_init_register(struct amdgpu_ring *ring)
 
 	/* enable the doorbell if requested */
 	if (ring->use_doorbell) {
-		WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_LOWER,
-					(adev->doorbell_index.kiq * 2) << 2);
+		/* The first few doorbells in pci doorbell bar are for GFX RB
+		 * rings and all the leftover for MEC.
+		 * So CP_MEC_DOORBELL_RANGE_LOWER should be set one index after
+		 * CP_RB_DOORBELL_RANGE_UPPER, as we assume there is only one
+		 * GFX RB rings.
+		 */
+		u32 tmp = REG_SET_FIELD(0, CP_MEC_DOORBELL_RANGE_LOWER,
+				DOORBELL_RANGE_LOWER,
+				adev->gfx.gfx_ring[0].doorbell_index + 2);
+
+		WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_LOWER, tmp);
 		WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_UPPER,
-					(adev->doorbell_index.userqueue_end * 2) << 2);
+				CP_MEC_DOORBELL_RANGE_UPPER__DOORBELL_RANGE_UPPER_MASK);
 	}
 
 	WREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL,
-- 
2.17.1