aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4439-drm-amdgpu-don-t-read-registers-if-gfxoff-is-enabled.patch
blob: 1aba1752cef80a4a02d8554b8a0b416edcce85b5 (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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
From 3aaf57ff28015d3d07f80b8c1540d75b2d20f288 Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexander.deucher@amd.com>
Date: Tue, 12 Nov 2019 09:46:54 -0500
Subject: [PATCH 4439/4736] drm/amdgpu: don't read registers if gfxoff is
 enabled (v2)

When gfxoff is enabled, accessing gfx registers via MMIO
can lead to a hang.

v2: return cached registers properly.

Bug: https://bugzilla.kernel.org/show_bug.cgi?id=205497
Reviewed-by: Evan Quan <evan.quan@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/nv.c    | 27 ++++++++++++++++----------
 drivers/gpu/drm/amd/amdgpu/soc15.c | 31 ++++++++++++++++++------------
 2 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
index b33da33214eb..be761785b2a8 100644
--- a/drivers/gpu/drm/amd/amdgpu/nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/nv.c
@@ -200,17 +200,25 @@ static uint32_t nv_read_indexed_register(struct amdgpu_device *adev, u32 se_num,
 	return val;
 }
 
-static uint32_t nv_get_register_value(struct amdgpu_device *adev,
+static int nv_get_register_value(struct amdgpu_device *adev,
 				      bool indexed, u32 se_num,
-				      u32 sh_num, u32 reg_offset)
+				      u32 sh_num, u32 reg_offset,
+				      u32 *value)
 {
 	if (indexed) {
-		return nv_read_indexed_register(adev, se_num, sh_num, reg_offset);
+		if (adev->pm.pp_feature & PP_GFXOFF_MASK)
+			return -EINVAL;
+		*value = nv_read_indexed_register(adev, se_num, sh_num, reg_offset);
 	} else {
-		if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG))
-			return adev->gfx.config.gb_addr_config;
-		return RREG32(reg_offset);
+		if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG)) {
+			*value = adev->gfx.config.gb_addr_config;
+		} else {
+			if (adev->pm.pp_feature & PP_GFXOFF_MASK)
+				return -EINVAL;
+			*value = RREG32(reg_offset);
+		}
 	}
+	return 0;
 }
 
 static int nv_read_register(struct amdgpu_device *adev, u32 se_num,
@@ -226,10 +234,9 @@ static int nv_read_register(struct amdgpu_device *adev, u32 se_num,
 		    (adev->reg_offset[en->hwip][en->inst][en->seg] + en->reg_offset))
 			continue;
 
-		*value = nv_get_register_value(adev,
-					       nv_allowed_read_registers[i].grbm_indexed,
-					       se_num, sh_num, reg_offset);
-		return 0;
+		return nv_get_register_value(adev,
+					     nv_allowed_read_registers[i].grbm_indexed,
+					     se_num, sh_num, reg_offset, value);
 	}
 	return -EINVAL;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
index e12cdbdd9aed..836a34c10db2 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -362,19 +362,27 @@ static uint32_t soc15_read_indexed_register(struct amdgpu_device *adev, u32 se_n
 	return val;
 }
 
-static uint32_t soc15_get_register_value(struct amdgpu_device *adev,
+static int soc15_get_register_value(struct amdgpu_device *adev,
 					 bool indexed, u32 se_num,
-					 u32 sh_num, u32 reg_offset)
+					 u32 sh_num, u32 reg_offset,
+					 u32 *value)
 {
 	if (indexed) {
-		return soc15_read_indexed_register(adev, se_num, sh_num, reg_offset);
+		if (adev->pm.pp_feature & PP_GFXOFF_MASK)
+			return -EINVAL;
+	        *value = soc15_read_indexed_register(adev, se_num, sh_num, reg_offset);
 	} else {
-		if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG))
-			return adev->gfx.config.gb_addr_config;
-		else if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmDB_DEBUG2))
-			return adev->gfx.config.db_debug2;
-		return RREG32(reg_offset);
+		if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG)) {
+			*value = adev->gfx.config.gb_addr_config;
+		} else if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmDB_DEBUG2)) {
+			*value = adev->gfx.config.db_debug2;
+		} else {
+			if (adev->pm.pp_feature & PP_GFXOFF_MASK)
+				return -EINVAL;
+			*value = RREG32(reg_offset);
+		}
 	}
+	return 0;
 }
 
 static int soc15_read_register(struct amdgpu_device *adev, u32 se_num,
@@ -390,10 +398,9 @@ static int soc15_read_register(struct amdgpu_device *adev, u32 se_num,
 					+ en->reg_offset))
 			continue;
 
-		*value = soc15_get_register_value(adev,
-						  soc15_allowed_read_registers[i].grbm_indexed,
-						  se_num, sh_num, reg_offset);
-		return 0;
+		return soc15_get_register_value(adev,
+						soc15_allowed_read_registers[i].grbm_indexed,
+						se_num, sh_num, reg_offset, value);
 	}
 	return -EINVAL;
 }
-- 
2.17.1