aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1297-drm-amd-display-dcn-add-check-surface-in_use.patch
blob: 9dca3e0b3396d0337abcb0aa5b1457ffca93d21a (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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
From 30811246cbd6287b00b9f8b018b9c809b35471f8 Mon Sep 17 00:00:00 2001
From: Charlene Liu <charlene.liu@amd.com>
Date: Mon, 4 Feb 2019 14:36:13 -0500
Subject: [PATCH 1297/2940] drm/amd/display: dcn add check surface in_use

Driver need to  poll the SURFACE_INUSE register to determine when to
start the new task and write data to the checked surface.

Implement the wait functions, and add the necessary hubbub registers.

Signed-off-by: Charlene Liu <charlene.liu@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  3 ++
 .../drm/amd/display/dc/dcn10/dcn10_hubbub.c   | 46 +++++++++++++++++++
 .../drm/amd/display/dc/dcn10/dcn10_hubbub.h   | 25 ++++++++--
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 22 ++++++++-
 .../gpu/drm/amd/display/dc/inc/hw/dchubbub.h  |  3 ++
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  2 +
 6 files changed, 97 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 0099e625ac88..73660bf903ae 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1723,6 +1723,9 @@ static void commit_planes_for_stream(struct dc *dc,
 
 			if (!pipe_ctx->plane_state)
 				continue;
+			/*make sure hw finished surface update*/
+			if (dc->hwss.wait_surface_safe_to_update)
+				dc->hwss.wait_surface_safe_to_update(dc, pipe_ctx);
 
 			/* Full fe update*/
 			if (update_type == UPDATE_TYPE_FAST)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
index e161ad836812..9c6217b99692 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
@@ -642,6 +642,50 @@ void hubbub1_soft_reset(struct hubbub *hubbub, bool reset)
 			DCHUBBUB_GLOBAL_SOFT_RESET, reset_en);
 }
 
+static bool hubbub1_is_surf_still_in_update(struct hubbub *hubbub, uint32_t hbup_inst)
+{
+	struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
+	uint32_t still_used_by_dcn = 0;
+
+	switch (hbup_inst) {
+	case 0:
+		REG_GET(SURFACE_CHECK0_ADDRESS_MSB,
+			CHECKER0_SURFACE_INUSE,
+			&still_used_by_dcn);
+		break;
+	case 1:
+		REG_GET(SURFACE_CHECK1_ADDRESS_MSB,
+			CHECKER1_SURFACE_INUSE,
+			&still_used_by_dcn);
+		break;
+	case 2:
+		REG_GET(SURFACE_CHECK2_ADDRESS_MSB,
+			CHECKER2_SURFACE_INUSE,
+			&still_used_by_dcn);
+		break;
+	case 3:
+		REG_GET(SURFACE_CHECK3_ADDRESS_MSB,
+			CHECKER3_SURFACE_INUSE,
+			&still_used_by_dcn);
+		break;
+	default:
+		break;
+	}
+	return (still_used_by_dcn == 1);
+}
+
+void hubbub1_wait_for_safe_surf_update(struct hubbub *hubbub, uint32_t hbup_inst)
+{
+	uint32_t still_used_by_dcn = 0, count = 0;
+
+	do {
+		still_used_by_dcn = hubbub1_is_surf_still_in_update(hubbub, hbup_inst);
+		udelay(1);
+		count++;
+	} while (still_used_by_dcn == 1 && count < 100);
+	ASSERT(count < 100);
+}
+
 static bool hubbub1_dcc_support_swizzle(
 		enum swizzle_mode_values swizzle,
 		unsigned int bytes_per_element,
@@ -860,12 +904,14 @@ static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub,
 	return true;
 }
 
+
 static const struct hubbub_funcs hubbub1_funcs = {
 	.update_dchub = hubbub1_update_dchub,
 	.dcc_support_swizzle = hubbub1_dcc_support_swizzle,
 	.dcc_support_pixel_format = hubbub1_dcc_support_pixel_format,
 	.get_dcc_compression_cap = hubbub1_get_dcc_compression_cap,
 	.wm_read_state = hubbub1_wm_read_state,
+	.wait_for_surf_safe_update = hubbub1_wait_for_safe_surf_update,
 };
 
 void hubbub1_construct(struct hubbub *hubbub,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
index 9cd4a5194154..f352e7ab0da6 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
@@ -52,7 +52,11 @@
 	SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
 	SR(DCHUBBUB_TEST_DEBUG_INDEX), \
 	SR(DCHUBBUB_TEST_DEBUG_DATA),\
-	SR(DCHUBBUB_SOFT_RESET)
+	SR(DCHUBBUB_SOFT_RESET),\
+	SR(SURFACE_CHECK0_ADDRESS_MSB),\
+	SR(SURFACE_CHECK1_ADDRESS_MSB),\
+	SR(SURFACE_CHECK2_ADDRESS_MSB),\
+	SR(SURFACE_CHECK3_ADDRESS_MSB)
 
 #define HUBBUB_SR_WATERMARK_REG_LIST()\
 	SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
@@ -116,6 +120,10 @@ struct dcn_hubbub_registers {
 	uint32_t DCN_VM_AGP_BOT;
 	uint32_t DCN_VM_AGP_TOP;
 	uint32_t DCN_VM_AGP_BASE;
+	uint32_t SURFACE_CHECK0_ADDRESS_MSB;
+	uint32_t SURFACE_CHECK1_ADDRESS_MSB;
+	uint32_t SURFACE_CHECK2_ADDRESS_MSB;
+	uint32_t SURFACE_CHECK3_ADDRESS_MSB;
 };
 
 /* set field name */
@@ -133,7 +141,11 @@ struct dcn_hubbub_registers {
 		HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \
 		HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \
 		HUBBUB_SF(DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \
-		HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh)
+		HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh),\
+		HUBBUB_SF(SURFACE_CHECK0_ADDRESS_MSB, CHECKER0_SURFACE_INUSE, mask_sh),\
+		HUBBUB_SF(SURFACE_CHECK1_ADDRESS_MSB, CHECKER1_SURFACE_INUSE, mask_sh),\
+		HUBBUB_SF(SURFACE_CHECK2_ADDRESS_MSB, CHECKER2_SURFACE_INUSE, mask_sh),\
+		HUBBUB_SF(SURFACE_CHECK3_ADDRESS_MSB, CHECKER3_SURFACE_INUSE, mask_sh)
 
 #define HUBBUB_MASK_SH_LIST_DCN10(mask_sh)\
 		HUBBUB_MASK_SH_LIST_DCN(mask_sh), \
@@ -167,7 +179,12 @@ struct dcn_hubbub_registers {
 		type FB_OFFSET;\
 		type AGP_BOT;\
 		type AGP_TOP;\
-		type AGP_BASE
+		type AGP_BASE;\
+		type CHECKER0_SURFACE_INUSE;\
+		type CHECKER1_SURFACE_INUSE;\
+		type CHECKER2_SURFACE_INUSE;\
+		type CHECKER3_SURFACE_INUSE
+
 
 
 struct dcn_hubbub_shift {
@@ -215,6 +232,8 @@ void hubbub1_wm_read_state(struct hubbub *hubbub,
 		struct dcn_hubbub_wm *wm);
 
 void hubbub1_soft_reset(struct hubbub *hubbub, bool reset);
+
+void hubbub1_wait_for_safe_surf_update(struct hubbub *hubbub, uint32_t hbup_inst);
 void hubbub1_construct(struct hubbub *hubbub,
 	struct dc_context *ctx,
 	const struct dcn_hubbub_registers *hubbub_regs,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 2a3bd75344fd..1131b0775534 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -88,6 +88,24 @@ static void log_mpc_crc(struct dc *dc,
 		REG_READ(DPP_TOP0_DPP_CRC_VAL_B_A), REG_READ(DPP_TOP0_DPP_CRC_VAL_R_G));
 }
 
+void dcn10_wait_for_surface_safe_to_use(struct dc *dc,
+	struct pipe_ctx *pipe_ctx)
+{
+	struct hubbub *hubbub = dc->res_pool->hubbub;
+
+	if (!pipe_ctx->plane_state)
+		return;
+	if (!pipe_ctx->stream)
+		return;
+
+	if (!pipe_ctx->plane_state->visible)
+		return;
+	if (hubbub->funcs->wait_for_surf_safe_update) {
+		hubbub->funcs->wait_for_surf_safe_update(dc->res_pool->hubbub,
+			pipe_ctx->plane_res.hubp->inst);
+	}
+}
+
 void dcn10_log_hubbub_state(struct dc *dc, struct dc_log_buffer_ctx *log_ctx)
 {
 	struct dc_context *dc_ctx = dc->ctx;
@@ -2945,7 +2963,9 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
 	.disable_stream_gating = NULL,
 	.enable_stream_gating = NULL,
 	.setup_periodic_interrupt = dcn10_setup_periodic_interrupt,
-	.setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt
+	.setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt,
+	.wait_surface_safe_to_update = dcn10_wait_for_surface_safe_to_use,
+
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
index 9d2d8e51306c..ac97d18d5568 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
@@ -73,6 +73,9 @@ struct hubbub_funcs {
 
 	void (*wm_read_state)(struct hubbub *hubbub,
 			struct dcn_hubbub_wm *wm);
+
+	void (*wait_for_surf_safe_update)(struct hubbub *hubbub,
+			uint32_t hbup_inst);
 };
 
 struct hubbub {
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 7676f25216b1..0ede4b604b77 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -232,6 +232,8 @@ struct hw_sequencer_funcs {
 	void (*setup_periodic_interrupt)(struct pipe_ctx *pipe_ctx, enum vline_select vline);
 	void (*setup_vupdate_interrupt)(struct pipe_ctx *pipe_ctx);
 
+	void (*wait_surface_safe_to_update)(struct dc *dc,
+			struct pipe_ctx *pipe_ctx);
 };
 
 void color_space_to_black_color(
-- 
2.17.1