1 /*
2  * Copyright 2015 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 #include <linux/slab.h>
26 #include <linux/mm.h>
27 
28 #include "dm_services.h"
29 
30 #include "dc.h"
31 
32 #include "core_status.h"
33 #include "core_types.h"
34 #include "hw_sequencer.h"
35 #include "dce/dce_hwseq.h"
36 
37 #include "resource.h"
38 
39 #include "clk_mgr.h"
40 #include "clock_source.h"
41 #include "dc_bios_types.h"
42 
43 #include "bios_parser_interface.h"
44 #include "include/irq_service_interface.h"
45 #include "transform.h"
46 #include "dmcu.h"
47 #include "dpp.h"
48 #include "timing_generator.h"
49 #include "abm.h"
50 #include "virtual/virtual_link_encoder.h"
51 
52 #include "link_hwss.h"
53 #include "link_encoder.h"
54 
55 #include "dc_link_ddc.h"
56 #include "dm_helpers.h"
57 #include "mem_input.h"
58 #include "hubp.h"
59 
60 #include "dc_link_dp.h"
61 
62 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
63 #include "dsc.h"
64 #endif
65 
66 #ifdef CONFIG_DRM_AMD_DC_DCN2_0
67 #include "vm_helper.h"
68 #endif
69 
70 #include "dce/dce_i2c.h"
71 
72 #define DC_LOGGER \
73 	dc->ctx->logger
74 
75 const static char DC_BUILD_ID[] = "production-build";
76 
77 /**
78  * DOC: Overview
79  *
80  * DC is the OS-agnostic component of the amdgpu DC driver.
81  *
82  * DC maintains and validates a set of structs representing the state of the
83  * driver and writes that state to AMD hardware
84  *
85  * Main DC HW structs:
86  *
87  * struct dc - The central struct.  One per driver.  Created on driver load,
88  * destroyed on driver unload.
89  *
90  * struct dc_context - One per driver.
91  * Used as a backpointer by most other structs in dc.
92  *
93  * struct dc_link - One per connector (the physical DP, HDMI, miniDP, or eDP
94  * plugpoints).  Created on driver load, destroyed on driver unload.
95  *
96  * struct dc_sink - One per display.  Created on boot or hotplug.
97  * Destroyed on shutdown or hotunplug.  A dc_link can have a local sink
98  * (the display directly attached).  It may also have one or more remote
99  * sinks (in the Multi-Stream Transport case)
100  *
101  * struct resource_pool - One per driver.  Represents the hw blocks not in the
102  * main pipeline.  Not directly accessible by dm.
103  *
104  * Main dc state structs:
105  *
106  * These structs can be created and destroyed as needed.  There is a full set of
107  * these structs in dc->current_state representing the currently programmed state.
108  *
109  * struct dc_state - The global DC state to track global state information,
110  * such as bandwidth values.
111  *
112  * struct dc_stream_state - Represents the hw configuration for the pipeline from
113  * a framebuffer to a display.  Maps one-to-one with dc_sink.
114  *
115  * struct dc_plane_state - Represents a framebuffer.  Each stream has at least one,
116  * and may have more in the Multi-Plane Overlay case.
117  *
118  * struct resource_context - Represents the programmable state of everything in
119  * the resource_pool.  Not directly accessible by dm.
120  *
121  * struct pipe_ctx - A member of struct resource_context.  Represents the
122  * internal hardware pipeline components.  Each dc_plane_state has either
123  * one or two (in the pipe-split case).
124  */
125 
126 /*******************************************************************************
127  * Private functions
128  ******************************************************************************/
129 
elevate_update_type(enum surface_update_type * original,enum surface_update_type new)130 static inline void elevate_update_type(enum surface_update_type *original, enum surface_update_type new)
131 {
132 	if (new > *original)
133 		*original = new;
134 }
135 
destroy_links(struct dc * dc)136 static void destroy_links(struct dc *dc)
137 {
138 	uint32_t i;
139 
140 	for (i = 0; i < dc->link_count; i++) {
141 		if (NULL != dc->links[i])
142 			link_destroy(&dc->links[i]);
143 	}
144 }
145 
create_links(struct dc * dc,uint32_t num_virtual_links)146 static bool create_links(
147 		struct dc *dc,
148 		uint32_t num_virtual_links)
149 {
150 	int i;
151 	int connectors_num;
152 	struct dc_bios *bios = dc->ctx->dc_bios;
153 
154 	dc->link_count = 0;
155 
156 	connectors_num = bios->funcs->get_connectors_number(bios);
157 
158 	if (connectors_num > ENUM_ID_COUNT) {
159 		dm_error(
160 			"DC: Number of connectors %d exceeds maximum of %d!\n",
161 			connectors_num,
162 			ENUM_ID_COUNT);
163 		return false;
164 	}
165 
166 	dm_output_to_console(
167 		"DC: %s: connectors_num: physical:%d, virtual:%d\n",
168 		__func__,
169 		connectors_num,
170 		num_virtual_links);
171 
172 	for (i = 0; i < connectors_num; i++) {
173 		struct link_init_data link_init_params = {0};
174 		struct dc_link *link;
175 
176 		link_init_params.ctx = dc->ctx;
177 		/* next BIOS object table connector */
178 		link_init_params.connector_index = i;
179 		link_init_params.link_index = dc->link_count;
180 		link_init_params.dc = dc;
181 		link = link_create(&link_init_params);
182 
183 		if (link) {
184 			bool should_destory_link = false;
185 
186 			if (link->connector_signal == SIGNAL_TYPE_EDP) {
187 				if (dc->config.edp_not_connected)
188 					should_destory_link = true;
189 				else if (dc->debug.remove_disconnect_edp) {
190 					enum dc_connection_type type;
191 					dc_link_detect_sink(link, &type);
192 					if (type == dc_connection_none)
193 						should_destory_link = true;
194 				}
195 			}
196 
197 			if (!should_destory_link) {
198 				dc->links[dc->link_count] = link;
199 				link->dc = dc;
200 				++dc->link_count;
201 			} else {
202 				link_destroy(&link);
203 			}
204 		}
205 	}
206 
207 	for (i = 0; i < num_virtual_links; i++) {
208 		struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL);
209 		struct encoder_init_data enc_init = {0};
210 
211 		if (link == NULL) {
212 			BREAK_TO_DEBUGGER();
213 			goto failed_alloc;
214 		}
215 
216 		link->link_index = dc->link_count;
217 		dc->links[dc->link_count] = link;
218 		dc->link_count++;
219 
220 		link->ctx = dc->ctx;
221 		link->dc = dc;
222 		link->connector_signal = SIGNAL_TYPE_VIRTUAL;
223 		link->link_id.type = OBJECT_TYPE_CONNECTOR;
224 		link->link_id.id = CONNECTOR_ID_VIRTUAL;
225 		link->link_id.enum_id = ENUM_ID_1;
226 		link->link_enc = kzalloc(sizeof(*link->link_enc), GFP_KERNEL);
227 
228 		if (!link->link_enc) {
229 			BREAK_TO_DEBUGGER();
230 			goto failed_alloc;
231 		}
232 
233 		link->link_status.dpcd_caps = &link->dpcd_caps;
234 
235 		enc_init.ctx = dc->ctx;
236 		enc_init.channel = CHANNEL_ID_UNKNOWN;
237 		enc_init.hpd_source = HPD_SOURCEID_UNKNOWN;
238 		enc_init.transmitter = TRANSMITTER_UNKNOWN;
239 		enc_init.connector = link->link_id;
240 		enc_init.encoder.type = OBJECT_TYPE_ENCODER;
241 		enc_init.encoder.id = ENCODER_ID_INTERNAL_VIRTUAL;
242 		enc_init.encoder.enum_id = ENUM_ID_1;
243 		virtual_link_encoder_construct(link->link_enc, &enc_init);
244 	}
245 
246 	return true;
247 
248 failed_alloc:
249 	return false;
250 }
251 
dc_perf_trace_create(void)252 static struct dc_perf_trace *dc_perf_trace_create(void)
253 {
254 	return kzalloc(sizeof(struct dc_perf_trace), GFP_KERNEL);
255 }
256 
dc_perf_trace_destroy(struct dc_perf_trace ** perf_trace)257 static void dc_perf_trace_destroy(struct dc_perf_trace **perf_trace)
258 {
259 	kfree(*perf_trace);
260 	*perf_trace = NULL;
261 }
262 
263 /**
264  *****************************************************************************
265  *  Function: dc_stream_adjust_vmin_vmax
266  *
267  *  @brief
268  *     Looks up the pipe context of dc_stream_state and updates the
269  *     vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh
270  *     Rate, which is a power-saving feature that targets reducing panel
271  *     refresh rate while the screen is static
272  *
273  *  @param [in] dc: dc reference
274  *  @param [in] stream: Initial dc stream state
275  *  @param [in] adjust: Updated parameters for vertical_total_min and
276  *  vertical_total_max
277  *****************************************************************************
278  */
dc_stream_adjust_vmin_vmax(struct dc * dc,struct dc_stream_state * stream,struct dc_crtc_timing_adjust * adjust)279 bool dc_stream_adjust_vmin_vmax(struct dc *dc,
280 		struct dc_stream_state *stream,
281 		struct dc_crtc_timing_adjust *adjust)
282 {
283 	int i = 0;
284 	bool ret = false;
285 
286 	for (i = 0; i < MAX_PIPES; i++) {
287 		struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
288 
289 		if (pipe->stream == stream && pipe->stream_res.tg) {
290 			pipe->stream->adjust = *adjust;
291 			dc->hwss.set_drr(&pipe,
292 					1,
293 					adjust->v_total_min,
294 					adjust->v_total_max,
295 					adjust->v_total_mid,
296 					adjust->v_total_mid_frame_num);
297 
298 			ret = true;
299 		}
300 	}
301 	return ret;
302 }
303 
dc_stream_get_crtc_position(struct dc * dc,struct dc_stream_state ** streams,int num_streams,unsigned int * v_pos,unsigned int * nom_v_pos)304 bool dc_stream_get_crtc_position(struct dc *dc,
305 		struct dc_stream_state **streams, int num_streams,
306 		unsigned int *v_pos, unsigned int *nom_v_pos)
307 {
308 	/* TODO: Support multiple streams */
309 	const struct dc_stream_state *stream = streams[0];
310 	int i = 0;
311 	bool ret = false;
312 	struct crtc_position position;
313 
314 	for (i = 0; i < MAX_PIPES; i++) {
315 		struct pipe_ctx *pipe =
316 				&dc->current_state->res_ctx.pipe_ctx[i];
317 
318 		if (pipe->stream == stream && pipe->stream_res.stream_enc) {
319 			dc->hwss.get_position(&pipe, 1, &position);
320 
321 			*v_pos = position.vertical_count;
322 			*nom_v_pos = position.nominal_vcount;
323 			ret = true;
324 		}
325 	}
326 	return ret;
327 }
328 
329 /**
330  * dc_stream_configure_crc() - Configure CRC capture for the given stream.
331  * @dc: DC Object
332  * @stream: The stream to configure CRC on.
333  * @enable: Enable CRC if true, disable otherwise.
334  * @continuous: Capture CRC on every frame if true. Otherwise, only capture
335  *              once.
336  *
337  * By default, only CRC0 is configured, and the entire frame is used to
338  * calculate the crc.
339  */
dc_stream_configure_crc(struct dc * dc,struct dc_stream_state * stream,bool enable,bool continuous)340 bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
341 			     bool enable, bool continuous)
342 {
343 	int i;
344 	struct pipe_ctx *pipe;
345 	struct crc_params param;
346 	struct timing_generator *tg;
347 
348 	for (i = 0; i < MAX_PIPES; i++) {
349 		pipe = &dc->current_state->res_ctx.pipe_ctx[i];
350 		if (pipe->stream == stream)
351 			break;
352 	}
353 	/* Stream not found */
354 	if (i == MAX_PIPES)
355 		return false;
356 
357 	/* Always capture the full frame */
358 	param.windowa_x_start = 0;
359 	param.windowa_y_start = 0;
360 	param.windowa_x_end = pipe->stream->timing.h_addressable;
361 	param.windowa_y_end = pipe->stream->timing.v_addressable;
362 	param.windowb_x_start = 0;
363 	param.windowb_y_start = 0;
364 	param.windowb_x_end = pipe->stream->timing.h_addressable;
365 	param.windowb_y_end = pipe->stream->timing.v_addressable;
366 
367 	/* Default to the union of both windows */
368 	param.selection = UNION_WINDOW_A_B;
369 	param.continuous_mode = continuous;
370 	param.enable = enable;
371 
372 	tg = pipe->stream_res.tg;
373 
374 	/* Only call if supported */
375 	if (tg->funcs->configure_crc)
376 		return tg->funcs->configure_crc(tg, &param);
377 	DC_LOG_WARNING("CRC capture not supported.");
378 	return false;
379 }
380 
381 /**
382  * dc_stream_get_crc() - Get CRC values for the given stream.
383  * @dc: DC object
384  * @stream: The DC stream state of the stream to get CRCs from.
385  * @r_cr, g_y, b_cb: CRC values for the three channels are stored here.
386  *
387  * dc_stream_configure_crc needs to be called beforehand to enable CRCs.
388  * Return false if stream is not found, or if CRCs are not enabled.
389  */
dc_stream_get_crc(struct dc * dc,struct dc_stream_state * stream,uint32_t * r_cr,uint32_t * g_y,uint32_t * b_cb)390 bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
391 		       uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
392 {
393 	int i;
394 	struct pipe_ctx *pipe;
395 	struct timing_generator *tg;
396 
397 	for (i = 0; i < MAX_PIPES; i++) {
398 		pipe = &dc->current_state->res_ctx.pipe_ctx[i];
399 		if (pipe->stream == stream)
400 			break;
401 	}
402 	/* Stream not found */
403 	if (i == MAX_PIPES)
404 		return false;
405 
406 	tg = pipe->stream_res.tg;
407 
408 	if (tg->funcs->get_crc)
409 		return tg->funcs->get_crc(tg, r_cr, g_y, b_cb);
410 	DC_LOG_WARNING("CRC capture not supported.");
411 	return false;
412 }
413 
dc_stream_set_dither_option(struct dc_stream_state * stream,enum dc_dither_option option)414 void dc_stream_set_dither_option(struct dc_stream_state *stream,
415 		enum dc_dither_option option)
416 {
417 	struct bit_depth_reduction_params params;
418 	struct dc_link *link = stream->link;
419 	struct pipe_ctx *pipes = NULL;
420 	int i;
421 
422 	for (i = 0; i < MAX_PIPES; i++) {
423 		if (link->dc->current_state->res_ctx.pipe_ctx[i].stream ==
424 				stream) {
425 			pipes = &link->dc->current_state->res_ctx.pipe_ctx[i];
426 			break;
427 		}
428 	}
429 
430 	if (!pipes)
431 		return;
432 	if (option > DITHER_OPTION_MAX)
433 		return;
434 
435 	stream->dither_option = option;
436 
437 	memset(&params, 0, sizeof(params));
438 	resource_build_bit_depth_reduction_params(stream, &params);
439 	stream->bit_depth_params = params;
440 
441 	if (pipes->plane_res.xfm &&
442 	    pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth) {
443 		pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
444 			pipes->plane_res.xfm,
445 			pipes->plane_res.scl_data.lb_params.depth,
446 			&stream->bit_depth_params);
447 	}
448 
449 	pipes->stream_res.opp->funcs->
450 		opp_program_bit_depth_reduction(pipes->stream_res.opp, &params);
451 }
452 
dc_stream_set_gamut_remap(struct dc * dc,const struct dc_stream_state * stream)453 bool dc_stream_set_gamut_remap(struct dc *dc, const struct dc_stream_state *stream)
454 {
455 	int i = 0;
456 	bool ret = false;
457 	struct pipe_ctx *pipes;
458 
459 	for (i = 0; i < MAX_PIPES; i++) {
460 		if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
461 			pipes = &dc->current_state->res_ctx.pipe_ctx[i];
462 			dc->hwss.program_gamut_remap(pipes);
463 			ret = true;
464 		}
465 	}
466 
467 	return ret;
468 }
469 
dc_stream_program_csc_matrix(struct dc * dc,struct dc_stream_state * stream)470 bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream)
471 {
472 	int i = 0;
473 	bool ret = false;
474 	struct pipe_ctx *pipes;
475 
476 	for (i = 0; i < MAX_PIPES; i++) {
477 		if (dc->current_state->res_ctx.pipe_ctx[i].stream
478 				== stream) {
479 
480 			pipes = &dc->current_state->res_ctx.pipe_ctx[i];
481 			dc->hwss.program_output_csc(dc,
482 					pipes,
483 					stream->output_color_space,
484 					stream->csc_color_matrix.matrix,
485 					pipes->stream_res.opp->inst);
486 			ret = true;
487 		}
488 	}
489 
490 	return ret;
491 }
492 
dc_stream_set_static_screen_events(struct dc * dc,struct dc_stream_state ** streams,int num_streams,const struct dc_static_screen_events * events)493 void dc_stream_set_static_screen_events(struct dc *dc,
494 		struct dc_stream_state **streams,
495 		int num_streams,
496 		const struct dc_static_screen_events *events)
497 {
498 	int i = 0;
499 	int j = 0;
500 	struct pipe_ctx *pipes_affected[MAX_PIPES];
501 	int num_pipes_affected = 0;
502 
503 	for (i = 0; i < num_streams; i++) {
504 		struct dc_stream_state *stream = streams[i];
505 
506 		for (j = 0; j < MAX_PIPES; j++) {
507 			if (dc->current_state->res_ctx.pipe_ctx[j].stream
508 					== stream) {
509 				pipes_affected[num_pipes_affected++] =
510 						&dc->current_state->res_ctx.pipe_ctx[j];
511 			}
512 		}
513 	}
514 
515 	dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, events);
516 }
517 
destruct(struct dc * dc)518 static void destruct(struct dc *dc)
519 {
520 	if (dc->current_state) {
521 		dc_release_state(dc->current_state);
522 		dc->current_state = NULL;
523 	}
524 
525 	destroy_links(dc);
526 
527 	if (dc->clk_mgr) {
528 		dc_destroy_clk_mgr(dc->clk_mgr);
529 		dc->clk_mgr = NULL;
530 	}
531 
532 	dc_destroy_resource_pool(dc);
533 
534 	if (dc->ctx->gpio_service)
535 		dal_gpio_service_destroy(&dc->ctx->gpio_service);
536 
537 	if (dc->ctx->created_bios)
538 		dal_bios_parser_destroy(&dc->ctx->dc_bios);
539 
540 	dc_perf_trace_destroy(&dc->ctx->perf_trace);
541 
542 	kfree(dc->ctx);
543 	dc->ctx = NULL;
544 
545 	kfree(dc->bw_vbios);
546 	dc->bw_vbios = NULL;
547 
548 	kfree(dc->bw_dceip);
549 	dc->bw_dceip = NULL;
550 
551 #ifdef CONFIG_DRM_AMD_DC_DCN1_0
552 	kfree(dc->dcn_soc);
553 	dc->dcn_soc = NULL;
554 
555 	kfree(dc->dcn_ip);
556 	dc->dcn_ip = NULL;
557 
558 #endif
559 #ifdef CONFIG_DRM_AMD_DC_DCN2_0
560 	kfree(dc->vm_helper);
561 	dc->vm_helper = NULL;
562 
563 #endif
564 }
565 
construct(struct dc * dc,const struct dc_init_data * init_params)566 static bool construct(struct dc *dc,
567 		const struct dc_init_data *init_params)
568 {
569 	struct dc_context *dc_ctx;
570 	struct bw_calcs_dceip *dc_dceip;
571 	struct bw_calcs_vbios *dc_vbios;
572 #ifdef CONFIG_DRM_AMD_DC_DCN1_0
573 	struct dcn_soc_bounding_box *dcn_soc;
574 	struct dcn_ip_params *dcn_ip;
575 #endif
576 
577 	enum dce_version dc_version = DCE_VERSION_UNKNOWN;
578 	dc->config = init_params->flags;
579 
580 #ifdef CONFIG_DRM_AMD_DC_DCN2_0
581 	// Allocate memory for the vm_helper
582 	dc->vm_helper = kzalloc(sizeof(struct vm_helper), GFP_KERNEL);
583 	if (!dc->vm_helper) {
584 		dm_error("%s: failed to create dc->vm_helper\n", __func__);
585 		goto fail;
586 	}
587 
588 #endif
589 	memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides));
590 
591 	dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL);
592 	if (!dc_dceip) {
593 		dm_error("%s: failed to create dceip\n", __func__);
594 		goto fail;
595 	}
596 
597 	dc->bw_dceip = dc_dceip;
598 
599 	dc_vbios = kzalloc(sizeof(*dc_vbios), GFP_KERNEL);
600 	if (!dc_vbios) {
601 		dm_error("%s: failed to create vbios\n", __func__);
602 		goto fail;
603 	}
604 
605 	dc->bw_vbios = dc_vbios;
606 #ifdef CONFIG_DRM_AMD_DC_DCN1_0
607 	dcn_soc = kzalloc(sizeof(*dcn_soc), GFP_KERNEL);
608 	if (!dcn_soc) {
609 		dm_error("%s: failed to create dcn_soc\n", __func__);
610 		goto fail;
611 	}
612 
613 	dc->dcn_soc = dcn_soc;
614 
615 	dcn_ip = kzalloc(sizeof(*dcn_ip), GFP_KERNEL);
616 	if (!dcn_ip) {
617 		dm_error("%s: failed to create dcn_ip\n", __func__);
618 		goto fail;
619 	}
620 
621 	dc->dcn_ip = dcn_ip;
622 #ifdef CONFIG_DRM_AMD_DC_DCN2_0
623 	dc->soc_bounding_box = init_params->soc_bounding_box;
624 #endif
625 #endif
626 
627 	dc_ctx = kzalloc(sizeof(*dc_ctx), GFP_KERNEL);
628 	if (!dc_ctx) {
629 		dm_error("%s: failed to create ctx\n", __func__);
630 		goto fail;
631 	}
632 
633 	dc_ctx->cgs_device = init_params->cgs_device;
634 	dc_ctx->driver_context = init_params->driver;
635 	dc_ctx->dc = dc;
636 	dc_ctx->asic_id = init_params->asic_id;
637 	dc_ctx->dc_sink_id_count = 0;
638 	dc_ctx->dc_stream_id_count = 0;
639 	dc->ctx = dc_ctx;
640 
641 	/* Create logger */
642 
643 	dc_ctx->dce_environment = init_params->dce_environment;
644 
645 	dc_version = resource_parse_asic_id(init_params->asic_id);
646 	dc_ctx->dce_version = dc_version;
647 
648 	/* Resource should construct all asic specific resources.
649 	 * This should be the only place where we need to parse the asic id
650 	 */
651 	if (init_params->vbios_override)
652 		dc_ctx->dc_bios = init_params->vbios_override;
653 	else {
654 		/* Create BIOS parser */
655 		struct bp_init_data bp_init_data;
656 
657 		bp_init_data.ctx = dc_ctx;
658 		bp_init_data.bios = init_params->asic_id.atombios_base_address;
659 
660 		dc_ctx->dc_bios = dal_bios_parser_create(
661 				&bp_init_data, dc_version);
662 
663 		if (!dc_ctx->dc_bios) {
664 			ASSERT_CRITICAL(false);
665 			goto fail;
666 		}
667 
668 		dc_ctx->created_bios = true;
669 		}
670 
671 	dc_ctx->perf_trace = dc_perf_trace_create();
672 	if (!dc_ctx->perf_trace) {
673 		ASSERT_CRITICAL(false);
674 		goto fail;
675 	}
676 
677 	/* Create GPIO service */
678 	dc_ctx->gpio_service = dal_gpio_service_create(
679 			dc_version,
680 			dc_ctx->dce_environment,
681 			dc_ctx);
682 
683 	if (!dc_ctx->gpio_service) {
684 		ASSERT_CRITICAL(false);
685 		goto fail;
686 	}
687 
688 	dc->res_pool = dc_create_resource_pool(dc, init_params, dc_version);
689 	if (!dc->res_pool)
690 		goto fail;
691 
692 	dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg);
693 	if (!dc->clk_mgr)
694 		goto fail;
695 
696 #ifdef CONFIG_DRM_AMD_DC_DCN2_1
697 	if (dc->res_pool->funcs->update_bw_bounding_box)
698 		dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params);
699 #endif
700 
701 	/* Creation of current_state must occur after dc->dml
702 	 * is initialized in dc_create_resource_pool because
703 	 * on creation it copies the contents of dc->dml
704 	 */
705 
706 	dc->current_state = dc_create_state(dc);
707 
708 	if (!dc->current_state) {
709 		dm_error("%s: failed to create validate ctx\n", __func__);
710 		goto fail;
711 	}
712 
713 	dc_resource_state_construct(dc, dc->current_state);
714 
715 	if (!create_links(dc, init_params->num_virtual_links))
716 		goto fail;
717 
718 	return true;
719 
720 fail:
721 
722 	destruct(dc);
723 	return false;
724 }
725 
726 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
disable_all_writeback_pipes_for_stream(const struct dc * dc,struct dc_stream_state * stream,struct dc_state * context)727 static bool disable_all_writeback_pipes_for_stream(
728 		const struct dc *dc,
729 		struct dc_stream_state *stream,
730 		struct dc_state *context)
731 {
732 	int i;
733 
734 	for (i = 0; i < stream->num_wb_info; i++)
735 		stream->writeback_info[i].wb_enabled = false;
736 
737 	return true;
738 }
739 #endif
740 
disable_dangling_plane(struct dc * dc,struct dc_state * context)741 static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
742 {
743 	int i, j;
744 	struct dc_state *dangling_context = dc_create_state(dc);
745 	struct dc_state *current_ctx;
746 
747 	if (dangling_context == NULL)
748 		return;
749 
750 	dc_resource_state_copy_construct(dc->current_state, dangling_context);
751 
752 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
753 		struct dc_stream_state *old_stream =
754 				dc->current_state->res_ctx.pipe_ctx[i].stream;
755 		bool should_disable = true;
756 
757 		for (j = 0; j < context->stream_count; j++) {
758 			if (old_stream == context->streams[j]) {
759 				should_disable = false;
760 				break;
761 			}
762 		}
763 		if (should_disable && old_stream) {
764 			dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
765 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
766 			disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
767 #endif
768 			dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context);
769 		}
770 	}
771 
772 	current_ctx = dc->current_state;
773 	dc->current_state = dangling_context;
774 	dc_release_state(current_ctx);
775 }
776 
777 /*******************************************************************************
778  * Public functions
779  ******************************************************************************/
780 
dc_create(const struct dc_init_data * init_params)781 struct dc *dc_create(const struct dc_init_data *init_params)
782 {
783 	struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
784 	unsigned int full_pipe_count;
785 
786 	if (NULL == dc)
787 		goto alloc_fail;
788 
789 	if (false == construct(dc, init_params))
790 		goto construct_fail;
791 
792 	/*TODO: separate HW and SW initialization*/
793 	dc->hwss.init_hw(dc);
794 
795 	full_pipe_count = dc->res_pool->pipe_count;
796 	if (dc->res_pool->underlay_pipe_index != NO_UNDERLAY_PIPE)
797 		full_pipe_count--;
798 	dc->caps.max_streams = min(
799 			full_pipe_count,
800 			dc->res_pool->stream_enc_count);
801 
802 	dc->caps.max_links = dc->link_count;
803 	dc->caps.max_audios = dc->res_pool->audio_count;
804 	dc->caps.linear_pitch_alignment = 64;
805 
806 	/* Populate versioning information */
807 	dc->versions.dc_ver = DC_VER;
808 
809 	if (dc->res_pool->dmcu != NULL)
810 		dc->versions.dmcu_version = dc->res_pool->dmcu->dmcu_version;
811 
812 	dc->build_id = DC_BUILD_ID;
813 
814 	DC_LOG_DC("Display Core initialized\n");
815 
816 
817 
818 	return dc;
819 
820 construct_fail:
821 	kfree(dc);
822 
823 alloc_fail:
824 	return NULL;
825 }
826 
dc_init_callbacks(struct dc * dc,const struct dc_callback_init * init_params)827 void dc_init_callbacks(struct dc *dc,
828 		const struct dc_callback_init *init_params)
829 {
830 }
831 
dc_destroy(struct dc ** dc)832 void dc_destroy(struct dc **dc)
833 {
834 	destruct(*dc);
835 	kfree(*dc);
836 	*dc = NULL;
837 }
838 
enable_timing_multisync(struct dc * dc,struct dc_state * ctx)839 static void enable_timing_multisync(
840 		struct dc *dc,
841 		struct dc_state *ctx)
842 {
843 	int i = 0, multisync_count = 0;
844 	int pipe_count = dc->res_pool->pipe_count;
845 	struct pipe_ctx *multisync_pipes[MAX_PIPES] = { NULL };
846 
847 	for (i = 0; i < pipe_count; i++) {
848 		if (!ctx->res_ctx.pipe_ctx[i].stream ||
849 				!ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.enabled)
850 			continue;
851 		if (ctx->res_ctx.pipe_ctx[i].stream == ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.event_source)
852 			continue;
853 		multisync_pipes[multisync_count] = &ctx->res_ctx.pipe_ctx[i];
854 		multisync_count++;
855 	}
856 
857 	if (multisync_count > 0) {
858 		dc->hwss.enable_per_frame_crtc_position_reset(
859 			dc, multisync_count, multisync_pipes);
860 	}
861 }
862 
program_timing_sync(struct dc * dc,struct dc_state * ctx)863 static void program_timing_sync(
864 		struct dc *dc,
865 		struct dc_state *ctx)
866 {
867 	int i, j, k;
868 	int group_index = 0;
869 	int num_group = 0;
870 	int pipe_count = dc->res_pool->pipe_count;
871 	struct pipe_ctx *unsynced_pipes[MAX_PIPES] = { NULL };
872 
873 	for (i = 0; i < pipe_count; i++) {
874 		if (!ctx->res_ctx.pipe_ctx[i].stream || ctx->res_ctx.pipe_ctx[i].top_pipe)
875 			continue;
876 
877 		unsynced_pipes[i] = &ctx->res_ctx.pipe_ctx[i];
878 	}
879 
880 	for (i = 0; i < pipe_count; i++) {
881 		int group_size = 1;
882 		struct pipe_ctx *pipe_set[MAX_PIPES];
883 
884 		if (!unsynced_pipes[i])
885 			continue;
886 
887 		pipe_set[0] = unsynced_pipes[i];
888 		unsynced_pipes[i] = NULL;
889 
890 		/* Add tg to the set, search rest of the tg's for ones with
891 		 * same timing, add all tgs with same timing to the group
892 		 */
893 		for (j = i + 1; j < pipe_count; j++) {
894 			if (!unsynced_pipes[j])
895 				continue;
896 
897 			if (resource_are_streams_timing_synchronizable(
898 					unsynced_pipes[j]->stream,
899 					pipe_set[0]->stream)) {
900 				pipe_set[group_size] = unsynced_pipes[j];
901 				unsynced_pipes[j] = NULL;
902 				group_size++;
903 			}
904 		}
905 
906 		/* set first pipe with plane as master */
907 		for (j = 0; j < group_size; j++) {
908 			struct pipe_ctx *temp;
909 
910 			if (pipe_set[j]->plane_state) {
911 				if (j == 0)
912 					break;
913 
914 				temp = pipe_set[0];
915 				pipe_set[0] = pipe_set[j];
916 				pipe_set[j] = temp;
917 				break;
918 			}
919 		}
920 
921 
922 		for (k = 0; k < group_size; k++) {
923 			struct dc_stream_status *status = dc_stream_get_status_from_state(ctx, pipe_set[k]->stream);
924 
925 			status->timing_sync_info.group_id = num_group;
926 			status->timing_sync_info.group_size = group_size;
927 			if (k == 0)
928 				status->timing_sync_info.master = true;
929 			else
930 				status->timing_sync_info.master = false;
931 
932 		}
933 		/* remove any other pipes with plane as they have already been synced */
934 		for (j = j + 1; j < group_size; j++) {
935 			if (pipe_set[j]->plane_state) {
936 				group_size--;
937 				pipe_set[j] = pipe_set[group_size];
938 				j--;
939 			}
940 		}
941 
942 		if (group_size > 1) {
943 			dc->hwss.enable_timing_synchronization(
944 				dc, group_index, group_size, pipe_set);
945 			group_index++;
946 		}
947 		num_group++;
948 	}
949 }
950 
context_changed(struct dc * dc,struct dc_state * context)951 static bool context_changed(
952 		struct dc *dc,
953 		struct dc_state *context)
954 {
955 	uint8_t i;
956 
957 	if (context->stream_count != dc->current_state->stream_count)
958 		return true;
959 
960 	for (i = 0; i < dc->current_state->stream_count; i++) {
961 		if (dc->current_state->streams[i] != context->streams[i])
962 			return true;
963 	}
964 
965 	return false;
966 }
967 
dc_validate_seamless_boot_timing(const struct dc * dc,const struct dc_sink * sink,struct dc_crtc_timing * crtc_timing)968 bool dc_validate_seamless_boot_timing(const struct dc *dc,
969 				const struct dc_sink *sink,
970 				struct dc_crtc_timing *crtc_timing)
971 {
972 	struct timing_generator *tg;
973 	struct dc_link *link = sink->link;
974 	unsigned int enc_inst, tg_inst;
975 
976 	/* Check for enabled DIG to identify enabled display */
977 	if (!link->link_enc->funcs->is_dig_enabled(link->link_enc))
978 		return false;
979 
980 	/* Check for which front end is used by this encoder.
981 	 * Note the inst is 1 indexed, where 0 is undefined.
982 	 * Note that DIG_FE can source from different OTG but our
983 	 * current implementation always map 1-to-1, so this code makes
984 	 * the same assumption and doesn't check OTG source.
985 	 */
986 	enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc);
987 
988 	/* Instance should be within the range of the pool */
989 	if (enc_inst >= dc->res_pool->pipe_count)
990 		return false;
991 
992 	if (enc_inst >= dc->res_pool->stream_enc_count)
993 		return false;
994 
995 	tg_inst = dc->res_pool->stream_enc[enc_inst]->funcs->dig_source_otg(
996 		dc->res_pool->stream_enc[enc_inst]);
997 
998 	if (tg_inst >= dc->res_pool->timing_generator_count)
999 		return false;
1000 
1001 	tg = dc->res_pool->timing_generators[tg_inst];
1002 
1003 	if (!tg->funcs->is_matching_timing)
1004 		return false;
1005 
1006 	if (!tg->funcs->is_matching_timing(tg, crtc_timing))
1007 		return false;
1008 
1009 	if (dc_is_dp_signal(link->connector_signal)) {
1010 		unsigned int pix_clk_100hz;
1011 
1012 		dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
1013 			dc->res_pool->dp_clock_source,
1014 			tg_inst, &pix_clk_100hz);
1015 
1016 		if (crtc_timing->pix_clk_100hz != pix_clk_100hz)
1017 			return false;
1018 
1019 	}
1020 
1021 	return true;
1022 }
1023 
dc_enable_stereo(struct dc * dc,struct dc_state * context,struct dc_stream_state * streams[],uint8_t stream_count)1024 bool dc_enable_stereo(
1025 	struct dc *dc,
1026 	struct dc_state *context,
1027 	struct dc_stream_state *streams[],
1028 	uint8_t stream_count)
1029 {
1030 	bool ret = true;
1031 	int i, j;
1032 	struct pipe_ctx *pipe;
1033 
1034 	for (i = 0; i < MAX_PIPES; i++) {
1035 		if (context != NULL)
1036 			pipe = &context->res_ctx.pipe_ctx[i];
1037 		else
1038 			pipe = &dc->current_state->res_ctx.pipe_ctx[i];
1039 		for (j = 0 ; pipe && j < stream_count; j++)  {
1040 			if (streams[j] && streams[j] == pipe->stream &&
1041 				dc->hwss.setup_stereo)
1042 				dc->hwss.setup_stereo(pipe, dc);
1043 		}
1044 	}
1045 
1046 	return ret;
1047 }
1048 
1049 /*
1050  * Applies given context to HW and copy it into current context.
1051  * It's up to the user to release the src context afterwards.
1052  */
dc_commit_state_no_check(struct dc * dc,struct dc_state * context)1053 static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
1054 {
1055 	struct dc_bios *dcb = dc->ctx->dc_bios;
1056 	enum dc_status result = DC_ERROR_UNEXPECTED;
1057 	struct pipe_ctx *pipe;
1058 	int i, k, l;
1059 	struct dc_stream_state *dc_streams[MAX_STREAMS] = {0};
1060 
1061 	disable_dangling_plane(dc, context);
1062 
1063 	for (i = 0; i < context->stream_count; i++)
1064 		dc_streams[i] =  context->streams[i];
1065 
1066 	if (!dcb->funcs->is_accelerated_mode(dcb))
1067 		dc->hwss.enable_accelerated_mode(dc, context);
1068 
1069 	for (i = 0; i < context->stream_count; i++) {
1070 		if (context->streams[i]->apply_seamless_boot_optimization)
1071 			dc->optimize_seamless_boot = true;
1072 	}
1073 
1074 	if (!dc->optimize_seamless_boot)
1075 		dc->hwss.prepare_bandwidth(dc, context);
1076 
1077 	/* re-program planes for existing stream, in case we need to
1078 	 * free up plane resource for later use
1079 	 */
1080 	for (i = 0; i < context->stream_count; i++) {
1081 		if (context->streams[i]->mode_changed)
1082 			continue;
1083 
1084 		dc->hwss.apply_ctx_for_surface(
1085 			dc, context->streams[i],
1086 			context->stream_status[i].plane_count,
1087 			context); /* use new pipe config in new context */
1088 	}
1089 
1090 	/* Program hardware */
1091 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
1092 		pipe = &context->res_ctx.pipe_ctx[i];
1093 		dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
1094 	}
1095 
1096 	result = dc->hwss.apply_ctx_to_hw(dc, context);
1097 
1098 	if (result != DC_OK)
1099 		return result;
1100 
1101 	if (context->stream_count > 1 && !dc->debug.disable_timing_sync) {
1102 		enable_timing_multisync(dc, context);
1103 		program_timing_sync(dc, context);
1104 	}
1105 
1106 	/* Program all planes within new context*/
1107 	for (i = 0; i < context->stream_count; i++) {
1108 		const struct dc_link *link = context->streams[i]->link;
1109 
1110 		if (!context->streams[i]->mode_changed)
1111 			continue;
1112 
1113 		dc->hwss.apply_ctx_for_surface(
1114 				dc, context->streams[i],
1115 				context->stream_status[i].plane_count,
1116 				context);
1117 
1118 		/*
1119 		 * enable stereo
1120 		 * TODO rework dc_enable_stereo call to work with validation sets?
1121 		 */
1122 		for (k = 0; k < MAX_PIPES; k++) {
1123 			pipe = &context->res_ctx.pipe_ctx[k];
1124 
1125 			for (l = 0 ; pipe && l < context->stream_count; l++)  {
1126 				if (context->streams[l] &&
1127 					context->streams[l] == pipe->stream &&
1128 					dc->hwss.setup_stereo)
1129 					dc->hwss.setup_stereo(pipe, dc);
1130 			}
1131 		}
1132 
1133 		CONN_MSG_MODE(link, "{%dx%d, %dx%d@%dKhz}",
1134 				context->streams[i]->timing.h_addressable,
1135 				context->streams[i]->timing.v_addressable,
1136 				context->streams[i]->timing.h_total,
1137 				context->streams[i]->timing.v_total,
1138 				context->streams[i]->timing.pix_clk_100hz / 10);
1139 	}
1140 
1141 	dc_enable_stereo(dc, context, dc_streams, context->stream_count);
1142 
1143 	if (!dc->optimize_seamless_boot)
1144 		/* pplib is notified if disp_num changed */
1145 		dc->hwss.optimize_bandwidth(dc, context);
1146 
1147 	for (i = 0; i < context->stream_count; i++)
1148 		context->streams[i]->mode_changed = false;
1149 
1150 	memset(&context->commit_hints, 0, sizeof(context->commit_hints));
1151 
1152 	dc_release_state(dc->current_state);
1153 
1154 	dc->current_state = context;
1155 
1156 	dc_retain_state(dc->current_state);
1157 
1158 	return result;
1159 }
1160 
dc_commit_state(struct dc * dc,struct dc_state * context)1161 bool dc_commit_state(struct dc *dc, struct dc_state *context)
1162 {
1163 	enum dc_status result = DC_ERROR_UNEXPECTED;
1164 	int i;
1165 
1166 	if (false == context_changed(dc, context))
1167 		return DC_OK;
1168 
1169 	DC_LOG_DC("%s: %d streams\n",
1170 				__func__, context->stream_count);
1171 
1172 	for (i = 0; i < context->stream_count; i++) {
1173 		struct dc_stream_state *stream = context->streams[i];
1174 
1175 		dc_stream_log(dc, stream);
1176 	}
1177 
1178 	result = dc_commit_state_no_check(dc, context);
1179 
1180 	return (result == DC_OK);
1181 }
1182 
dc_post_update_surfaces_to_stream(struct dc * dc)1183 bool dc_post_update_surfaces_to_stream(struct dc *dc)
1184 {
1185 	int i;
1186 	struct dc_state *context = dc->current_state;
1187 
1188 	if (!dc->optimized_required || dc->optimize_seamless_boot)
1189 		return true;
1190 
1191 	post_surface_trace(dc);
1192 
1193 	for (i = 0; i < dc->res_pool->pipe_count; i++)
1194 		if (context->res_ctx.pipe_ctx[i].stream == NULL ||
1195 		    context->res_ctx.pipe_ctx[i].plane_state == NULL) {
1196 			context->res_ctx.pipe_ctx[i].pipe_idx = i;
1197 			dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]);
1198 		}
1199 
1200 	dc->optimized_required = false;
1201 
1202 	dc->hwss.optimize_bandwidth(dc, context);
1203 	return true;
1204 }
1205 
dc_create_state(struct dc * dc)1206 struct dc_state *dc_create_state(struct dc *dc)
1207 {
1208 	struct dc_state *context = kvzalloc(sizeof(struct dc_state),
1209 					    GFP_KERNEL);
1210 
1211 	if (!context)
1212 		return NULL;
1213 	/* Each context must have their own instance of VBA and in order to
1214 	 * initialize and obtain IP and SOC the base DML instance from DC is
1215 	 * initially copied into every context
1216 	 */
1217 #ifdef CONFIG_DRM_AMD_DC_DCN1_0
1218 	memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib));
1219 #endif
1220 
1221 	kref_init(&context->refcount);
1222 
1223 	return context;
1224 }
1225 
dc_copy_state(struct dc_state * src_ctx)1226 struct dc_state *dc_copy_state(struct dc_state *src_ctx)
1227 {
1228 	int i, j;
1229 	struct dc_state *new_ctx = kvmalloc(sizeof(struct dc_state), GFP_KERNEL);
1230 
1231 	if (!new_ctx)
1232 		return NULL;
1233 	memcpy(new_ctx, src_ctx, sizeof(struct dc_state));
1234 
1235 	for (i = 0; i < MAX_PIPES; i++) {
1236 			struct pipe_ctx *cur_pipe = &new_ctx->res_ctx.pipe_ctx[i];
1237 
1238 			if (cur_pipe->top_pipe)
1239 				cur_pipe->top_pipe =  &new_ctx->res_ctx.pipe_ctx[cur_pipe->top_pipe->pipe_idx];
1240 
1241 			if (cur_pipe->bottom_pipe)
1242 				cur_pipe->bottom_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->bottom_pipe->pipe_idx];
1243 
1244 			if (cur_pipe->prev_odm_pipe)
1245 				cur_pipe->prev_odm_pipe =  &new_ctx->res_ctx.pipe_ctx[cur_pipe->prev_odm_pipe->pipe_idx];
1246 
1247 			if (cur_pipe->next_odm_pipe)
1248 				cur_pipe->next_odm_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->next_odm_pipe->pipe_idx];
1249 
1250 	}
1251 
1252 	for (i = 0; i < new_ctx->stream_count; i++) {
1253 			dc_stream_retain(new_ctx->streams[i]);
1254 			for (j = 0; j < new_ctx->stream_status[i].plane_count; j++)
1255 				dc_plane_state_retain(
1256 					new_ctx->stream_status[i].plane_states[j]);
1257 	}
1258 
1259 	kref_init(&new_ctx->refcount);
1260 
1261 	return new_ctx;
1262 }
1263 
dc_retain_state(struct dc_state * context)1264 void dc_retain_state(struct dc_state *context)
1265 {
1266 	kref_get(&context->refcount);
1267 }
1268 
dc_state_free(struct kref * kref)1269 static void dc_state_free(struct kref *kref)
1270 {
1271 	struct dc_state *context = container_of(kref, struct dc_state, refcount);
1272 	dc_resource_state_destruct(context);
1273 	kvfree(context);
1274 }
1275 
dc_release_state(struct dc_state * context)1276 void dc_release_state(struct dc_state *context)
1277 {
1278 	kref_put(&context->refcount, dc_state_free);
1279 }
1280 
dc_set_generic_gpio_for_stereo(bool enable,struct gpio_service * gpio_service)1281 bool dc_set_generic_gpio_for_stereo(bool enable,
1282 		struct gpio_service *gpio_service)
1283 {
1284 	enum gpio_result gpio_result = GPIO_RESULT_NON_SPECIFIC_ERROR;
1285 	struct gpio_pin_info pin_info;
1286 	struct gpio *generic;
1287 	struct gpio_generic_mux_config *config = kzalloc(sizeof(struct gpio_generic_mux_config),
1288 			   GFP_KERNEL);
1289 
1290 	if (!config)
1291 		return false;
1292 	pin_info = dal_gpio_get_generic_pin_info(gpio_service, GPIO_ID_GENERIC, 0);
1293 
1294 	if (pin_info.mask == 0xFFFFFFFF || pin_info.offset == 0xFFFFFFFF) {
1295 		kfree(config);
1296 		return false;
1297 	} else {
1298 		generic = dal_gpio_service_create_generic_mux(
1299 			gpio_service,
1300 			pin_info.offset,
1301 			pin_info.mask);
1302 	}
1303 
1304 	if (!generic) {
1305 		kfree(config);
1306 		return false;
1307 	}
1308 
1309 	gpio_result = dal_gpio_open(generic, GPIO_MODE_OUTPUT);
1310 
1311 	config->enable_output_from_mux = enable;
1312 	config->mux_select = GPIO_SIGNAL_SOURCE_PASS_THROUGH_STEREO_SYNC;
1313 
1314 	if (gpio_result == GPIO_RESULT_OK)
1315 		gpio_result = dal_mux_setup_config(generic, config);
1316 
1317 	if (gpio_result == GPIO_RESULT_OK) {
1318 		dal_gpio_close(generic);
1319 		dal_gpio_destroy_generic_mux(&generic);
1320 		kfree(config);
1321 		return true;
1322 	} else {
1323 		dal_gpio_close(generic);
1324 		dal_gpio_destroy_generic_mux(&generic);
1325 		kfree(config);
1326 		return false;
1327 	}
1328 }
1329 
is_surface_in_context(const struct dc_state * context,const struct dc_plane_state * plane_state)1330 static bool is_surface_in_context(
1331 		const struct dc_state *context,
1332 		const struct dc_plane_state *plane_state)
1333 {
1334 	int j;
1335 
1336 	for (j = 0; j < MAX_PIPES; j++) {
1337 		const struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
1338 
1339 		if (plane_state == pipe_ctx->plane_state) {
1340 			return true;
1341 		}
1342 	}
1343 
1344 	return false;
1345 }
1346 
get_plane_info_update_type(const struct dc_surface_update * u)1347 static enum surface_update_type get_plane_info_update_type(const struct dc_surface_update *u)
1348 {
1349 	union surface_update_flags *update_flags = &u->surface->update_flags;
1350 	enum surface_update_type update_type = UPDATE_TYPE_FAST;
1351 
1352 	if (!u->plane_info)
1353 		return UPDATE_TYPE_FAST;
1354 
1355 	if (u->plane_info->color_space != u->surface->color_space) {
1356 		update_flags->bits.color_space_change = 1;
1357 		elevate_update_type(&update_type, UPDATE_TYPE_MED);
1358 	}
1359 
1360 	if (u->plane_info->horizontal_mirror != u->surface->horizontal_mirror) {
1361 		update_flags->bits.horizontal_mirror_change = 1;
1362 		elevate_update_type(&update_type, UPDATE_TYPE_MED);
1363 	}
1364 
1365 	if (u->plane_info->rotation != u->surface->rotation) {
1366 		update_flags->bits.rotation_change = 1;
1367 		elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1368 	}
1369 
1370 	if (u->plane_info->format != u->surface->format) {
1371 		update_flags->bits.pixel_format_change = 1;
1372 		elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1373 	}
1374 
1375 	if (u->plane_info->stereo_format != u->surface->stereo_format) {
1376 		update_flags->bits.stereo_format_change = 1;
1377 		elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1378 	}
1379 
1380 	if (u->plane_info->per_pixel_alpha != u->surface->per_pixel_alpha) {
1381 		update_flags->bits.per_pixel_alpha_change = 1;
1382 		elevate_update_type(&update_type, UPDATE_TYPE_MED);
1383 	}
1384 
1385 	if (u->plane_info->global_alpha_value != u->surface->global_alpha_value) {
1386 		update_flags->bits.global_alpha_change = 1;
1387 		elevate_update_type(&update_type, UPDATE_TYPE_MED);
1388 	}
1389 
1390 	if (u->plane_info->sdr_white_level != u->surface->sdr_white_level) {
1391 		update_flags->bits.sdr_white_level = 1;
1392 		elevate_update_type(&update_type, UPDATE_TYPE_MED);
1393 	}
1394 
1395 	if (u->plane_info->dcc.enable != u->surface->dcc.enable
1396 			|| u->plane_info->dcc.independent_64b_blks != u->surface->dcc.independent_64b_blks
1397 			|| u->plane_info->dcc.meta_pitch != u->surface->dcc.meta_pitch) {
1398 		update_flags->bits.dcc_change = 1;
1399 		elevate_update_type(&update_type, UPDATE_TYPE_MED);
1400 	}
1401 
1402 	if (resource_pixel_format_to_bpp(u->plane_info->format) !=
1403 			resource_pixel_format_to_bpp(u->surface->format)) {
1404 		/* different bytes per element will require full bandwidth
1405 		 * and DML calculation
1406 		 */
1407 		update_flags->bits.bpp_change = 1;
1408 		elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1409 	}
1410 
1411 	if (u->plane_info->plane_size.surface_pitch != u->surface->plane_size.surface_pitch
1412 			|| u->plane_info->plane_size.surface_pitch != u->surface->plane_size.surface_pitch
1413 			|| u->plane_info->plane_size.chroma_pitch != u->surface->plane_size.chroma_pitch) {
1414 		update_flags->bits.plane_size_change = 1;
1415 		elevate_update_type(&update_type, UPDATE_TYPE_MED);
1416 	}
1417 
1418 
1419 	if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info,
1420 			sizeof(union dc_tiling_info)) != 0) {
1421 		update_flags->bits.swizzle_change = 1;
1422 		elevate_update_type(&update_type, UPDATE_TYPE_MED);
1423 
1424 		/* todo: below are HW dependent, we should add a hook to
1425 		 * DCE/N resource and validated there.
1426 		 */
1427 		if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
1428 			/* swizzled mode requires RQ to be setup properly,
1429 			 * thus need to run DML to calculate RQ settings
1430 			 */
1431 			update_flags->bits.bandwidth_change = 1;
1432 			elevate_update_type(&update_type, UPDATE_TYPE_FULL);
1433 		}
1434 	}
1435 
1436 	/* This should be UPDATE_TYPE_FAST if nothing has changed. */
1437 	return update_type;
1438 }
1439 
get_scaling_info_update_type(const struct dc_surface_update * u)1440 static enum surface_update_type get_scaling_info_update_type(
1441 		const struct dc_surface_update *u)
1442 {
1443 	union surface_update_flags *update_flags = &u->surface->update_flags;
1444 
1445 	if (!u->scaling_info)
1446 		return UPDATE_TYPE_FAST;
1447 
1448 	if (u->scaling_info->clip_rect.width != u->surface->clip_rect.width
1449 			|| u->scaling_info->clip_rect.height != u->surface->clip_rect.height
1450 			|| u->scaling_info->dst_rect.width != u->surface->dst_rect.width
1451 			|| u->scaling_info->dst_rect.height != u->surface->dst_rect.height) {
1452 		update_flags->bits.scaling_change = 1;
1453 
1454 		if ((u->scaling_info->dst_rect.width < u->surface->dst_rect.width
1455 			|| u->scaling_info->dst_rect.height < u->surface->dst_rect.height)
1456 				&& (u->scaling_info->dst_rect.width < u->surface->src_rect.width
1457 					|| u->scaling_info->dst_rect.height < u->surface->src_rect.height))
1458 			/* Making dst rect smaller requires a bandwidth change */
1459 			update_flags->bits.bandwidth_change = 1;
1460 	}
1461 
1462 	if (u->scaling_info->src_rect.width != u->surface->src_rect.width
1463 		|| u->scaling_info->src_rect.height != u->surface->src_rect.height) {
1464 
1465 		update_flags->bits.scaling_change = 1;
1466 		if (u->scaling_info->src_rect.width > u->surface->src_rect.width
1467 				&& u->scaling_info->src_rect.height > u->surface->src_rect.height)
1468 			/* Making src rect bigger requires a bandwidth change */
1469 			update_flags->bits.clock_change = 1;
1470 	}
1471 
1472 	if (u->scaling_info->src_rect.x != u->surface->src_rect.x
1473 			|| u->scaling_info->src_rect.y != u->surface->src_rect.y
1474 			|| u->scaling_info->clip_rect.x != u->surface->clip_rect.x
1475 			|| u->scaling_info->clip_rect.y != u->surface->clip_rect.y
1476 			|| u->scaling_info->dst_rect.x != u->surface->dst_rect.x
1477 			|| u->scaling_info->dst_rect.y != u->surface->dst_rect.y)
1478 		update_flags->bits.position_change = 1;
1479 
1480 	if (update_flags->bits.clock_change
1481 			|| update_flags->bits.bandwidth_change)
1482 		return UPDATE_TYPE_FULL;
1483 
1484 	if (update_flags->bits.scaling_change
1485 			|| update_flags->bits.position_change)
1486 		return UPDATE_TYPE_MED;
1487 
1488 	return UPDATE_TYPE_FAST;
1489 }
1490 
det_surface_update(const struct dc * dc,const struct dc_surface_update * u)1491 static enum surface_update_type det_surface_update(const struct dc *dc,
1492 		const struct dc_surface_update *u)
1493 {
1494 	const struct dc_state *context = dc->current_state;
1495 	enum surface_update_type type;
1496 	enum surface_update_type overall_type = UPDATE_TYPE_FAST;
1497 	union surface_update_flags *update_flags = &u->surface->update_flags;
1498 
1499 	update_flags->raw = 0; // Reset all flags
1500 
1501 	if (u->flip_addr)
1502 		update_flags->bits.addr_update = 1;
1503 
1504 	if (!is_surface_in_context(context, u->surface)) {
1505 		update_flags->bits.new_plane = 1;
1506 		return UPDATE_TYPE_FULL;
1507 	}
1508 
1509 	if (u->surface->force_full_update) {
1510 		update_flags->bits.full_update = 1;
1511 		return UPDATE_TYPE_FULL;
1512 	}
1513 
1514 	type = get_plane_info_update_type(u);
1515 	elevate_update_type(&overall_type, type);
1516 
1517 	type = get_scaling_info_update_type(u);
1518 	elevate_update_type(&overall_type, type);
1519 
1520 	if (u->flip_addr)
1521 		update_flags->bits.addr_update = 1;
1522 
1523 	if (u->in_transfer_func)
1524 		update_flags->bits.in_transfer_func_change = 1;
1525 
1526 	if (u->input_csc_color_matrix)
1527 		update_flags->bits.input_csc_change = 1;
1528 
1529 	if (u->coeff_reduction_factor)
1530 		update_flags->bits.coeff_reduction_change = 1;
1531 
1532 	if (u->gamma) {
1533 		enum surface_pixel_format format = SURFACE_PIXEL_FORMAT_GRPH_BEGIN;
1534 
1535 		if (u->plane_info)
1536 			format = u->plane_info->format;
1537 		else if (u->surface)
1538 			format = u->surface->format;
1539 
1540 		if (dce_use_lut(format))
1541 			update_flags->bits.gamma_change = 1;
1542 	}
1543 
1544 	if (update_flags->bits.in_transfer_func_change) {
1545 		type = UPDATE_TYPE_MED;
1546 		elevate_update_type(&overall_type, type);
1547 	}
1548 
1549 	if (update_flags->bits.input_csc_change
1550 			|| update_flags->bits.coeff_reduction_change
1551 			|| update_flags->bits.gamma_change) {
1552 		type = UPDATE_TYPE_FULL;
1553 		elevate_update_type(&overall_type, type);
1554 	}
1555 
1556 	return overall_type;
1557 }
1558 
check_update_surfaces_for_stream(struct dc * dc,struct dc_surface_update * updates,int surface_count,struct dc_stream_update * stream_update,const struct dc_stream_status * stream_status)1559 static enum surface_update_type check_update_surfaces_for_stream(
1560 		struct dc *dc,
1561 		struct dc_surface_update *updates,
1562 		int surface_count,
1563 		struct dc_stream_update *stream_update,
1564 		const struct dc_stream_status *stream_status)
1565 {
1566 	int i;
1567 	enum surface_update_type overall_type = UPDATE_TYPE_FAST;
1568 
1569 	if (stream_status == NULL || stream_status->plane_count != surface_count)
1570 		return UPDATE_TYPE_FULL;
1571 
1572 	/* some stream updates require passive update */
1573 	if (stream_update) {
1574 		if ((stream_update->src.height != 0) &&
1575 				(stream_update->src.width != 0))
1576 			return UPDATE_TYPE_FULL;
1577 
1578 		if ((stream_update->dst.height != 0) &&
1579 				(stream_update->dst.width != 0))
1580 			return UPDATE_TYPE_FULL;
1581 
1582 		if (stream_update->out_transfer_func)
1583 			return UPDATE_TYPE_FULL;
1584 
1585 		if (stream_update->abm_level)
1586 			return UPDATE_TYPE_FULL;
1587 
1588 		if (stream_update->dpms_off)
1589 			return UPDATE_TYPE_FULL;
1590 
1591 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
1592 		if (stream_update->wb_update)
1593 			return UPDATE_TYPE_FULL;
1594 #endif
1595 	}
1596 
1597 	for (i = 0 ; i < surface_count; i++) {
1598 		enum surface_update_type type =
1599 				det_surface_update(dc, &updates[i]);
1600 
1601 		if (type == UPDATE_TYPE_FULL)
1602 			return type;
1603 
1604 		elevate_update_type(&overall_type, type);
1605 	}
1606 
1607 	return overall_type;
1608 }
1609 
1610 /**
1611  * dc_check_update_surfaces_for_stream() - Determine update type (fast, med, or full)
1612  *
1613  * See :c:type:`enum surface_update_type <surface_update_type>` for explanation of update types
1614  */
dc_check_update_surfaces_for_stream(struct dc * dc,struct dc_surface_update * updates,int surface_count,struct dc_stream_update * stream_update,const struct dc_stream_status * stream_status)1615 enum surface_update_type dc_check_update_surfaces_for_stream(
1616 		struct dc *dc,
1617 		struct dc_surface_update *updates,
1618 		int surface_count,
1619 		struct dc_stream_update *stream_update,
1620 		const struct dc_stream_status *stream_status)
1621 {
1622 	int i;
1623 	enum surface_update_type type;
1624 
1625 	for (i = 0; i < surface_count; i++)
1626 		updates[i].surface->update_flags.raw = 0;
1627 
1628 	type = check_update_surfaces_for_stream(dc, updates, surface_count, stream_update, stream_status);
1629 	if (type == UPDATE_TYPE_FULL)
1630 		for (i = 0; i < surface_count; i++)
1631 			updates[i].surface->update_flags.raw = 0xFFFFFFFF;
1632 
1633 	if (type == UPDATE_TYPE_FAST && memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0)
1634 		dc->optimized_required = true;
1635 
1636 	return type;
1637 }
1638 
stream_get_status(struct dc_state * ctx,struct dc_stream_state * stream)1639 static struct dc_stream_status *stream_get_status(
1640 	struct dc_state *ctx,
1641 	struct dc_stream_state *stream)
1642 {
1643 	uint8_t i;
1644 
1645 	for (i = 0; i < ctx->stream_count; i++) {
1646 		if (stream == ctx->streams[i]) {
1647 			return &ctx->stream_status[i];
1648 		}
1649 	}
1650 
1651 	return NULL;
1652 }
1653 
1654 static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
1655 
copy_surface_update_to_plane(struct dc_plane_state * surface,struct dc_surface_update * srf_update)1656 static void copy_surface_update_to_plane(
1657 		struct dc_plane_state *surface,
1658 		struct dc_surface_update *srf_update)
1659 {
1660 	if (srf_update->flip_addr) {
1661 		surface->address = srf_update->flip_addr->address;
1662 		surface->flip_immediate =
1663 			srf_update->flip_addr->flip_immediate;
1664 		surface->time.time_elapsed_in_us[surface->time.index] =
1665 			srf_update->flip_addr->flip_timestamp_in_us -
1666 				surface->time.prev_update_time_in_us;
1667 		surface->time.prev_update_time_in_us =
1668 			srf_update->flip_addr->flip_timestamp_in_us;
1669 		surface->time.index++;
1670 		if (surface->time.index >= DC_PLANE_UPDATE_TIMES_MAX)
1671 			surface->time.index = 0;
1672 	}
1673 
1674 	if (srf_update->scaling_info) {
1675 		surface->scaling_quality =
1676 				srf_update->scaling_info->scaling_quality;
1677 		surface->dst_rect =
1678 				srf_update->scaling_info->dst_rect;
1679 		surface->src_rect =
1680 				srf_update->scaling_info->src_rect;
1681 		surface->clip_rect =
1682 				srf_update->scaling_info->clip_rect;
1683 	}
1684 
1685 	if (srf_update->plane_info) {
1686 		surface->color_space =
1687 				srf_update->plane_info->color_space;
1688 		surface->format =
1689 				srf_update->plane_info->format;
1690 		surface->plane_size =
1691 				srf_update->plane_info->plane_size;
1692 		surface->rotation =
1693 				srf_update->plane_info->rotation;
1694 		surface->horizontal_mirror =
1695 				srf_update->plane_info->horizontal_mirror;
1696 		surface->stereo_format =
1697 				srf_update->plane_info->stereo_format;
1698 		surface->tiling_info =
1699 				srf_update->plane_info->tiling_info;
1700 		surface->visible =
1701 				srf_update->plane_info->visible;
1702 		surface->per_pixel_alpha =
1703 				srf_update->plane_info->per_pixel_alpha;
1704 		surface->global_alpha =
1705 				srf_update->plane_info->global_alpha;
1706 		surface->global_alpha_value =
1707 				srf_update->plane_info->global_alpha_value;
1708 		surface->dcc =
1709 				srf_update->plane_info->dcc;
1710 		surface->sdr_white_level =
1711 				srf_update->plane_info->sdr_white_level;
1712 		surface->layer_index =
1713 				srf_update->plane_info->layer_index;
1714 	}
1715 
1716 	if (srf_update->gamma &&
1717 			(surface->gamma_correction !=
1718 					srf_update->gamma)) {
1719 		memcpy(&surface->gamma_correction->entries,
1720 			&srf_update->gamma->entries,
1721 			sizeof(struct dc_gamma_entries));
1722 		surface->gamma_correction->is_identity =
1723 			srf_update->gamma->is_identity;
1724 		surface->gamma_correction->num_entries =
1725 			srf_update->gamma->num_entries;
1726 		surface->gamma_correction->type =
1727 			srf_update->gamma->type;
1728 	}
1729 
1730 	if (srf_update->in_transfer_func &&
1731 			(surface->in_transfer_func !=
1732 				srf_update->in_transfer_func)) {
1733 		surface->in_transfer_func->sdr_ref_white_level =
1734 			srf_update->in_transfer_func->sdr_ref_white_level;
1735 		surface->in_transfer_func->tf =
1736 			srf_update->in_transfer_func->tf;
1737 		surface->in_transfer_func->type =
1738 			srf_update->in_transfer_func->type;
1739 		memcpy(&surface->in_transfer_func->tf_pts,
1740 			&srf_update->in_transfer_func->tf_pts,
1741 			sizeof(struct dc_transfer_func_distributed_points));
1742 	}
1743 
1744 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
1745 	if (srf_update->func_shaper &&
1746 			(surface->in_shaper_func !=
1747 			srf_update->func_shaper))
1748 		memcpy(surface->in_shaper_func, srf_update->func_shaper,
1749 		sizeof(*surface->in_shaper_func));
1750 
1751 	if (srf_update->lut3d_func &&
1752 			(surface->lut3d_func !=
1753 			srf_update->lut3d_func))
1754 		memcpy(surface->lut3d_func, srf_update->lut3d_func,
1755 		sizeof(*surface->lut3d_func));
1756 
1757 	if (srf_update->blend_tf &&
1758 			(surface->blend_tf !=
1759 			srf_update->blend_tf))
1760 		memcpy(surface->blend_tf, srf_update->blend_tf,
1761 		sizeof(*surface->blend_tf));
1762 
1763 #endif
1764 	if (srf_update->input_csc_color_matrix)
1765 		surface->input_csc_color_matrix =
1766 			*srf_update->input_csc_color_matrix;
1767 
1768 	if (srf_update->coeff_reduction_factor)
1769 		surface->coeff_reduction_factor =
1770 			*srf_update->coeff_reduction_factor;
1771 }
1772 
copy_stream_update_to_stream(struct dc * dc,struct dc_state * context,struct dc_stream_state * stream,const struct dc_stream_update * update)1773 static void copy_stream_update_to_stream(struct dc *dc,
1774 					 struct dc_state *context,
1775 					 struct dc_stream_state *stream,
1776 					 const struct dc_stream_update *update)
1777 {
1778 	if (update == NULL || stream == NULL)
1779 		return;
1780 
1781 	if (update->src.height && update->src.width)
1782 		stream->src = update->src;
1783 
1784 	if (update->dst.height && update->dst.width)
1785 		stream->dst = update->dst;
1786 
1787 	if (update->out_transfer_func &&
1788 	    stream->out_transfer_func != update->out_transfer_func) {
1789 		stream->out_transfer_func->sdr_ref_white_level =
1790 			update->out_transfer_func->sdr_ref_white_level;
1791 		stream->out_transfer_func->tf = update->out_transfer_func->tf;
1792 		stream->out_transfer_func->type =
1793 			update->out_transfer_func->type;
1794 		memcpy(&stream->out_transfer_func->tf_pts,
1795 		       &update->out_transfer_func->tf_pts,
1796 		       sizeof(struct dc_transfer_func_distributed_points));
1797 	}
1798 
1799 	if (update->hdr_static_metadata)
1800 		stream->hdr_static_metadata = *update->hdr_static_metadata;
1801 
1802 	if (update->abm_level)
1803 		stream->abm_level = *update->abm_level;
1804 
1805 	if (update->periodic_interrupt0)
1806 		stream->periodic_interrupt0 = *update->periodic_interrupt0;
1807 
1808 	if (update->periodic_interrupt1)
1809 		stream->periodic_interrupt1 = *update->periodic_interrupt1;
1810 
1811 	if (update->gamut_remap)
1812 		stream->gamut_remap_matrix = *update->gamut_remap;
1813 
1814 	/* Note: this being updated after mode set is currently not a use case
1815 	 * however if it arises OCSC would need to be reprogrammed at the
1816 	 * minimum
1817 	 */
1818 	if (update->output_color_space)
1819 		stream->output_color_space = *update->output_color_space;
1820 
1821 	if (update->output_csc_transform)
1822 		stream->csc_color_matrix = *update->output_csc_transform;
1823 
1824 	if (update->vrr_infopacket)
1825 		stream->vrr_infopacket = *update->vrr_infopacket;
1826 
1827 	if (update->dpms_off)
1828 		stream->dpms_off = *update->dpms_off;
1829 
1830 	if (update->vsc_infopacket)
1831 		stream->vsc_infopacket = *update->vsc_infopacket;
1832 
1833 	if (update->vsp_infopacket)
1834 		stream->vsp_infopacket = *update->vsp_infopacket;
1835 
1836 	if (update->dither_option)
1837 		stream->dither_option = *update->dither_option;
1838 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
1839 	/* update current stream with writeback info */
1840 	if (update->wb_update) {
1841 		int i;
1842 
1843 		stream->num_wb_info = update->wb_update->num_wb_info;
1844 		ASSERT(stream->num_wb_info <= MAX_DWB_PIPES);
1845 		for (i = 0; i < stream->num_wb_info; i++)
1846 			stream->writeback_info[i] =
1847 				update->wb_update->writeback_info[i];
1848 	}
1849 #endif
1850 #if defined(CONFIG_DRM_AMD_DC_DSC_SUPPORT)
1851 	if (update->dsc_config) {
1852 		struct dc_dsc_config old_dsc_cfg = stream->timing.dsc_cfg;
1853 		uint32_t old_dsc_enabled = stream->timing.flags.DSC;
1854 		uint32_t enable_dsc = (update->dsc_config->num_slices_h != 0 &&
1855 				       update->dsc_config->num_slices_v != 0);
1856 
1857 		stream->timing.dsc_cfg = *update->dsc_config;
1858 		stream->timing.flags.DSC = enable_dsc;
1859 		if (!dc->res_pool->funcs->validate_bandwidth(dc, context,
1860 							     true)) {
1861 			stream->timing.dsc_cfg = old_dsc_cfg;
1862 			stream->timing.flags.DSC = old_dsc_enabled;
1863 		}
1864 	}
1865 #endif
1866 }
1867 
commit_planes_do_stream_update(struct dc * dc,struct dc_stream_state * stream,struct dc_stream_update * stream_update,enum surface_update_type update_type,struct dc_state * context)1868 static void commit_planes_do_stream_update(struct dc *dc,
1869 		struct dc_stream_state *stream,
1870 		struct dc_stream_update *stream_update,
1871 		enum surface_update_type update_type,
1872 		struct dc_state *context)
1873 {
1874 	int j;
1875 
1876 	// Stream updates
1877 	for (j = 0; j < dc->res_pool->pipe_count; j++) {
1878 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
1879 
1880 		if (!pipe_ctx->top_pipe &&  !pipe_ctx->prev_odm_pipe && pipe_ctx->stream == stream) {
1881 
1882 			if (stream_update->periodic_interrupt0 &&
1883 					dc->hwss.setup_periodic_interrupt)
1884 				dc->hwss.setup_periodic_interrupt(pipe_ctx, VLINE0);
1885 
1886 			if (stream_update->periodic_interrupt1 &&
1887 					dc->hwss.setup_periodic_interrupt)
1888 				dc->hwss.setup_periodic_interrupt(pipe_ctx, VLINE1);
1889 
1890 			if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
1891 					stream_update->vrr_infopacket ||
1892 					stream_update->vsc_infopacket ||
1893 					stream_update->vsp_infopacket) {
1894 				resource_build_info_frame(pipe_ctx);
1895 				dc->hwss.update_info_frame(pipe_ctx);
1896 			}
1897 
1898 			if (stream_update->gamut_remap)
1899 				dc_stream_set_gamut_remap(dc, stream);
1900 
1901 			if (stream_update->output_csc_transform)
1902 				dc_stream_program_csc_matrix(dc, stream);
1903 
1904 			if (stream_update->dither_option) {
1905 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
1906 				struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
1907 #endif
1908 				resource_build_bit_depth_reduction_params(pipe_ctx->stream,
1909 									&pipe_ctx->stream->bit_depth_params);
1910 				pipe_ctx->stream_res.opp->funcs->opp_program_fmt(pipe_ctx->stream_res.opp,
1911 						&stream->bit_depth_params,
1912 						&stream->clamping);
1913 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
1914 				while (odm_pipe) {
1915 					odm_pipe->stream_res.opp->funcs->opp_program_fmt(odm_pipe->stream_res.opp,
1916 							&stream->bit_depth_params,
1917 							&stream->clamping);
1918 					odm_pipe = odm_pipe->next_odm_pipe;
1919 				}
1920 #endif
1921 			}
1922 
1923 #if defined(CONFIG_DRM_AMD_DC_DSC_SUPPORT)
1924 			if (stream_update->dsc_config && dc->hwss.pipe_control_lock_global) {
1925 				dc->hwss.pipe_control_lock_global(dc, pipe_ctx, true);
1926 				dp_update_dsc_config(pipe_ctx);
1927 				dc->hwss.pipe_control_lock_global(dc, pipe_ctx, false);
1928 			}
1929 #endif
1930 			/* Full fe update*/
1931 			if (update_type == UPDATE_TYPE_FAST)
1932 				continue;
1933 
1934 			if (stream_update->dpms_off) {
1935 				dc->hwss.pipe_control_lock(dc, pipe_ctx, true);
1936 
1937 				if (*stream_update->dpms_off) {
1938 					core_link_disable_stream(pipe_ctx);
1939 					/* for dpms, keep acquired resources*/
1940 					if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only)
1941 						pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
1942 
1943 					dc->hwss.optimize_bandwidth(dc, dc->current_state);
1944 				} else {
1945 					if (!dc->optimize_seamless_boot)
1946 						dc->hwss.prepare_bandwidth(dc, dc->current_state);
1947 
1948 					core_link_enable_stream(dc->current_state, pipe_ctx);
1949 				}
1950 
1951 				dc->hwss.pipe_control_lock(dc, pipe_ctx, false);
1952 			}
1953 
1954 			if (stream_update->abm_level && pipe_ctx->stream_res.abm) {
1955 				if (pipe_ctx->stream_res.tg->funcs->is_blanked) {
1956 					// if otg funcs defined check if blanked before programming
1957 					if (!pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg))
1958 						pipe_ctx->stream_res.abm->funcs->set_abm_level(
1959 							pipe_ctx->stream_res.abm, stream->abm_level);
1960 				} else
1961 					pipe_ctx->stream_res.abm->funcs->set_abm_level(
1962 						pipe_ctx->stream_res.abm, stream->abm_level);
1963 			}
1964 		}
1965 	}
1966 }
1967 
commit_planes_for_stream(struct dc * dc,struct dc_surface_update * srf_updates,int surface_count,struct dc_stream_state * stream,struct dc_stream_update * stream_update,enum surface_update_type update_type,struct dc_state * context)1968 static void commit_planes_for_stream(struct dc *dc,
1969 		struct dc_surface_update *srf_updates,
1970 		int surface_count,
1971 		struct dc_stream_state *stream,
1972 		struct dc_stream_update *stream_update,
1973 		enum surface_update_type update_type,
1974 		struct dc_state *context)
1975 {
1976 	int i, j;
1977 	struct pipe_ctx *top_pipe_to_program = NULL;
1978 
1979 	if (dc->optimize_seamless_boot && surface_count > 0) {
1980 		/* Optimize seamless boot flag keeps clocks and watermarks high until
1981 		 * first flip. After first flip, optimization is required to lower
1982 		 * bandwidth. Important to note that it is expected UEFI will
1983 		 * only light up a single display on POST, therefore we only expect
1984 		 * one stream with seamless boot flag set.
1985 		 */
1986 		if (stream->apply_seamless_boot_optimization) {
1987 			stream->apply_seamless_boot_optimization = false;
1988 			dc->optimize_seamless_boot = false;
1989 			dc->optimized_required = true;
1990 		}
1991 	}
1992 
1993 	if (update_type == UPDATE_TYPE_FULL && !dc->optimize_seamless_boot) {
1994 		dc->hwss.prepare_bandwidth(dc, context);
1995 		context_clock_trace(dc, context);
1996 	}
1997 
1998 	// Stream updates
1999 	if (stream_update)
2000 		commit_planes_do_stream_update(dc, stream, stream_update, update_type, context);
2001 
2002 	if (surface_count == 0) {
2003 		/*
2004 		 * In case of turning off screen, no need to program front end a second time.
2005 		 * just return after program blank.
2006 		 */
2007 		dc->hwss.apply_ctx_for_surface(dc, stream, 0, context);
2008 		return;
2009 	}
2010 
2011 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
2012 	if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
2013 		for (i = 0; i < surface_count; i++) {
2014 			struct dc_plane_state *plane_state = srf_updates[i].surface;
2015 			/*set logical flag for lock/unlock use*/
2016 			for (j = 0; j < dc->res_pool->pipe_count; j++) {
2017 				struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2018 				if (!pipe_ctx->plane_state)
2019 					continue;
2020 				if (pipe_ctx->plane_state != plane_state)
2021 					continue;
2022 				plane_state->triplebuffer_flips = false;
2023 				if (update_type == UPDATE_TYPE_FAST &&
2024 					dc->hwss.program_triplebuffer != NULL &&
2025 					!plane_state->flip_immediate &&
2026 					!dc->debug.disable_tri_buf) {
2027 						/*triple buffer for VUpdate  only*/
2028 						plane_state->triplebuffer_flips = true;
2029 				}
2030 			}
2031 		}
2032 	}
2033 #endif
2034 
2035 	// Update Type FULL, Surface updates
2036 	for (j = 0; j < dc->res_pool->pipe_count; j++) {
2037 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2038 
2039 		if (!pipe_ctx->top_pipe &&
2040 			!pipe_ctx->prev_odm_pipe &&
2041 			pipe_ctx->stream &&
2042 			pipe_ctx->stream == stream) {
2043 			struct dc_stream_status *stream_status = NULL;
2044 
2045 			top_pipe_to_program = pipe_ctx;
2046 
2047 			if (!pipe_ctx->plane_state)
2048 				continue;
2049 
2050 			/* Full fe update*/
2051 			if (update_type == UPDATE_TYPE_FAST)
2052 				continue;
2053 
2054 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
2055 			ASSERT(!pipe_ctx->plane_state->triplebuffer_flips);
2056 
2057 			if (dc->hwss.program_triplebuffer != NULL &&
2058 				!dc->debug.disable_tri_buf) {
2059 				/*turn off triple buffer for full update*/
2060 				dc->hwss.program_triplebuffer(
2061 					dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips);
2062 			}
2063 #endif
2064 			stream_status =
2065 				stream_get_status(context, pipe_ctx->stream);
2066 
2067 			dc->hwss.apply_ctx_for_surface(
2068 					dc, pipe_ctx->stream, stream_status->plane_count, context);
2069 		}
2070 	}
2071 
2072 	// Update Type FAST, Surface updates
2073 	if (update_type == UPDATE_TYPE_FAST) {
2074 		/* Lock the top pipe while updating plane addrs, since freesync requires
2075 		 *  plane addr update event triggers to be synchronized.
2076 		 *  top_pipe_to_program is expected to never be NULL
2077 		 */
2078 		dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true);
2079 
2080 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
2081 		if (dc->hwss.set_flip_control_gsl)
2082 			for (i = 0; i < surface_count; i++) {
2083 				struct dc_plane_state *plane_state = srf_updates[i].surface;
2084 
2085 				for (j = 0; j < dc->res_pool->pipe_count; j++) {
2086 					struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2087 
2088 					if (pipe_ctx->stream != stream)
2089 						continue;
2090 
2091 					if (pipe_ctx->plane_state != plane_state)
2092 						continue;
2093 
2094 					// GSL has to be used for flip immediate
2095 					dc->hwss.set_flip_control_gsl(pipe_ctx,
2096 							plane_state->flip_immediate);
2097 				}
2098 			}
2099 #endif
2100 		/* Perform requested Updates */
2101 		for (i = 0; i < surface_count; i++) {
2102 			struct dc_plane_state *plane_state = srf_updates[i].surface;
2103 
2104 			for (j = 0; j < dc->res_pool->pipe_count; j++) {
2105 				struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2106 
2107 				if (pipe_ctx->stream != stream)
2108 					continue;
2109 
2110 				if (pipe_ctx->plane_state != plane_state)
2111 					continue;
2112 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
2113 				/*program triple buffer after lock based on flip type*/
2114 				if (dc->hwss.program_triplebuffer != NULL &&
2115 					!dc->debug.disable_tri_buf) {
2116 					/*only enable triplebuffer for  fast_update*/
2117 					dc->hwss.program_triplebuffer(
2118 						dc, pipe_ctx, plane_state->triplebuffer_flips);
2119 				}
2120 #endif
2121 				if (srf_updates[i].flip_addr)
2122 					dc->hwss.update_plane_addr(dc, pipe_ctx);
2123 			}
2124 		}
2125 
2126 		dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
2127 	}
2128 
2129 	// Fire manual trigger only when bottom plane is flipped
2130 	for (j = 0; j < dc->res_pool->pipe_count; j++) {
2131 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
2132 
2133 		if (pipe_ctx->bottom_pipe ||
2134 				!pipe_ctx->stream ||
2135 				pipe_ctx->stream != stream ||
2136 				!pipe_ctx->plane_state->update_flags.bits.addr_update)
2137 			continue;
2138 
2139 		if (pipe_ctx->stream_res.tg->funcs->program_manual_trigger)
2140 			pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg);
2141 	}
2142 }
2143 
dc_commit_updates_for_stream(struct dc * dc,struct dc_surface_update * srf_updates,int surface_count,struct dc_stream_state * stream,struct dc_stream_update * stream_update,struct dc_state * state)2144 void dc_commit_updates_for_stream(struct dc *dc,
2145 		struct dc_surface_update *srf_updates,
2146 		int surface_count,
2147 		struct dc_stream_state *stream,
2148 		struct dc_stream_update *stream_update,
2149 		struct dc_state *state)
2150 {
2151 	const struct dc_stream_status *stream_status;
2152 	enum surface_update_type update_type;
2153 	struct dc_state *context;
2154 	struct dc_context *dc_ctx = dc->ctx;
2155 	int i;
2156 
2157 	stream_status = dc_stream_get_status(stream);
2158 	context = dc->current_state;
2159 
2160 	update_type = dc_check_update_surfaces_for_stream(
2161 				dc, srf_updates, surface_count, stream_update, stream_status);
2162 
2163 	if (update_type >= update_surface_trace_level)
2164 		update_surface_trace(dc, srf_updates, surface_count);
2165 
2166 
2167 	if (update_type >= UPDATE_TYPE_FULL) {
2168 
2169 		/* initialize scratch memory for building context */
2170 		context = dc_create_state(dc);
2171 		if (context == NULL) {
2172 			DC_ERROR("Failed to allocate new validate context!\n");
2173 			return;
2174 		}
2175 
2176 		dc_resource_state_copy_construct(state, context);
2177 
2178 		for (i = 0; i < dc->res_pool->pipe_count; i++) {
2179 			struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
2180 			struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
2181 
2182 			if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state)
2183 				new_pipe->plane_state->force_full_update = true;
2184 		}
2185 	}
2186 
2187 
2188 	for (i = 0; i < surface_count; i++) {
2189 		struct dc_plane_state *surface = srf_updates[i].surface;
2190 
2191 		copy_surface_update_to_plane(surface, &srf_updates[i]);
2192 
2193 	}
2194 
2195 	copy_stream_update_to_stream(dc, context, stream, stream_update);
2196 
2197 	commit_planes_for_stream(
2198 				dc,
2199 				srf_updates,
2200 				surface_count,
2201 				stream,
2202 				stream_update,
2203 				update_type,
2204 				context);
2205 	/*update current_State*/
2206 	if (dc->current_state != context) {
2207 
2208 		struct dc_state *old = dc->current_state;
2209 
2210 		dc->current_state = context;
2211 		dc_release_state(old);
2212 
2213 		for (i = 0; i < dc->res_pool->pipe_count; i++) {
2214 			struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2215 
2216 			if (pipe_ctx->plane_state && pipe_ctx->stream == stream)
2217 				pipe_ctx->plane_state->force_full_update = false;
2218 		}
2219 	}
2220 	/*let's use current_state to update watermark etc*/
2221 	if (update_type >= UPDATE_TYPE_FULL)
2222 		dc_post_update_surfaces_to_stream(dc);
2223 
2224 	return;
2225 
2226 }
2227 
dc_get_current_stream_count(struct dc * dc)2228 uint8_t dc_get_current_stream_count(struct dc *dc)
2229 {
2230 	return dc->current_state->stream_count;
2231 }
2232 
dc_get_stream_at_index(struct dc * dc,uint8_t i)2233 struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i)
2234 {
2235 	if (i < dc->current_state->stream_count)
2236 		return dc->current_state->streams[i];
2237 	return NULL;
2238 }
2239 
dc_interrupt_to_irq_source(struct dc * dc,uint32_t src_id,uint32_t ext_id)2240 enum dc_irq_source dc_interrupt_to_irq_source(
2241 		struct dc *dc,
2242 		uint32_t src_id,
2243 		uint32_t ext_id)
2244 {
2245 	return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id);
2246 }
2247 
2248 /**
2249  * dc_interrupt_set() - Enable/disable an AMD hw interrupt source
2250  */
dc_interrupt_set(struct dc * dc,enum dc_irq_source src,bool enable)2251 bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable)
2252 {
2253 
2254 	if (dc == NULL)
2255 		return false;
2256 
2257 	return dal_irq_service_set(dc->res_pool->irqs, src, enable);
2258 }
2259 
dc_interrupt_ack(struct dc * dc,enum dc_irq_source src)2260 void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src)
2261 {
2262 	dal_irq_service_ack(dc->res_pool->irqs, src);
2263 }
2264 
dc_set_power_state(struct dc * dc,enum dc_acpi_cm_power_state power_state)2265 void dc_set_power_state(
2266 	struct dc *dc,
2267 	enum dc_acpi_cm_power_state power_state)
2268 {
2269 	struct kref refcount;
2270 	struct display_mode_lib *dml = kzalloc(sizeof(struct display_mode_lib),
2271 						GFP_KERNEL);
2272 
2273 	ASSERT(dml);
2274 	if (!dml)
2275 		return;
2276 
2277 	switch (power_state) {
2278 	case DC_ACPI_CM_POWER_STATE_D0:
2279 		dc_resource_state_construct(dc, dc->current_state);
2280 
2281 		dc->hwss.init_hw(dc);
2282 
2283 #ifdef CONFIG_DRM_AMD_DC_DCN2_0
2284 		if (dc->hwss.init_sys_ctx != NULL &&
2285 			dc->vm_pa_config.valid) {
2286 			dc->hwss.init_sys_ctx(dc->hwseq, dc, &dc->vm_pa_config);
2287 		}
2288 #endif
2289 
2290 		break;
2291 	default:
2292 		ASSERT(dc->current_state->stream_count == 0);
2293 		/* Zero out the current context so that on resume we start with
2294 		 * clean state, and dc hw programming optimizations will not
2295 		 * cause any trouble.
2296 		 */
2297 
2298 		/* Preserve refcount */
2299 		refcount = dc->current_state->refcount;
2300 		/* Preserve display mode lib */
2301 		memcpy(dml, &dc->current_state->bw_ctx.dml, sizeof(struct display_mode_lib));
2302 
2303 		dc_resource_state_destruct(dc->current_state);
2304 		memset(dc->current_state, 0,
2305 				sizeof(*dc->current_state));
2306 
2307 		dc->current_state->refcount = refcount;
2308 		dc->current_state->bw_ctx.dml = *dml;
2309 
2310 		break;
2311 	}
2312 
2313 	kfree(dml);
2314 }
2315 
dc_resume(struct dc * dc)2316 void dc_resume(struct dc *dc)
2317 {
2318 
2319 	uint32_t i;
2320 
2321 	for (i = 0; i < dc->link_count; i++)
2322 		core_link_resume(dc->links[i]);
2323 }
2324 
dc_get_current_backlight_pwm(struct dc * dc)2325 unsigned int dc_get_current_backlight_pwm(struct dc *dc)
2326 {
2327 	struct abm *abm = dc->res_pool->abm;
2328 
2329 	if (abm)
2330 		return abm->funcs->get_current_backlight(abm);
2331 
2332 	return 0;
2333 }
2334 
dc_get_target_backlight_pwm(struct dc * dc)2335 unsigned int dc_get_target_backlight_pwm(struct dc *dc)
2336 {
2337 	struct abm *abm = dc->res_pool->abm;
2338 
2339 	if (abm)
2340 		return abm->funcs->get_target_backlight(abm);
2341 
2342 	return 0;
2343 }
2344 
dc_is_dmcu_initialized(struct dc * dc)2345 bool dc_is_dmcu_initialized(struct dc *dc)
2346 {
2347 	struct dmcu *dmcu = dc->res_pool->dmcu;
2348 
2349 	if (dmcu)
2350 		return dmcu->funcs->is_dmcu_initialized(dmcu);
2351 	return false;
2352 }
2353 
dc_submit_i2c(struct dc * dc,uint32_t link_index,struct i2c_command * cmd)2354 bool dc_submit_i2c(
2355 		struct dc *dc,
2356 		uint32_t link_index,
2357 		struct i2c_command *cmd)
2358 {
2359 
2360 	struct dc_link *link = dc->links[link_index];
2361 	struct ddc_service *ddc = link->ddc;
2362 	return dce_i2c_submit_command(
2363 		dc->res_pool,
2364 		ddc->ddc_pin,
2365 		cmd);
2366 }
2367 
link_add_remote_sink_helper(struct dc_link * dc_link,struct dc_sink * sink)2368 static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
2369 {
2370 	if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
2371 		BREAK_TO_DEBUGGER();
2372 		return false;
2373 	}
2374 
2375 	dc_sink_retain(sink);
2376 
2377 	dc_link->remote_sinks[dc_link->sink_count] = sink;
2378 	dc_link->sink_count++;
2379 
2380 	return true;
2381 }
2382 
2383 /**
2384  * dc_link_add_remote_sink() - Create a sink and attach it to an existing link
2385  *
2386  * EDID length is in bytes
2387  */
dc_link_add_remote_sink(struct dc_link * link,const uint8_t * edid,int len,struct dc_sink_init_data * init_data)2388 struct dc_sink *dc_link_add_remote_sink(
2389 		struct dc_link *link,
2390 		const uint8_t *edid,
2391 		int len,
2392 		struct dc_sink_init_data *init_data)
2393 {
2394 	struct dc_sink *dc_sink;
2395 	enum dc_edid_status edid_status;
2396 
2397 	if (len > DC_MAX_EDID_BUFFER_SIZE) {
2398 		dm_error("Max EDID buffer size breached!\n");
2399 		return NULL;
2400 	}
2401 
2402 	if (!init_data) {
2403 		BREAK_TO_DEBUGGER();
2404 		return NULL;
2405 	}
2406 
2407 	if (!init_data->link) {
2408 		BREAK_TO_DEBUGGER();
2409 		return NULL;
2410 	}
2411 
2412 	dc_sink = dc_sink_create(init_data);
2413 
2414 	if (!dc_sink)
2415 		return NULL;
2416 
2417 	memmove(dc_sink->dc_edid.raw_edid, edid, len);
2418 	dc_sink->dc_edid.length = len;
2419 
2420 	if (!link_add_remote_sink_helper(
2421 			link,
2422 			dc_sink))
2423 		goto fail_add_sink;
2424 
2425 	edid_status = dm_helpers_parse_edid_caps(
2426 			link->ctx,
2427 			&dc_sink->dc_edid,
2428 			&dc_sink->edid_caps);
2429 
2430 	/*
2431 	 * Treat device as no EDID device if EDID
2432 	 * parsing fails
2433 	 */
2434 	if (edid_status != EDID_OK) {
2435 		dc_sink->dc_edid.length = 0;
2436 		dm_error("Bad EDID, status%d!\n", edid_status);
2437 	}
2438 
2439 	return dc_sink;
2440 
2441 fail_add_sink:
2442 	dc_sink_release(dc_sink);
2443 	return NULL;
2444 }
2445 
2446 /**
2447  * dc_link_remove_remote_sink() - Remove a remote sink from a dc_link
2448  *
2449  * Note that this just removes the struct dc_sink - it doesn't
2450  * program hardware or alter other members of dc_link
2451  */
dc_link_remove_remote_sink(struct dc_link * link,struct dc_sink * sink)2452 void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
2453 {
2454 	int i;
2455 
2456 	if (!link->sink_count) {
2457 		BREAK_TO_DEBUGGER();
2458 		return;
2459 	}
2460 
2461 	for (i = 0; i < link->sink_count; i++) {
2462 		if (link->remote_sinks[i] == sink) {
2463 			dc_sink_release(sink);
2464 			link->remote_sinks[i] = NULL;
2465 
2466 			/* shrink array to remove empty place */
2467 			while (i < link->sink_count - 1) {
2468 				link->remote_sinks[i] = link->remote_sinks[i+1];
2469 				i++;
2470 			}
2471 			link->remote_sinks[i] = NULL;
2472 			link->sink_count--;
2473 			return;
2474 		}
2475 	}
2476 }
2477 
get_clock_requirements_for_state(struct dc_state * state,struct AsicStateEx * info)2478 void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info)
2479 {
2480 	info->displayClock				= (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz;
2481 	info->engineClock				= (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_khz;
2482 	info->memoryClock				= (unsigned int)state->bw_ctx.bw.dcn.clk.dramclk_khz;
2483 	info->maxSupportedDppClock		= (unsigned int)state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz;
2484 	info->dppClock					= (unsigned int)state->bw_ctx.bw.dcn.clk.dppclk_khz;
2485 	info->socClock					= (unsigned int)state->bw_ctx.bw.dcn.clk.socclk_khz;
2486 	info->dcfClockDeepSleep			= (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz;
2487 	info->fClock					= (unsigned int)state->bw_ctx.bw.dcn.clk.fclk_khz;
2488 	info->phyClock					= (unsigned int)state->bw_ctx.bw.dcn.clk.phyclk_khz;
2489 }
dc_set_clock(struct dc * dc,enum dc_clock_type clock_type,uint32_t clk_khz,uint32_t stepping)2490 enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping)
2491 {
2492 	if (dc->hwss.set_clock)
2493 		return dc->hwss.set_clock(dc, clock_type, clk_khz, stepping);
2494 	return DC_ERROR_UNEXPECTED;
2495 }
dc_get_clock(struct dc * dc,enum dc_clock_type clock_type,struct dc_clock_config * clock_cfg)2496 void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg)
2497 {
2498 	if (dc->hwss.get_clock)
2499 		dc->hwss.get_clock(dc, clock_type, clock_cfg);
2500 }
2501