aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/2465-drm-amd-display-Refactor-clk_mgr-functions.patch
blob: cdd73fb2fc217ad142cbfe03b497ad3eb8ea2e6c (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
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
From f141748d0ed80edd6695c0ade96b09b4bd65b9fa Mon Sep 17 00:00:00 2001
From: Eric Yang <Eric.Yang2@amd.com>
Date: Wed, 8 May 2019 19:06:30 -0400
Subject: [PATCH 2465/2940] drm/amd/display: Refactor clk_mgr functions

[Why]
Some HW specific implementations can be pulled out into clk_mgr.c.

[How]
- Pull get_active_display_cnt out to clk_mgr.
- Pull out shared logic in set_dispclk and set_dprefclk

Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c  | 25 ++++++++
 .../display/dc/clk_mgr/dcn10/rv1_clk_mgr.c    | 25 +-------
 .../dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c  | 58 ++++++++++---------
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  | 43 +++++---------
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h  |  2 +
 5 files changed, 71 insertions(+), 82 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
index 27d407a9b452..06e73ce45ed0 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
@@ -36,6 +36,31 @@
 #include "dcn10/rv2_clk_mgr.h"
 #include "dcn20/dcn20_clk_mgr.h"
 
+
+int clk_mgr_helper_get_active_display_cnt(
+		struct dc *dc,
+		struct dc_state *context)
+{
+	int i, display_count;
+
+	display_count = 0;
+	for (i = 0; i < context->stream_count; i++) {
+		const struct dc_stream_state *stream = context->streams[i];
+
+		/*
+		 * Only notify active stream or virtual stream.
+		 * Need to notify virtual stream to work around
+		 * headless case. HPD does not fire when system is in
+		 * S0i2.
+		 */
+		if (!stream->dpms_off || stream->signal == SIGNAL_TYPE_VIRTUAL)
+			display_count++;
+	}
+
+	return display_count;
+}
+
+
 struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg)
 {
 	struct hw_asic_id asic_id = ctx->asic_id;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c
index 0a083a5e89ca..a8e175cb0fe2 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c
@@ -114,29 +114,6 @@ static void ramp_up_dispclk_with_dpp(struct clk_mgr_internal *clk_mgr, struct dc
 	clk_mgr->base.clks.max_supported_dppclk_khz = new_clocks->max_supported_dppclk_khz;
 }
 
-static int get_active_display_cnt(
-		struct dc *dc,
-		struct dc_state *context)
-{
-	int i, display_count;
-
-	display_count = 0;
-	for (i = 0; i < context->stream_count; i++) {
-		const struct dc_stream_state *stream = context->streams[i];
-
-		/*
-		 * Only notify active stream or virtual stream.
-		 * Need to notify virtual stream to work around
-		 * headless case. HPD does not fire when system is in
-		 * S0i2.
-		 */
-		if (!stream->dpms_off || stream->signal == SIGNAL_TYPE_VIRTUAL)
-			display_count++;
-	}
-
-	return display_count;
-}
-
 static void rv1_update_clocks(struct clk_mgr *clk_mgr_base,
 			struct dc_state *context,
 			bool safe_to_lower)
@@ -156,7 +133,7 @@ static void rv1_update_clocks(struct clk_mgr *clk_mgr_base,
 
 	pp_smu = &clk_mgr->pp_smu->rv_funcs;
 
-	display_count = get_active_display_cnt(dc, context);
+	display_count = clk_mgr_helper_get_active_display_cnt(dc, context);
 
 	if (display_count == 0)
 		enter_display_off = true;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c
index 196087072063..1897e91c8ccb 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c
@@ -68,57 +68,59 @@ static const struct IP_BASE MP1_BASE  = { { { { 0x00016000, 0, 0, 0, 0 } },
 #define VBIOSSMC_MSG_SetDispclkFreq           0x4
 #define VBIOSSMC_MSG_SetDprefclkFreq          0x5
 
-int rv1_vbios_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz)
+int rv1_vbios_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, unsigned int msg_id, unsigned int param)
 {
-
-	int actual_dispclk_set_khz = -1;
-	struct dc *core_dc = clk_mgr->base.ctx->dc;
-	struct dmcu *dmcu = core_dc->res_pool->dmcu;
-
 	/* First clear response register */
-	//dm_write_reg(ctx, mmMP1_SMN_C2PMSG_91, 0);
 	REG_WRITE(MP1_SMN_C2PMSG_91, 0);
 
 	/* Set the parameter register for the SMU message, unit is Mhz */
-	//dm_write_reg(ctx, mmMP1_SMN_C2PMSG_83, requested_dispclk_khz / 1000);
-	REG_WRITE(MP1_SMN_C2PMSG_83, requested_dispclk_khz / 1000);
+	REG_WRITE(MP1_SMN_C2PMSG_83, param);
 
 	/* Trigger the message transaction by writing the message ID */
-	//dm_write_reg(ctx, mmMP1_SMN_C2PMSG_67, VBIOSSMC_MSG_SetDispclkFreq);
-	REG_WRITE(MP1_SMN_C2PMSG_67, VBIOSSMC_MSG_SetDispclkFreq);
+	REG_WRITE(MP1_SMN_C2PMSG_67, msg_id);
 
 	REG_WAIT(MP1_SMN_C2PMSG_91, CONTENT, 1, 10, 200000);
 
 	/* Actual dispclk set is returned in the parameter register */
-	actual_dispclk_set_khz = REG_READ(MP1_SMN_C2PMSG_83) * 1000;
+	return REG_READ(MP1_SMN_C2PMSG_83);
+}
+
+int rv1_vbios_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz)
+{
+	int actual_dispclk_set_mhz = -1;
+	struct dc *core_dc = clk_mgr->base.ctx->dc;
+	struct dmcu *dmcu = core_dc->res_pool->dmcu;
+
+	/*  Unit of SMU msg parameter is Mhz */
+	actual_dispclk_set_mhz = rv1_vbios_smu_send_msg_with_param(
+			clk_mgr,
+			VBIOSSMC_MSG_SetDispclkFreq,
+			requested_dispclk_khz / 1000);
+
+	/* Actual dispclk set is returned in the parameter register */
+	actual_dispclk_set_mhz = REG_READ(MP1_SMN_C2PMSG_83) * 1000;
 
 	if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
 		if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) {
-			if (clk_mgr->dfs_bypass_disp_clk != actual_dispclk_set_khz)
+			if (clk_mgr->dfs_bypass_disp_clk != actual_dispclk_set_mhz)
 				dmcu->funcs->set_psr_wait_loop(dmcu,
-						actual_dispclk_set_khz / 1000 / 7);
+						actual_dispclk_set_mhz / 7);
 		}
 	}
 
-	return actual_dispclk_set_khz;
+	return actual_dispclk_set_mhz * 1000;
 }
 
 int rv1_vbios_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr)
 {
-	int actual_dprefclk_set_khz = -1;
-
-	REG_WRITE(MP1_SMN_C2PMSG_91, 0);
-
-	/* Set the parameter register for the SMU message */
-	REG_WRITE(MP1_SMN_C2PMSG_83, clk_mgr->base.dprefclk_khz / 1000);
+	int actual_dprefclk_set_mhz = -1;
 
-	/* Trigger the message transaction by writing the message ID */
-	REG_WRITE(MP1_SMN_C2PMSG_67, VBIOSSMC_MSG_SetDprefclkFreq);
-
-	/* Wait for SMU response */
-	REG_WAIT(MP1_SMN_C2PMSG_91, CONTENT, 1, 10, 200000);
+	actual_dprefclk_set_mhz = rv1_vbios_smu_send_msg_with_param(
+			clk_mgr,
+			VBIOSSMC_MSG_SetDprefclkFreq,
+			clk_mgr->base.dprefclk_khz / 1000);
 
-	actual_dprefclk_set_khz = REG_READ(MP1_SMN_C2PMSG_83) * 1000;
+	/* TODO: add code for programing DP DTO, currently this is down by command table */
 
-	return actual_dprefclk_set_khz;
+	return actual_dprefclk_set_mhz * 1000;
 }
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index ca3e40053978..5814cacbe1be 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -101,30 +101,7 @@ static uint32_t dentist_get_did_from_divider(int divider)
 	return divider_id;
 }
 
-static int get_active_display_cnt(
-		struct dc *dc,
-		struct dc_state *context)
-{
-	int i, display_count;
-
-	display_count = 0;
-	for (i = 0; i < context->stream_count; i++) {
-		const struct dc_stream_state *stream = context->streams[i];
-
-		/*
-		 * Only notify active stream or virtual stream.
-		 * Need to notify virtual stream to work around
-		 * headless case. HPD does not fire when system is in
-		 * S0i2.
-		 */
-		if (!stream->dpms_off || stream->signal == SIGNAL_TYPE_VIRTUAL)
-			display_count++;
-	}
-
-	return display_count;
-}
-
-static void update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
+void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
 		struct dc_state *context)
 {
 	int i;
@@ -143,7 +120,7 @@ static void update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
 	}
 }
 
-static void update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr)
+void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr)
 {
 	int dpp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
 			* clk_mgr->dentist_vco_freq_khz / clk_mgr->base.clks.dppclk_khz;
@@ -177,7 +154,7 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
 	bool dpp_clock_lowered = false;
 	struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu;
 
-	display_count = get_active_display_cnt(dc, context);
+	display_count = clk_mgr_helper_get_active_display_cnt(dc, context);
 	if (dc->res_pool->pp_smu)
 		pp_smu = &dc->res_pool->pp_smu->nv_funcs;
 
@@ -246,15 +223,21 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
 
 	if (dpp_clock_lowered) {
 		// if clock is being lowered, increase DTO before lowering refclk
-		update_clocks_update_dpp_dto(clk_mgr, context);
-		update_clocks_update_dentist(clk_mgr);
+		dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
+		dcn20_update_clocks_update_dentist(clk_mgr);
 	} else {
 		// if clock is being raised, increase refclk before lowering DTO
 		if (update_dppclk || update_dispclk)
-			update_clocks_update_dentist(clk_mgr);
+			dcn20_update_clocks_update_dentist(clk_mgr);
 		if (update_dppclk)
-			update_clocks_update_dpp_dto(clk_mgr, context);
+			dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
+	}
 
+	if (update_dispclk &&
+			dmcu && dmcu->funcs->is_dmcu_initialized(dmcu)) {
+		/*update dmcu for wait_loop count*/
+		dmcu->funcs->set_psr_wait_loop(dmcu,
+			clk_mgr_base->clks.dispclk_khz / 1000 / 7);
 	}
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h
index a3479f96eb9b..a44afc0625c5 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h
@@ -33,6 +33,8 @@ void dcn2_update_clocks(struct clk_mgr *dccg,
 void dcn2_update_clocks_fpga(struct clk_mgr *clk_mgr,
 			struct dc_state *context,
 			bool safe_to_lower);
+void dcn20_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
+		struct dc_state *context);
 
 void dcn2_init_clocks(struct clk_mgr *clk_mgr);
 
-- 
2.17.1