aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3083-drm-amd-display-Clean-up-dynamic-metadata-logic.patch
blob: 3f4ac77dceeba4aa1f19f8f9ac8fbedd108c4ddc (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
214
215
216
217
218
From f14a81f2232855ca1cd2f6725846cabdbb977dbe Mon Sep 17 00:00:00 2001
From: Julian Parkin <julian.parkin@amd.com>
Date: Wed, 3 Jul 2019 13:59:26 -0400
Subject: [PATCH 3083/4256] drm/amd/display: Clean up dynamic metadata logic

 [Why]
Code to enable DCN20 dynamic metadata feature is duplicated in two places
and was added to DCE110 enable stream.

[How]
Create DCN20 specific enable stream function for clarity, and add a hardware
sequencer function to program dynamic metadata to avoid the duplicate
code.

Signed-off-by: Julian Parkin <julian.parkin@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_stream.c   | 27 +++----
 .../display/dc/dce110/dce110_hw_sequencer.c   | 24 +-----
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    | 74 +++++++++++++++++++
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  1 +
 4 files changed, 86 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 35d697dd5808..41032c4c5bdf 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -563,6 +563,7 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
 
 	return ret;
 }
+
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 bool dc_stream_dmdata_status_done(struct dc *dc, struct dc_stream_state *stream)
 {
@@ -594,6 +595,14 @@ bool dc_stream_set_dynamic_metadata(struct dc *dc,
 	struct hubp *hubp;
 	int i;
 
+	/* Dynamic metadata is only supported on HDMI or DP */
+	if (!dc_is_hdmi_signal(stream->signal) && !dc_is_dp_signal(stream->signal))
+		return false;
+
+	/* Check hardware support */
+	if (!dc->hwss.program_dmdata_engine)
+		return false;
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream == stream)
@@ -609,23 +618,7 @@ bool dc_stream_set_dynamic_metadata(struct dc *dc,
 
 	pipe_ctx->stream->dmdata_address = attr->address;
 
-	if (pipe_ctx->stream_res.stream_enc &&
-			pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata != NULL) {
-		if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
-			/* if using dynamic meta, don't set up generic infopackets */
-			pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
-			pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-					pipe_ctx->stream_res.stream_enc,
-					true, pipe_ctx->plane_res.hubp->inst,
-					dc_is_dp_signal(pipe_ctx->stream->signal) ?
-							dmdata_dp : dmdata_hdmi);
-		} else
-			pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-					pipe_ctx->stream_res.stream_enc,
-					false, pipe_ctx->plane_res.hubp->inst,
-					dc_is_dp_signal(pipe_ctx->stream->signal) ?
-							dmdata_dp : dmdata_hdmi);
-	}
+	dc->hwss.program_dmdata_engine(pipe_ctx);
 
 	if (hubp->funcs->dmdata_set_attributes != NULL &&
 			pipe_ctx->stream->dmdata_address.quad_part != 0) {
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index fedbc6d0c40d..b8ef57a24228 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -664,29 +664,7 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
 	link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
 						    pipe_ctx->stream_res.stream_enc->id, true);
 
-	/* update AVI info frame (HDMI, DP)*/
-	/* TODO: FPGA may change to hwss.update_info_frame */
-
-#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
-	if (pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata != NULL &&
-			pipe_ctx->plane_res.hubp != NULL) {
-		if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
-			/* if using dynamic meta, don't set up generic infopackets */
-			pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
-			pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-					pipe_ctx->stream_res.stream_enc,
-					true, pipe_ctx->plane_res.hubp->inst,
-					dc_is_dp_signal(pipe_ctx->stream->signal) ?
-							dmdata_dp : dmdata_hdmi);
-		} else
-			pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-					pipe_ctx->stream_res.stream_enc,
-					false, pipe_ctx->plane_res.hubp->inst,
-					dc_is_dp_signal(pipe_ctx->stream->signal) ?
-							dmdata_dp : dmdata_hdmi);
-	}
-#endif
-	dce110_update_info_frame(pipe_ctx);
+	link->dc->hwss.update_info_frame(pipe_ctx);
 
 	/* enable early control to avoid corruption on DP monitor*/
 	active_total_with_borders =
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index c7c47f2a6e38..e60be115691b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -2058,6 +2058,78 @@ static void dcn20_set_flip_control_gsl(
 
 }
 
+static void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
+{
+	enum dc_lane_count lane_count =
+		pipe_ctx->stream->link->cur_link_settings.lane_count;
+
+	struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+	struct dc_link *link = pipe_ctx->stream->link;
+
+	uint32_t active_total_with_borders;
+	uint32_t early_control = 0;
+	struct timing_generator *tg = pipe_ctx->stream_res.tg;
+
+	/* For MST, there are multiply stream go to only one link.
+	 * connect DIG back_end to front_end while enable_stream and
+	 * disconnect them during disable_stream
+	 * BY this, it is logic clean to separate stream and link
+	 */
+	link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
+						    pipe_ctx->stream_res.stream_enc->id, true);
+
+	if (link->dc->hwss.program_dmdata_engine)
+		link->dc->hwss.program_dmdata_engine(pipe_ctx);
+
+	link->dc->hwss.update_info_frame(pipe_ctx);
+
+	/* enable early control to avoid corruption on DP monitor*/
+	active_total_with_borders =
+			timing->h_addressable
+				+ timing->h_border_left
+				+ timing->h_border_right;
+
+	if (lane_count != 0)
+		early_control = active_total_with_borders % lane_count;
+
+	if (early_control == 0)
+		early_control = lane_count;
+
+	tg->funcs->set_early_control(tg, early_control);
+
+	/* enable audio only within mode set */
+	if (pipe_ctx->stream_res.audio != NULL) {
+		if (dc_is_dp_signal(pipe_ctx->stream->signal))
+			pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
+	}
+}
+
+static void dcn20_program_dmdata_engine(struct pipe_ctx *pipe_ctx)
+{
+	struct dc_stream_state    *stream     = pipe_ctx->stream;
+	struct hubp               *hubp       = pipe_ctx->plane_res.hubp;
+	bool                       enable     = false;
+	struct stream_encoder     *stream_enc = pipe_ctx->stream_res.stream_enc;
+	enum dynamic_metadata_mode mode       = dc_is_dp_signal(stream->signal)
+							? dmdata_dp
+							: dmdata_hdmi;
+
+	/* if using dynamic meta, don't set up generic infopackets */
+	if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
+		pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
+		enable = true;
+	}
+
+	if (!hubp)
+		return;
+
+	if (!stream_enc || !stream_enc->funcs->set_dynamic_metadata)
+		return;
+
+	stream_enc->funcs->set_dynamic_metadata(stream_enc, enable,
+						hubp->inst, mode);
+}
+
 void dcn20_hw_sequencer_construct(struct dc *dc)
 {
 	dcn10_hw_sequencer_construct(dc);
@@ -2082,6 +2154,8 @@ void dcn20_hw_sequencer_construct(struct dc *dc)
 	dc->hwss.update_odm = dcn20_update_odm;
 	dc->hwss.blank_pixel_data = dcn20_blank_pixel_data;
 	dc->hwss.dmdata_status_done = dcn20_dmdata_status_done;
+	dc->hwss.program_dmdata_engine = dcn20_program_dmdata_engine;
+	dc->hwss.enable_stream = dcn20_enable_stream;
 	dc->hwss.disable_stream = dcn20_disable_stream;
 	dc->hwss.init_sys_ctx = dcn20_init_sys_ctx;
 	dc->hwss.init_vm_ctx = dcn20_init_vm_ctx;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index 36be08adae05..28645e10f854 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -231,6 +231,7 @@ struct hw_sequencer_funcs {
 	bool (*update_bandwidth)(
 			struct dc *dc,
 			struct dc_state *context);
+	void (*program_dmdata_engine)(struct pipe_ctx *pipe_ctx);
 	bool (*dmdata_status_done)(struct pipe_ctx *pipe_ctx);
 #endif
 
-- 
2.17.1