aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3484-drm-amd-display-Split-out-DC-programming-for-CRC-cap.patch
blob: ba763291bd1b9d466ad16fc25ec47af8109649f5 (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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
From d91c8aa3df7acd7c4b51cc926c7bc45f9b4a7781 Mon Sep 17 00:00:00 2001
From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Date: Tue, 20 Aug 2019 10:16:14 -0400
Subject: [PATCH 3484/4256] drm/amd/display: Split out DC programming for CRC
 capture

[Why]
Calling amdgpu_dm_crtc_set_crc_source in amdgpu_dm directly has the
consequence of adding additional vblank references or starting DPRX
CRC capture more than once without calling stop first.

Vblank references for CRC capture should be managed entirely by opening
and closing the CRC file from userspace.

Stream state also shouldn't be required on the CRC so we can close the
file after the CRTC has been disabled.

[How]
Do DC programming required for configuring CRC capture separately from
setting the source. Whenever we re-enable or reset a CRC this
programming should be reapplied.

CRC vblank reference handling in amdgpu_dm can be entirely dropped after
this.

Stream state also no longer needs to be required since we can just defer
the programming to when the stream is actually enabled.

Change-Id: Icc9a42f2e91cf2873704b45fbff4694a457219e5
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: David Francis <David.Francis@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 25 ++------
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 63 ++++++++++++-------
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h |  6 ++
 3 files changed, 49 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 474eb6849dc7..76708b620892 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5982,11 +5982,9 @@ static void amdgpu_dm_enable_crtc_interrupts(struct drm_device *dev,
 		/* The stream has changed so CRC capture needs to re-enabled. */
                 source = dm_new_crtc_state->crc_src;
                 if (amdgpu_dm_is_valid_crc_source(source)) {
-                        dm_new_crtc_state->crc_src = AMDGPU_DM_PIPE_CRC_SOURCE_NONE;
-                        if (source == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC)
-                                amdgpu_dm_crtc_set_crc_source(crtc, "crtc");
-                        else if (source == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX)
-                                amdgpu_dm_crtc_set_crc_source(crtc, "dprx");
+			amdgpu_dm_crtc_configure_crc_source(
+					crtc, dm_new_crtc_state,
+					dm_new_crtc_state->crc_src);
 		}
 #endif
 	}
@@ -6037,23 +6035,8 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev,
 
                 if (dm_old_crtc_state->interrupts_enabled &&
                     (!dm_new_crtc_state->interrupts_enabled ||
-                     drm_atomic_crtc_needs_modeset(new_crtc_state))) {
-			/*
-                         * Drop the extra vblank reference added by CRC
-                         * capture if applicable.
-                         */
-			if (amdgpu_dm_is_valid_crc_source(dm_new_crtc_state->crc_src))
-                                drm_crtc_vblank_put(crtc);
-
-                        /*
-                         * Only keep CRC capture enabled if there's
-                         * still a stream for the CRTC.
-                         */
-                        if (!dm_new_crtc_state->stream)
-				dm_new_crtc_state->crc_src = AMDGPU_DM_PIPE_CRC_SOURCE_NONE;
-
+		     drm_atomic_crtc_needs_modeset(new_crtc_state)))
 			manage_dm_interrupts(adev, acrtc, false);
-		}
 	}
 	/* Add check here for SoC's that support hardware cursor plane, to
 	 * unset legacy_cursor_update */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
index 422d9ac3b83d..d2099d649028 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -97,11 +97,47 @@ amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc, const char *src_name,
 	return 0;
 }
 
+int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc,
+                                        struct dm_crtc_state *dm_crtc_state,
+                                        enum amdgpu_dm_pipe_crc_source source)
+{
+        struct amdgpu_device *adev = crtc->dev->dev_private;
+        struct dc_stream_state *stream_state = dm_crtc_state->stream;
+        bool enable = amdgpu_dm_is_valid_crc_source(source);
+        int ret = 0;
+
+        /* Configuration will be deferred to stream enable. */
+        if (!stream_state)
+                return 0;
+
+        mutex_lock(&adev->dm.dc_lock);
+
+        /* Enable CRTC CRC generation if necessary. */
+        if (dm_is_crc_source_crtc(source)) {
+                if (!dc_stream_configure_crc(stream_state->ctx->dc,
+                                             stream_state, enable, enable)) {
+                        ret = -EINVAL;
+                        goto unlock;
+                }
+        }
+
+        /* Configure dithering */
+        if (!dm_need_crc_dither(source))
+                dc_stream_set_dither_option(stream_state, DITHER_OPTION_TRUN8);
+        else
+                dc_stream_set_dither_option(stream_state,
+                                            DITHER_OPTION_DEFAULT);
+
+unlock:
+        mutex_unlock(&adev->dm.dc_lock);
+
+        return ret;
+}
+
 int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 {
 	struct amdgpu_device *adev = crtc->dev->dev_private;
 	struct dm_crtc_state *crtc_state = to_dm_crtc_state(crtc->state);
-	struct dc_stream_state *stream_state = crtc_state->stream;
 	struct drm_dp_aux *aux = NULL;
 	bool enable = false;
 	bool enabled = false;
@@ -115,15 +151,8 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 		return -EINVAL;
 	}
 
-	if (!stream_state) {
-		DRM_ERROR("No stream state for CRTC%d\n", crtc->index);
-		return -EINVAL;
-	}
-
 	enable = amdgpu_dm_is_valid_crc_source(source);
 
-	mutex_lock(&adev->dm.dc_lock);
-
         /*
          * USER REQ SRC | CURRENT SRC | BEHAVIOR
          * -----------------------------
@@ -156,7 +185,6 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 
                 if (!aconn) {
                         DRM_DEBUG_DRIVER("No amd connector matching CRTC-%d\n", crtc->index);
-                        mutex_unlock(&adev->dm.dc_lock);
                         return -EINVAL;
                 }
 
@@ -164,25 +192,12 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 
                 if (!aux) {
                         DRM_DEBUG_DRIVER("No dp aux for amd connector\n");
-                        mutex_unlock(&adev->dm.dc_lock);
-                        return -EINVAL;
-                }
-	} else if (dm_is_crc_source_crtc(source)) {
-                if (!dc_stream_configure_crc(stream_state->ctx->dc, stream_state,
-                                             enable, enable)) {
-                        mutex_unlock(&adev->dm.dc_lock);
                         return -EINVAL;
                 }
         }
 
-        /* configure dithering */
-        if (!dm_need_crc_dither(source))
-                dc_stream_set_dither_option(stream_state, DITHER_OPTION_TRUN8);
-        else if (!dm_need_crc_dither(crtc_state->crc_src))
-                dc_stream_set_dither_option(stream_state, DITHER_OPTION_DEFAULT);
-
-	mutex_unlock(&adev->dm.dc_lock);
-
+	if (amdgpu_dm_crtc_configure_crc_source(crtc, crtc_state, source))
+		return -EINVAL;
 	/*
 	 * Reading the CRC requires the vblank interrupt handler to be
 	 * enabled. Keep a reference until CRC capture stops.
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
index 14de7301c28d..cc415ecc2c1a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
@@ -26,6 +26,9 @@
 #ifndef AMD_DAL_DEV_AMDGPU_DM_AMDGPU_DM_CRC_H_
 #define AMD_DAL_DEV_AMDGPU_DM_AMDGPU_DM_CRC_H_
 
+struct drm_crtc;
+struct dm_crtc_state;
+
 enum amdgpu_dm_pipe_crc_source {
 	AMDGPU_DM_PIPE_CRC_SOURCE_NONE = 0,
 	AMDGPU_DM_PIPE_CRC_SOURCE_CRTC,
@@ -44,6 +47,9 @@ static inline bool amdgpu_dm_is_valid_crc_source(enum amdgpu_dm_pipe_crc_source
 
 /* amdgpu_dm_crc.c */
 #ifdef CONFIG_DEBUG_FS
+int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc,
+                                        struct dm_crtc_state *dm_crtc_state,
+                                        enum amdgpu_dm_pipe_crc_source source);
 int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name);
 int amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc,
 				     const char *src_name,
-- 
2.17.1