Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / gpu / drm / amd / display / dc / core / dc_link_hwss.c
1 /* Copyright 2015 Advanced Micro Devices, Inc. */
2
3
4 #include "dm_services.h"
5 #include "dc.h"
6 #include "inc/core_types.h"
7 #include "include/ddc_service_types.h"
8 #include "include/i2caux_interface.h"
9 #include "link_hwss.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
16 #include "dsc.h"
17 #endif
18 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
19 #include "resource.h"
20 #endif
21
22 enum dc_status core_link_read_dpcd(
23         struct dc_link *link,
24         uint32_t address,
25         uint8_t *data,
26         uint32_t size)
27 {
28         if (!dm_helpers_dp_read_dpcd(link->ctx,
29                         link,
30                         address, data, size))
31                         return DC_ERROR_UNEXPECTED;
32
33         return DC_OK;
34 }
35
36 enum dc_status core_link_write_dpcd(
37         struct dc_link *link,
38         uint32_t address,
39         const uint8_t *data,
40         uint32_t size)
41 {
42         if (!dm_helpers_dp_write_dpcd(link->ctx,
43                         link,
44                         address, data, size))
45                                 return DC_ERROR_UNEXPECTED;
46
47         return DC_OK;
48 }
49
50 void dp_receiver_power_ctrl(struct dc_link *link, bool on)
51 {
52         uint8_t state;
53
54         state = on ? DP_POWER_STATE_D0 : DP_POWER_STATE_D3;
55
56         core_link_write_dpcd(link, DP_SET_POWER, &state,
57                         sizeof(state));
58 }
59
60 void dp_enable_link_phy(
61         struct dc_link *link,
62         enum signal_type signal,
63         enum clock_source_id clock_source,
64         const struct dc_link_settings *link_settings)
65 {
66         struct link_encoder *link_enc = link->link_enc;
67         struct dc  *core_dc = link->ctx->dc;
68         struct dmcu *dmcu = core_dc->res_pool->dmcu;
69
70         struct pipe_ctx *pipes =
71                         link->dc->current_state->res_ctx.pipe_ctx;
72         struct clock_source *dp_cs =
73                         link->dc->res_pool->dp_clock_source;
74         unsigned int i;
75         /* If the current pixel clock source is not DTO(happens after
76          * switching from HDMI passive dongle to DP on the same connector),
77          * switch the pixel clock source to DTO.
78          */
79         for (i = 0; i < MAX_PIPES; i++) {
80                 if (pipes[i].stream != NULL &&
81                         pipes[i].stream->link == link) {
82                         if (pipes[i].clock_source != NULL &&
83                                         pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
84                                 pipes[i].clock_source = dp_cs;
85                                 pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
86                                                 pipes[i].stream->timing.pix_clk_100hz;
87                                 pipes[i].clock_source->funcs->program_pix_clk(
88                                                         pipes[i].clock_source,
89                                                         &pipes[i].stream_res.pix_clk_params,
90                                                         &pipes[i].pll_settings);
91                         }
92                 }
93         }
94
95         if (dmcu != NULL && dmcu->funcs->lock_phy)
96                 dmcu->funcs->lock_phy(dmcu);
97
98         if (dc_is_dp_sst_signal(signal)) {
99                 link_enc->funcs->enable_dp_output(
100                                                 link_enc,
101                                                 link_settings,
102                                                 clock_source);
103         } else {
104                 link_enc->funcs->enable_dp_mst_output(
105                                                 link_enc,
106                                                 link_settings,
107                                                 clock_source);
108         }
109
110         if (dmcu != NULL && dmcu->funcs->unlock_phy)
111                 dmcu->funcs->unlock_phy(dmcu);
112
113         link->cur_link_settings = *link_settings;
114
115         dp_receiver_power_ctrl(link, true);
116 }
117
118 bool edp_receiver_ready_T9(struct dc_link *link)
119 {
120         unsigned int tries = 0;
121         unsigned char sinkstatus = 0;
122         unsigned char edpRev = 0;
123         enum dc_status result = DC_OK;
124         result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
125         if (edpRev < DP_EDP_12)
126                 return true;
127         /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
128         do {
129                 sinkstatus = 1;
130                 result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
131                 if (sinkstatus == 0)
132                         break;
133                 if (result != DC_OK)
134                         break;
135                 udelay(100); //MAx T9
136         } while (++tries < 50);
137
138         if (link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off > 0)
139                 udelay(link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off * 1000);
140
141         return result;
142 }
143 bool edp_receiver_ready_T7(struct dc_link *link)
144 {
145         unsigned int tries = 0;
146         unsigned char sinkstatus = 0;
147         unsigned char edpRev = 0;
148         enum dc_status result = DC_OK;
149
150         result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
151         if (result == DC_OK && edpRev < DP_EDP_12)
152                 return true;
153         /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
154         do {
155                 sinkstatus = 0;
156                 result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
157                 if (sinkstatus == 1)
158                         break;
159                 if (result != DC_OK)
160                         break;
161                 udelay(25); //MAx T7 is 50ms
162         } while (++tries < 300);
163
164         if (link->local_sink->edid_caps.panel_patch.extra_t7_ms > 0)
165                 udelay(link->local_sink->edid_caps.panel_patch.extra_t7_ms * 1000);
166
167         return result;
168 }
169
170 void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
171 {
172         struct dc  *core_dc = link->ctx->dc;
173         struct dmcu *dmcu = core_dc->res_pool->dmcu;
174
175         if (!link->wa_flags.dp_keep_receiver_powered)
176                 dp_receiver_power_ctrl(link, false);
177
178         if (signal == SIGNAL_TYPE_EDP) {
179                 link->link_enc->funcs->disable_output(link->link_enc, signal);
180                 link->dc->hwss.edp_power_control(link, false);
181         } else {
182                 if (dmcu != NULL && dmcu->funcs->lock_phy)
183                         dmcu->funcs->lock_phy(dmcu);
184
185                 link->link_enc->funcs->disable_output(link->link_enc, signal);
186
187                 if (dmcu != NULL && dmcu->funcs->unlock_phy)
188                         dmcu->funcs->unlock_phy(dmcu);
189         }
190
191         /* Clear current link setting.*/
192         memset(&link->cur_link_settings, 0,
193                         sizeof(link->cur_link_settings));
194 }
195
196 void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal)
197 {
198         /* MST disable link only when no stream use the link */
199         if (link->mst_stream_alloc_table.stream_count > 0)
200                 return;
201
202         dp_disable_link_phy(link, signal);
203
204         /* set the sink to SST mode after disabling the link */
205         dp_enable_mst_on_sink(link, false);
206 }
207
208 bool dp_set_hw_training_pattern(
209         struct dc_link *link,
210         enum hw_dp_training_pattern pattern)
211 {
212         enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
213
214         switch (pattern) {
215         case HW_DP_TRAINING_PATTERN_1:
216                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
217                 break;
218         case HW_DP_TRAINING_PATTERN_2:
219                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
220                 break;
221         case HW_DP_TRAINING_PATTERN_3:
222                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
223                 break;
224         case HW_DP_TRAINING_PATTERN_4:
225                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
226                 break;
227         default:
228                 break;
229         }
230
231         dp_set_hw_test_pattern(link, test_pattern, NULL, 0);
232
233         return true;
234 }
235
236 void dp_set_hw_lane_settings(
237         struct dc_link *link,
238         const struct link_training_settings *link_settings)
239 {
240         struct link_encoder *encoder = link->link_enc;
241
242         /* call Encoder to set lane settings */
243         encoder->funcs->dp_set_lane_settings(encoder, link_settings);
244 }
245
246 enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
247 {
248         /* We need to explicitly check that connector
249          * is not DP. Some Travis_VGA get reported
250          * by video bios as DP.
251          */
252         if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
253
254                 switch (link->dpcd_caps.branch_dev_id) {
255                 case DP_BRANCH_DEVICE_ID_2:
256                         if (strncmp(
257                                 link->dpcd_caps.branch_dev_name,
258                                 DP_VGA_LVDS_CONVERTER_ID_2,
259                                 sizeof(
260                                 link->dpcd_caps.
261                                 branch_dev_name)) == 0) {
262                                 return DP_PANEL_MODE_SPECIAL;
263                         }
264                         break;
265                 case DP_BRANCH_DEVICE_ID_3:
266                         if (strncmp(link->dpcd_caps.branch_dev_name,
267                                 DP_VGA_LVDS_CONVERTER_ID_3,
268                                 sizeof(
269                                 link->dpcd_caps.
270                                 branch_dev_name)) == 0) {
271                                 return DP_PANEL_MODE_SPECIAL;
272                         }
273                         break;
274                 default:
275                         break;
276                 }
277         }
278
279         if (link->dpcd_caps.panel_mode_edp) {
280                 return DP_PANEL_MODE_EDP;
281         }
282
283         return DP_PANEL_MODE_DEFAULT;
284 }
285
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)
291 {
292         struct encoder_set_dp_phy_pattern_param pattern_param = {0};
293         struct link_encoder *encoder = link->link_enc;
294
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);
299
300         encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param);
301 }
302
303 void dp_retrain_link_dp_test(struct dc_link *link,
304                         struct dc_link_settings *link_setting,
305                         bool skip_video_pattern)
306 {
307         struct pipe_ctx *pipes =
308                         &link->dc->current_state->res_ctx.pipe_ctx[0];
309         unsigned int i;
310
311         for (i = 0; i < MAX_PIPES; i++) {
312                 if (pipes[i].stream != NULL &&
313                         !pipes[i].top_pipe &&
314                         pipes[i].stream->link != NULL &&
315                         pipes[i].stream_res.stream_enc != NULL) {
316                         udelay(100);
317
318                         pipes[i].stream_res.stream_enc->funcs->dp_blank(
319                                         pipes[i].stream_res.stream_enc);
320
321                         /* disable any test pattern that might be active */
322                         dp_set_hw_test_pattern(link,
323                                         DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
324
325                         dp_receiver_power_ctrl(link, false);
326
327                         link->dc->hwss.disable_stream(&pipes[i], KEEP_ACQUIRED_RESOURCE);
328
329                         link->link_enc->funcs->disable_output(
330                                         link->link_enc,
331                                         SIGNAL_TYPE_DISPLAY_PORT);
332
333                         /* Clear current link setting. */
334                         memset(&link->cur_link_settings, 0,
335                                 sizeof(link->cur_link_settings));
336
337                         link->link_enc->funcs->enable_dp_output(
338                                                 link->link_enc,
339                                                 link_setting,
340                                                 pipes[i].clock_source->id);
341                         link->cur_link_settings = *link_setting;
342
343                         dp_receiver_power_ctrl(link, true);
344
345                         perform_link_training_with_retries(
346                                         link,
347                                         link_setting,
348                                         skip_video_pattern,
349                                         LINK_TRAINING_ATTEMPTS);
350
351
352                         link->dc->hwss.enable_stream(&pipes[i]);
353
354                         link->dc->hwss.unblank_stream(&pipes[i],
355                                         link_setting);
356
357                         if (pipes[i].stream_res.audio) {
358                                 /* notify audio driver for
359                                  * audio modes of monitor */
360                                 pipes[i].stream_res.audio->funcs->az_enable(
361                                                 pipes[i].stream_res.audio);
362
363                                 /* un-mute audio */
364                                 /* TODO: audio should be per stream rather than
365                                  * per link */
366                                 pipes[i].stream_res.stream_enc->funcs->
367                                 audio_mute_control(
368                                         pipes[i].stream_res.stream_enc, false);
369                         }
370                 }
371         }
372 }
373
374 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
375 #define DC_LOGGER \
376         dsc->ctx->logger
377 static void dsc_optc_config_log(struct display_stream_compressor *dsc,
378                 struct dsc_optc_config *config)
379 {
380         DC_LOG_DSC("Setting optc DSC config at DSC inst %d", dsc->inst);
381         DC_LOG_DSC("\n\tbytes_per_pixel %d\n\tis_pixel_format_444 %d\n\tslice_width %d",
382                         config->bytes_per_pixel,
383                         config->is_pixel_format_444, config->slice_width);
384 }
385
386 static bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
387 {
388         struct dc *core_dc = pipe_ctx->stream->ctx->dc;
389         struct dc_stream_state *stream = pipe_ctx->stream;
390         bool result = false;
391
392         if (IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment))
393                 result = true;
394         else
395                 result = dm_helpers_dp_write_dsc_enable(core_dc->ctx, stream, enable);
396         return result;
397 }
398
399 /* This has to be done after DSC was enabled on RX first, i.e. after dp_enable_dsc_on_rx() had been called
400  */
401 static void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
402 {
403         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
404         struct dc *core_dc = pipe_ctx->stream->ctx->dc;
405         struct dc_stream_state *stream = pipe_ctx->stream;
406         struct pipe_ctx *odm_pipe = dc_res_get_odm_bottom_pipe(pipe_ctx);
407
408         if (enable) {
409                 /* TODO proper function */
410                 struct dsc_config dsc_cfg;
411                 struct dsc_optc_config dsc_optc_cfg;
412                 enum optc_dsc_mode optc_dsc_mode;
413                 uint8_t dsc_packed_pps[128];
414
415                 /* Enable DSC hw block */
416                 dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
417                 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
418                 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
419                 dsc_cfg.color_depth = stream->timing.display_color_depth;
420                 dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
421
422                 dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg, &dsc_packed_pps[0]);
423                 if (odm_pipe) {
424                         struct display_stream_compressor *bot_dsc = odm_pipe->stream_res.dsc;
425                         uint8_t dsc_packed_pps_odm[128];
426
427                         dsc_cfg.pic_width /= 2;
428                         ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % 2 == 0);
429                         dsc_cfg.dc_dsc_cfg.num_slices_h /= 2;
430                         dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg, &dsc_packed_pps_odm[0]);
431                         bot_dsc->funcs->dsc_set_config(bot_dsc, &dsc_cfg, &dsc_optc_cfg, &dsc_packed_pps_odm[0]);
432                         bot_dsc->funcs->dsc_enable(bot_dsc, odm_pipe->stream_res.opp->inst);
433                 }
434                 dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
435
436                 optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
437
438                 dsc_optc_config_log(dsc, &dsc_optc_cfg);
439                 /* Enable DSC in encoder */
440                 if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment) && pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config)
441                         pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
442                                                                         optc_dsc_mode,
443                                                                         dsc_optc_cfg.bytes_per_pixel,
444                                                                         dsc_optc_cfg.slice_width,
445                                                                         &dsc_packed_pps[0]);
446
447                 /* Enable DSC in OPTC */
448                 pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
449                                                         optc_dsc_mode,
450                                                         dsc_optc_cfg.bytes_per_pixel,
451                                                         dsc_optc_cfg.slice_width);
452         } else {
453                 /* disable DSC in OPTC */
454                 pipe_ctx->stream_res.tg->funcs->set_dsc_config(
455                                 pipe_ctx->stream_res.tg,
456                                 OPTC_DSC_DISABLED, 0, 0);
457
458                 /* disable DSC in stream encoder */
459                 if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
460                         pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
461                                         pipe_ctx->stream_res.stream_enc,
462                                         OPTC_DSC_DISABLED, 0, 0, NULL);
463                 }
464
465                 /* disable DSC block */
466                 pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
467                 if (odm_pipe)
468                         odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
469         }
470 }
471
472 bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
473 {
474         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
475         bool result = false;
476
477         if (!pipe_ctx->stream->timing.flags.DSC)
478                 goto out;
479         if (!dsc)
480                 goto out;
481
482         if (enable) {
483                 if (dp_set_dsc_on_rx(pipe_ctx, true)) {
484                         dp_set_dsc_on_stream(pipe_ctx, true);
485                         result = true;
486                 }
487         } else {
488                 dp_set_dsc_on_rx(pipe_ctx, false);
489                 dp_set_dsc_on_stream(pipe_ctx, false);
490                 result = true;
491         }
492 out:
493         return result;
494 }
495
496 bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
497 {
498         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
499
500         if (!pipe_ctx->stream->timing.flags.DSC)
501                 return false;
502         if (!dsc)
503                 return false;
504
505         dp_set_dsc_on_stream(pipe_ctx, true);
506         return true;
507 }
508
509 #endif
510