xref: /linux/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c (revision 0a5e0416e191571de9362b769feb31b3e87a705e)
1 /*
2  * Copyright 2012-16 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 #include "dal_asic_id.h"
27 #include "dc_types.h"
28 #include "dccg.h"
29 #include "clk_mgr_internal.h"
30 #include "dc_state_priv.h"
31 #include "link_service.h"
32 
33 #include "dce100/dce_clk_mgr.h"
34 #include "dce110/dce110_clk_mgr.h"
35 #include "dce112/dce112_clk_mgr.h"
36 #include "dce120/dce120_clk_mgr.h"
37 #include "dcn10/rv1_clk_mgr.h"
38 #include "dcn10/rv2_clk_mgr.h"
39 #include "dcn20/dcn20_clk_mgr.h"
40 #include "dcn21/rn_clk_mgr.h"
41 #include "dcn201/dcn201_clk_mgr.h"
42 #include "dcn30/dcn30_clk_mgr.h"
43 #include "dcn301/vg_clk_mgr.h"
44 #include "dcn31/dcn31_clk_mgr.h"
45 #include "dcn314/dcn314_clk_mgr.h"
46 #include "dcn315/dcn315_clk_mgr.h"
47 #include "dcn316/dcn316_clk_mgr.h"
48 #include "dcn32/dcn32_clk_mgr.h"
49 #include "dcn35/dcn35_clk_mgr.h"
50 #include "dcn401/dcn401_clk_mgr.h"
51 #include "dcn42/dcn42_clk_mgr.h"
52 #include "dcn42b/dcn42b_clk_mgr.h"
53 
54 int clk_mgr_helper_get_active_display_cnt(
55 		struct dc *dc,
56 		struct dc_state *context)
57 {
58 	int i, display_count;
59 
60 	display_count = 0;
61 	for (i = 0; i < context->stream_count; i++) {
62 		const struct dc_stream_state *stream = context->streams[i];
63 		const struct dc_stream_status *stream_status = &context->stream_status[i];
64 
65 		/* Don't count SubVP phantom pipes as part of active
66 		 * display count
67 		 */
68 		if (dc_state_get_stream_subvp_type(context, stream) == SUBVP_PHANTOM)
69 			continue;
70 
71 		if (!stream->dpms_off || dc->is_switch_in_progress_dest || (stream_status && stream_status->plane_count))
72 			display_count++;
73 	}
74 
75 	return display_count;
76 }
77 
78 int clk_mgr_helper_get_active_plane_cnt(
79 		struct dc *dc,
80 		struct dc_state *context)
81 {
82 	(void)dc;
83 	int i, total_plane_count;
84 
85 	total_plane_count = 0;
86 	for (i = 0; i < context->stream_count; i++) {
87 		const struct dc_stream_status stream_status = context->stream_status[i];
88 
89 		/*
90 		 * Sum up plane_count for all streams ( active and virtual ).
91 		 */
92 		total_plane_count += stream_status.plane_count;
93 	}
94 
95 	return total_plane_count;
96 }
97 
98 void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
99 {
100 	struct dc_link *edp_links[MAX_NUM_EDP];
101 	struct dc_link *edp_link = NULL;
102 	unsigned int edp_num;
103 	unsigned int panel_inst;
104 
105 	dc_get_edp_links(dc, edp_links, &edp_num);
106 	if (dc->hwss.exit_optimized_pwr_state)
107 		dc->hwss.exit_optimized_pwr_state(dc, dc->current_state);
108 
109 	if (edp_num) {
110 		for (panel_inst = 0; panel_inst < edp_num; panel_inst++) {
111 			bool allow_active = false;
112 
113 			edp_link = edp_links[panel_inst];
114 			if (!edp_link->psr_settings.psr_feature_enabled)
115 				continue;
116 			clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active;
117 			dc->link_srv->edp_set_psr_allow_active(edp_link, &allow_active, false, false, NULL);
118 			dc->link_srv->edp_set_replay_allow_active(edp_link, &allow_active, false, false, NULL);
119 		}
120 	}
121 
122 }
123 
124 void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
125 {
126 	struct dc_link *edp_links[MAX_NUM_EDP];
127 	struct dc_link *edp_link = NULL;
128 	unsigned int edp_num;
129 	unsigned int panel_inst;
130 
131 	dc_get_edp_links(dc, edp_links, &edp_num);
132 	if (edp_num) {
133 		for (panel_inst = 0; panel_inst < edp_num; panel_inst++) {
134 			edp_link = edp_links[panel_inst];
135 			if (!edp_link->psr_settings.psr_feature_enabled)
136 				continue;
137 			dc->link_srv->edp_set_psr_allow_active(edp_link,
138 					&clk_mgr->psr_allow_active_cache, false, false, NULL);
139 			dc->link_srv->edp_set_replay_allow_active(edp_link,
140 					&clk_mgr->psr_allow_active_cache, false, false, NULL);
141 		}
142 	}
143 
144 	if (dc->hwss.optimize_pwr_state)
145 		dc->hwss.optimize_pwr_state(dc, dc->current_state);
146 
147 }
148 
149 struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg)
150 {
151 	struct hw_asic_id asic_id = ctx->asic_id;
152 
153 	switch (asic_id.chip_family) {
154 	case FAMILY_SI:
155 	case FAMILY_CI:
156 	case FAMILY_KV: {
157 		struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr);
158 
159 		if (clk_mgr == NULL) {
160 			BREAK_TO_DEBUGGER();
161 			return NULL;
162 		}
163 		dce_clk_mgr_construct(ctx, clk_mgr);
164 		return &clk_mgr->base;
165 	}
166 	case FAMILY_CZ: {
167 		struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr);
168 
169 		if (clk_mgr == NULL) {
170 			BREAK_TO_DEBUGGER();
171 			return NULL;
172 		}
173 		dce110_clk_mgr_construct(ctx, clk_mgr);
174 		return &clk_mgr->base;
175 	}
176 	case FAMILY_VI: {
177 		struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr);
178 
179 		if (clk_mgr == NULL) {
180 			BREAK_TO_DEBUGGER();
181 			return NULL;
182 		}
183 		if (ASIC_REV_IS_TONGA_P(asic_id.hw_internal_rev) ||
184 				ASIC_REV_IS_FIJI_P(asic_id.hw_internal_rev)) {
185 			dce_clk_mgr_construct(ctx, clk_mgr);
186 			return &clk_mgr->base;
187 		}
188 		if (ASIC_REV_IS_POLARIS10_P(asic_id.hw_internal_rev) ||
189 				ASIC_REV_IS_POLARIS11_M(asic_id.hw_internal_rev) ||
190 				ASIC_REV_IS_POLARIS12_V(asic_id.hw_internal_rev)) {
191 			dce112_clk_mgr_construct(ctx, clk_mgr);
192 			return &clk_mgr->base;
193 		}
194 		if (ASIC_REV_IS_VEGAM(asic_id.hw_internal_rev)) {
195 			dce112_clk_mgr_construct(ctx, clk_mgr);
196 			return &clk_mgr->base;
197 		}
198 		return &clk_mgr->base;
199 	}
200 	case FAMILY_AI: {
201 		struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr);
202 
203 		if (clk_mgr == NULL) {
204 			BREAK_TO_DEBUGGER();
205 			return NULL;
206 		}
207 		if (ASICREV_IS_VEGA20_P(asic_id.hw_internal_rev))
208 			dce121_clk_mgr_construct(ctx, clk_mgr);
209 		else
210 			dce120_clk_mgr_construct(ctx, clk_mgr);
211 		return &clk_mgr->base;
212 	}
213 #if defined(CONFIG_DRM_AMD_DC_FP)
214 	case FAMILY_RV: {
215 		struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr);
216 
217 		if (clk_mgr == NULL) {
218 			BREAK_TO_DEBUGGER();
219 			return NULL;
220 		}
221 
222 		if (ASICREV_IS_RENOIR(asic_id.hw_internal_rev)) {
223 			rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
224 			return &clk_mgr->base;
225 		}
226 
227 		if (ASICREV_IS_GREEN_SARDINE(asic_id.hw_internal_rev)) {
228 			rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
229 			return &clk_mgr->base;
230 		}
231 		if (ASICREV_IS_RAVEN2(asic_id.hw_internal_rev)) {
232 			rv2_clk_mgr_construct(ctx, clk_mgr, pp_smu);
233 			return &clk_mgr->base;
234 		}
235 		if (ASICREV_IS_RAVEN(asic_id.hw_internal_rev) ||
236 				ASICREV_IS_PICASSO(asic_id.hw_internal_rev)) {
237 			rv1_clk_mgr_construct(ctx, clk_mgr, pp_smu);
238 			return &clk_mgr->base;
239 		}
240 		return &clk_mgr->base;
241 	}
242 	case FAMILY_NV: {
243 		struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr);
244 
245 		if (clk_mgr == NULL) {
246 			BREAK_TO_DEBUGGER();
247 			return NULL;
248 		}
249 		if (ctx->dce_version == DCN_VERSION_2_01) {
250 			dcn201_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
251 			return &clk_mgr->base;
252 		}
253 		if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) {
254 			dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
255 			return &clk_mgr->base;
256 		}
257 		if (ASICREV_IS_DIMGREY_CAVEFISH_P(asic_id.hw_internal_rev)) {
258 			dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
259 			return &clk_mgr->base;
260 		}
261 		if (ASICREV_IS_BEIGE_GOBY_P(asic_id.hw_internal_rev)) {
262 			dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
263 			return &clk_mgr->base;
264 		}
265 		dcn20_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
266 		return &clk_mgr->base;
267 	}
268 	case FAMILY_VGH:
269 		if (ASICREV_IS_VANGOGH(asic_id.hw_internal_rev)) {
270 			struct clk_mgr_vgh *clk_mgr = kzalloc_obj(*clk_mgr);
271 
272 			if (clk_mgr == NULL) {
273 				BREAK_TO_DEBUGGER();
274 				return NULL;
275 			}
276 			vg_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
277 			return &clk_mgr->base.base;
278 		}
279 		break;
280 
281 	case FAMILY_YELLOW_CARP: {
282 		struct clk_mgr_dcn31 *clk_mgr = kzalloc_obj(*clk_mgr);
283 
284 		if (clk_mgr == NULL) {
285 			BREAK_TO_DEBUGGER();
286 			return NULL;
287 		}
288 
289 		dcn31_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
290 		return &clk_mgr->base.base;
291 	}
292 		break;
293 	case AMDGPU_FAMILY_GC_10_3_6: {
294 		struct clk_mgr_dcn315 *clk_mgr = kzalloc_obj(*clk_mgr);
295 
296 		if (clk_mgr == NULL) {
297 			BREAK_TO_DEBUGGER();
298 			return NULL;
299 		}
300 
301 		dcn315_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
302 		return &clk_mgr->base.base;
303 	}
304 		break;
305 	case AMDGPU_FAMILY_GC_10_3_7: {
306 		struct clk_mgr_dcn316 *clk_mgr = kzalloc_obj(*clk_mgr);
307 
308 		if (clk_mgr == NULL) {
309 			BREAK_TO_DEBUGGER();
310 			return NULL;
311 		}
312 
313 		dcn316_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
314 		return &clk_mgr->base.base;
315 	}
316 		break;
317 	case AMDGPU_FAMILY_GC_11_0_0: {
318 		struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr);
319 
320 		if (clk_mgr == NULL) {
321 			BREAK_TO_DEBUGGER();
322 			return NULL;
323 		}
324 		dcn32_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
325 		return &clk_mgr->base;
326 	}
327 
328 	case AMDGPU_FAMILY_GC_11_0_1: {
329 		struct clk_mgr_dcn314 *clk_mgr = kzalloc_obj(*clk_mgr);
330 
331 		if (clk_mgr == NULL) {
332 			BREAK_TO_DEBUGGER();
333 			return NULL;
334 		}
335 
336 		dcn314_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
337 		return &clk_mgr->base.base;
338 	}
339 	break;
340 
341 	case AMDGPU_FAMILY_GC_11_5_0: {
342 		if (ctx->dce_version == DCN_VERSION_4_2B) {
343 			struct clk_mgr_dcn42 *clk_mgr = kzalloc_obj(*clk_mgr);
344 
345 			if (clk_mgr == NULL) {
346 				BREAK_TO_DEBUGGER();
347 				return NULL;
348 			}
349 			dcn42b_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
350 			return &clk_mgr->base.base;
351 		}
352 		struct clk_mgr_dcn35 *clk_mgr = kzalloc_obj(*clk_mgr);
353 
354 		if (clk_mgr == NULL) {
355 			BREAK_TO_DEBUGGER();
356 			return NULL;
357 		}
358 		if (ctx->dce_version == DCN_VERSION_3_51)
359 			dcn351_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
360 		else
361 			dcn35_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
362 
363 		return &clk_mgr->base.base;
364 	}
365 	break;
366 
367 	case AMDGPU_FAMILY_GC_12_0_0: {
368 		struct clk_mgr_internal *clk_mgr = dcn401_clk_mgr_construct(ctx, dccg);
369 
370 		if (clk_mgr == NULL) {
371 			BREAK_TO_DEBUGGER();
372 			return NULL;
373 		}
374 
375 		return &clk_mgr->base;
376 	}
377 	break;
378 	case AMDGPU_FAMILY_GC_11_5_4: {
379 		struct clk_mgr_dcn42 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL);
380 
381 		if (clk_mgr == NULL) {
382 			BREAK_TO_DEBUGGER();
383 			return NULL;
384 		}
385 
386 		dcn42_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
387 		return &clk_mgr->base.base;
388 	}
389 	break;
390 #endif	/* CONFIG_DRM_AMD_DC_FP */
391 	default:
392 		ASSERT(0); /* Unknown Asic */
393 		break;
394 	}
395 
396 	return NULL;
397 }
398 
399 void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base)
400 {
401 	struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
402 
403 #ifdef CONFIG_DRM_AMD_DC_FP
404 	switch (clk_mgr_base->ctx->asic_id.chip_family) {
405 	case FAMILY_NV:
406 		if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
407 			dcn3_clk_mgr_destroy(clk_mgr);
408 		} else if (ASICREV_IS_DIMGREY_CAVEFISH_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
409 			dcn3_clk_mgr_destroy(clk_mgr);
410 		}
411 		if (ASICREV_IS_BEIGE_GOBY_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) {
412 			dcn3_clk_mgr_destroy(clk_mgr);
413 		}
414 		break;
415 
416 	case FAMILY_VGH:
417 		if (ASICREV_IS_VANGOGH(clk_mgr_base->ctx->asic_id.hw_internal_rev))
418 			vg_clk_mgr_destroy(clk_mgr);
419 		break;
420 
421 	case FAMILY_YELLOW_CARP:
422 		dcn31_clk_mgr_destroy(clk_mgr);
423 		break;
424 
425 	case AMDGPU_FAMILY_GC_10_3_6:
426 		dcn315_clk_mgr_destroy(clk_mgr);
427 		break;
428 
429 	case AMDGPU_FAMILY_GC_10_3_7:
430 		dcn316_clk_mgr_destroy(clk_mgr);
431 		break;
432 
433 	case AMDGPU_FAMILY_GC_11_0_0:
434 		dcn32_clk_mgr_destroy(clk_mgr);
435 		break;
436 
437 	case AMDGPU_FAMILY_GC_11_0_1:
438 		dcn314_clk_mgr_destroy(clk_mgr);
439 		break;
440 
441 	case AMDGPU_FAMILY_GC_11_5_0:
442 		if (clk_mgr_base->ctx->dce_version == DCN_VERSION_4_2B) {
443 			dcn42_clk_mgr_destroy(clk_mgr);
444 			break;
445 		}
446 		dcn35_clk_mgr_destroy(clk_mgr);
447 		break;
448 	case AMDGPU_FAMILY_GC_12_0_0:
449 		dcn401_clk_mgr_destroy(clk_mgr);
450 		break;
451 	case AMDGPU_FAMILY_GC_11_5_4:
452 		dcn42_clk_mgr_destroy(clk_mgr);
453 		break;
454 
455 	default:
456 		break;
457 	}
458 #endif /* CONFIG_DRM_AMD_DC_FP */
459 
460 	kfree(clk_mgr);
461 }
462 
463