1 /* Copyright 2015 Advanced Micro Devices, Inc. */
4 #include "dm_services.h"
6 #include "inc/core_types.h"
7 #include "include/ddc_service_types.h"
8 #include "include/i2caux_interface.h"
10 #include "hw_sequencer.h"
11 #include "dc_link_dp.h"
12 #include "dc_link_ddc.h"
13 #include "dm_helpers.h"
14 #include "dpcd_defs.h"
15 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
18 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
22 static uint8_t convert_to_count(uint8_t lttpr_repeater_count)
24 switch (lttpr_repeater_count) {
25 case 0x80: // 1 lttpr repeater
27 case 0x40: // 2 lttpr repeaters
29 case 0x20: // 3 lttpr repeaters
31 case 0x10: // 4 lttpr repeaters
33 case 0x08: // 5 lttpr repeaters
35 case 0x04: // 6 lttpr repeaters
37 case 0x02: // 7 lttpr repeaters
39 case 0x01: // 8 lttpr repeaters
44 return 0; // invalid value
47 static inline bool is_immediate_downstream(struct dc_link *link, uint32_t offset)
49 return (convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == offset);
52 enum dc_status core_link_read_dpcd(
58 if (!link->aux_access_disabled &&
59 !dm_helpers_dp_read_dpcd(link->ctx,
60 link, address, data, size)) {
61 return DC_ERROR_UNEXPECTED;
67 enum dc_status core_link_write_dpcd(
73 if (!link->aux_access_disabled &&
74 !dm_helpers_dp_write_dpcd(link->ctx,
75 link, address, data, size)) {
76 return DC_ERROR_UNEXPECTED;
82 void dp_receiver_power_ctrl(struct dc_link *link, bool on)
86 state = on ? DP_POWER_STATE_D0 : DP_POWER_STATE_D3;
88 if (link->sync_lt_in_progress)
91 core_link_write_dpcd(link, DP_SET_POWER, &state,
95 void dp_enable_link_phy(
97 enum signal_type signal,
98 enum clock_source_id clock_source,
99 const struct dc_link_settings *link_settings)
101 struct link_encoder *link_enc = link->link_enc;
102 struct dc *core_dc = link->ctx->dc;
103 struct dmcu *dmcu = core_dc->res_pool->dmcu;
105 struct pipe_ctx *pipes =
106 link->dc->current_state->res_ctx.pipe_ctx;
107 struct clock_source *dp_cs =
108 link->dc->res_pool->dp_clock_source;
110 /* If the current pixel clock source is not DTO(happens after
111 * switching from HDMI passive dongle to DP on the same connector),
112 * switch the pixel clock source to DTO.
114 for (i = 0; i < MAX_PIPES; i++) {
115 if (pipes[i].stream != NULL &&
116 pipes[i].stream->link == link) {
117 if (pipes[i].clock_source != NULL &&
118 pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
119 pipes[i].clock_source = dp_cs;
120 pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
121 pipes[i].stream->timing.pix_clk_100hz;
122 pipes[i].clock_source->funcs->program_pix_clk(
123 pipes[i].clock_source,
124 &pipes[i].stream_res.pix_clk_params,
125 &pipes[i].pll_settings);
130 if (dmcu != NULL && dmcu->funcs->lock_phy)
131 dmcu->funcs->lock_phy(dmcu);
133 if (dc_is_dp_sst_signal(signal)) {
134 link_enc->funcs->enable_dp_output(
139 link_enc->funcs->enable_dp_mst_output(
145 if (dmcu != NULL && dmcu->funcs->unlock_phy)
146 dmcu->funcs->unlock_phy(dmcu);
148 link->cur_link_settings = *link_settings;
150 dp_receiver_power_ctrl(link, true);
153 bool edp_receiver_ready_T9(struct dc_link *link)
155 unsigned int tries = 0;
156 unsigned char sinkstatus = 0;
157 unsigned char edpRev = 0;
158 enum dc_status result = DC_OK;
159 result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
160 if (edpRev < DP_EDP_12)
162 /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
165 result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
170 udelay(100); //MAx T9
171 } while (++tries < 50);
173 if (link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off > 0)
174 udelay(link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off * 1000);
178 bool edp_receiver_ready_T7(struct dc_link *link)
180 unsigned int tries = 0;
181 unsigned char sinkstatus = 0;
182 unsigned char edpRev = 0;
183 enum dc_status result = DC_OK;
185 result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
186 if (result == DC_OK && edpRev < DP_EDP_12)
188 /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
191 result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
196 udelay(25); //MAx T7 is 50ms
197 } while (++tries < 300);
199 if (link->local_sink->edid_caps.panel_patch.extra_t7_ms > 0)
200 udelay(link->local_sink->edid_caps.panel_patch.extra_t7_ms * 1000);
205 void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
207 struct dc *core_dc = link->ctx->dc;
208 struct dmcu *dmcu = core_dc->res_pool->dmcu;
210 if (!link->wa_flags.dp_keep_receiver_powered)
211 dp_receiver_power_ctrl(link, false);
213 if (signal == SIGNAL_TYPE_EDP) {
214 link->link_enc->funcs->disable_output(link->link_enc, signal);
215 link->dc->hwss.edp_power_control(link, false);
217 if (dmcu != NULL && dmcu->funcs->lock_phy)
218 dmcu->funcs->lock_phy(dmcu);
220 link->link_enc->funcs->disable_output(link->link_enc, signal);
222 if (dmcu != NULL && dmcu->funcs->unlock_phy)
223 dmcu->funcs->unlock_phy(dmcu);
226 /* Clear current link setting.*/
227 memset(&link->cur_link_settings, 0,
228 sizeof(link->cur_link_settings));
231 void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal)
233 /* MST disable link only when no stream use the link */
234 if (link->mst_stream_alloc_table.stream_count > 0)
237 dp_disable_link_phy(link, signal);
239 /* set the sink to SST mode after disabling the link */
240 dp_enable_mst_on_sink(link, false);
243 bool dp_set_hw_training_pattern(
244 struct dc_link *link,
245 enum dc_dp_training_pattern pattern,
248 enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
251 case DP_TRAINING_PATTERN_SEQUENCE_1:
252 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
254 case DP_TRAINING_PATTERN_SEQUENCE_2:
255 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
257 case DP_TRAINING_PATTERN_SEQUENCE_3:
258 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
260 case DP_TRAINING_PATTERN_SEQUENCE_4:
261 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
267 dp_set_hw_test_pattern(link, test_pattern, NULL, 0);
272 void dp_set_hw_lane_settings(
273 struct dc_link *link,
274 const struct link_training_settings *link_settings,
277 struct link_encoder *encoder = link->link_enc;
279 if (!link->is_lttpr_mode_transparent && !is_immediate_downstream(link, offset))
282 /* call Encoder to set lane settings */
283 encoder->funcs->dp_set_lane_settings(encoder, link_settings);
286 void dp_set_hw_test_pattern(
287 struct dc_link *link,
288 enum dp_test_pattern test_pattern,
289 uint8_t *custom_pattern,
290 uint32_t custom_pattern_size)
292 struct encoder_set_dp_phy_pattern_param pattern_param = {0};
293 struct link_encoder *encoder = link->link_enc;
295 pattern_param.dp_phy_pattern = test_pattern;
296 pattern_param.custom_pattern = custom_pattern;
297 pattern_param.custom_pattern_size = custom_pattern_size;
298 pattern_param.dp_panel_mode = dp_get_panel_mode(link);
300 encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param);
303 void dp_retrain_link_dp_test(struct dc_link *link,
304 struct dc_link_settings *link_setting,
305 bool skip_video_pattern)
307 struct pipe_ctx *pipes =
308 &link->dc->current_state->res_ctx.pipe_ctx[0];
311 for (i = 0; i < MAX_PIPES; i++) {
312 if (pipes[i].stream != NULL &&
313 !pipes[i].top_pipe && !pipes[i].prev_odm_pipe &&
314 pipes[i].stream->link != NULL &&
315 pipes[i].stream_res.stream_enc != NULL &&
316 pipes[i].stream->link == link) {
319 pipes[i].stream_res.stream_enc->funcs->dp_blank(
320 pipes[i].stream_res.stream_enc);
322 /* disable any test pattern that might be active */
323 dp_set_hw_test_pattern(link,
324 DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
326 dp_receiver_power_ctrl(link, false);
328 link->dc->hwss.disable_stream(&pipes[i]);
329 if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only)
330 (&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio);
332 link->link_enc->funcs->disable_output(
334 SIGNAL_TYPE_DISPLAY_PORT);
336 /* Clear current link setting. */
337 memset(&link->cur_link_settings, 0,
338 sizeof(link->cur_link_settings));
340 link->link_enc->funcs->enable_dp_output(
343 pipes[i].clock_source->id);
344 link->cur_link_settings = *link_setting;
346 dp_receiver_power_ctrl(link, true);
348 perform_link_training_with_retries(
352 LINK_TRAINING_ATTEMPTS);
355 link->dc->hwss.enable_stream(&pipes[i]);
357 link->dc->hwss.unblank_stream(&pipes[i],
360 if (pipes[i].stream_res.audio) {
361 /* notify audio driver for
362 * audio modes of monitor */
363 pipes[i].stream_res.audio->funcs->az_enable(
364 pipes[i].stream_res.audio);
367 /* TODO: audio should be per stream rather than
369 pipes[i].stream_res.stream_enc->funcs->
371 pipes[i].stream_res.stream_enc, false);
377 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
380 static void dsc_optc_config_log(struct display_stream_compressor *dsc,
381 struct dsc_optc_config *config)
383 uint32_t precision = 1 << 28;
384 uint32_t bytes_per_pixel_int = config->bytes_per_pixel / precision;
385 uint32_t bytes_per_pixel_mod = config->bytes_per_pixel % precision;
386 uint64_t ll_bytes_per_pix_fraq = bytes_per_pixel_mod;
388 /* 7 fractional digits decimal precision for bytes per pixel is enough because DSC
389 * bits per pixel precision is 1/16th of a pixel, which means bytes per pixel precision is
390 * 1/16/8 = 1/128 of a byte, or 0.0078125 decimal
392 ll_bytes_per_pix_fraq *= 10000000;
393 ll_bytes_per_pix_fraq /= precision;
395 DC_LOG_DSC("\tbytes_per_pixel 0x%08x (%d.%07d)",
396 config->bytes_per_pixel, bytes_per_pixel_int, (uint32_t)ll_bytes_per_pix_fraq);
397 DC_LOG_DSC("\tis_pixel_format_444 %d", config->is_pixel_format_444);
398 DC_LOG_DSC("\tslice_width %d", config->slice_width);
401 static bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
403 struct dc *core_dc = pipe_ctx->stream->ctx->dc;
404 struct dc_stream_state *stream = pipe_ctx->stream;
407 if (IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment))
410 result = dm_helpers_dp_write_dsc_enable(core_dc->ctx, stream, enable);
414 /* The stream with these settings can be sent (unblanked) only after DSC was enabled on RX first,
415 * i.e. after dp_enable_dsc_on_rx() had been called
417 void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
419 struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
420 struct dc *core_dc = pipe_ctx->stream->ctx->dc;
421 struct dc_stream_state *stream = pipe_ctx->stream;
422 struct pipe_ctx *odm_pipe;
425 for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
429 struct dsc_config dsc_cfg;
430 struct dsc_optc_config dsc_optc_cfg;
431 enum optc_dsc_mode optc_dsc_mode;
433 /* Enable DSC hw block */
434 dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
435 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
436 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
437 dsc_cfg.color_depth = stream->timing.display_color_depth;
438 dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
439 ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
440 dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
442 dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
443 dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
444 for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
445 struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
447 odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
448 odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
450 dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
451 dsc_cfg.pic_width *= opp_cnt;
453 optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
455 /* Enable DSC in encoder */
456 if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
457 DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id);
458 dsc_optc_config_log(dsc, &dsc_optc_cfg);
459 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
461 dsc_optc_cfg.bytes_per_pixel,
462 dsc_optc_cfg.slice_width);
464 /* PPS SDP is set elsewhere because it has to be done after DIG FE is connected to DIG BE */
467 /* Enable DSC in OPTC */
468 DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
469 dsc_optc_config_log(dsc, &dsc_optc_cfg);
470 pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
472 dsc_optc_cfg.bytes_per_pixel,
473 dsc_optc_cfg.slice_width);
475 /* disable DSC in OPTC */
476 pipe_ctx->stream_res.tg->funcs->set_dsc_config(
477 pipe_ctx->stream_res.tg,
478 OPTC_DSC_DISABLED, 0, 0);
480 /* disable DSC in stream encoder */
481 if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
482 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
483 pipe_ctx->stream_res.stream_enc,
484 OPTC_DSC_DISABLED, 0, 0);
486 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
487 pipe_ctx->stream_res.stream_enc, false, NULL);
490 /* disable DSC block */
491 pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
492 for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
493 odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
497 bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
499 struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
502 if (!pipe_ctx->stream->timing.flags.DSC)
508 if (dp_set_dsc_on_rx(pipe_ctx, true)) {
509 dp_set_dsc_on_stream(pipe_ctx, true);
513 dp_set_dsc_on_rx(pipe_ctx, false);
514 dp_set_dsc_on_stream(pipe_ctx, false);
521 bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable)
523 struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
524 struct dc *core_dc = pipe_ctx->stream->ctx->dc;
525 struct dc_stream_state *stream = pipe_ctx->stream;
527 if (!pipe_ctx->stream->timing.flags.DSC || !dsc)
531 struct dsc_config dsc_cfg;
532 uint8_t dsc_packed_pps[128];
534 /* Enable DSC hw block */
535 dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
536 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
537 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
538 dsc_cfg.color_depth = stream->timing.display_color_depth;
539 dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
542 dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
543 if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
544 DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id);
545 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
546 pipe_ctx->stream_res.stream_enc,
551 /* disable DSC PPS in stream encoder */
552 if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
553 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
554 pipe_ctx->stream_res.stream_enc, false, NULL);
562 bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
564 struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
566 if (!pipe_ctx->stream->timing.flags.DSC)
571 dp_set_dsc_on_stream(pipe_ctx, true);
572 dp_set_dsc_pps_sdp(pipe_ctx, true);