1 /*
2 * Copyright 2022 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26 /* FILE POLICY AND INTENDED USAGE:
27 * This file implements retrieval and configuration of eDP panel features such
28 * as PSR and ABM and it also manages specs defined eDP panel power sequences.
29 */
30
31 #include "link_edp_panel_control.h"
32 #include "link_dpcd.h"
33 #include "link_dp_capability.h"
34 #include "dm_helpers.h"
35 #include "dal_asic_id.h"
36 #include "link_dp_phy.h"
37 #include "dce/dmub_psr.h"
38 #include "dc/dc_dmub_srv.h"
39 #include "dce/dmub_replay.h"
40 #include "abm.h"
41 #define DC_LOGGER_INIT(logger)
42
43 #define DP_SINK_PR_ENABLE_AND_CONFIGURATION 0x37B
44
45 /* Travis */
46 static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT";
47 /* Nutmeg */
48 static const uint8_t DP_VGA_LVDS_CONVERTER_ID_3[] = "dnomlA";
49
dp_set_panel_mode(struct dc_link * link,enum dp_panel_mode panel_mode)50 void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode)
51 {
52 union dpcd_edp_config edp_config_set;
53 bool panel_mode_edp = false;
54 enum dc_status result;
55
56 memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
57
58 switch (panel_mode) {
59 case DP_PANEL_MODE_EDP:
60 case DP_PANEL_MODE_SPECIAL:
61 panel_mode_edp = true;
62 break;
63
64 default:
65 break;
66 }
67
68 /*set edp panel mode in receiver*/
69 result = core_link_read_dpcd(
70 link,
71 DP_EDP_CONFIGURATION_SET,
72 &edp_config_set.raw,
73 sizeof(edp_config_set.raw));
74
75 if (result == DC_OK &&
76 edp_config_set.bits.PANEL_MODE_EDP
77 != panel_mode_edp) {
78
79 edp_config_set.bits.PANEL_MODE_EDP =
80 panel_mode_edp;
81 result = core_link_write_dpcd(
82 link,
83 DP_EDP_CONFIGURATION_SET,
84 &edp_config_set.raw,
85 sizeof(edp_config_set.raw));
86
87 ASSERT(result == DC_OK);
88 }
89
90 link->panel_mode = panel_mode;
91 DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
92 "eDP panel mode enabled: %d \n",
93 link->link_index,
94 link->dpcd_caps.panel_mode_edp,
95 panel_mode_edp);
96 }
97
dp_get_panel_mode(struct dc_link * link)98 enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
99 {
100 /* We need to explicitly check that connector
101 * is not DP. Some Travis_VGA get reported
102 * by video bios as DP.
103 */
104 if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
105
106 switch (link->dpcd_caps.branch_dev_id) {
107 case DP_BRANCH_DEVICE_ID_0022B9:
108 /* alternate scrambler reset is required for Travis
109 * for the case when external chip does not
110 * provide sink device id, alternate scrambler
111 * scheme will be overriden later by querying
112 * Encoder features
113 */
114 if (strncmp(
115 link->dpcd_caps.branch_dev_name,
116 DP_VGA_LVDS_CONVERTER_ID_2,
117 sizeof(
118 link->dpcd_caps.
119 branch_dev_name)) == 0) {
120 return DP_PANEL_MODE_SPECIAL;
121 }
122 break;
123 case DP_BRANCH_DEVICE_ID_00001A:
124 /* alternate scrambler reset is required for Travis
125 * for the case when external chip does not provide
126 * sink device id, alternate scrambler scheme will
127 * be overriden later by querying Encoder feature
128 */
129 if (strncmp(link->dpcd_caps.branch_dev_name,
130 DP_VGA_LVDS_CONVERTER_ID_3,
131 sizeof(
132 link->dpcd_caps.
133 branch_dev_name)) == 0) {
134 return DP_PANEL_MODE_SPECIAL;
135 }
136 break;
137 default:
138 break;
139 }
140 }
141
142 if (link->dpcd_caps.panel_mode_edp &&
143 (link->connector_signal == SIGNAL_TYPE_EDP ||
144 (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
145 link->is_internal_display))) {
146 return DP_PANEL_MODE_EDP;
147 }
148
149 return DP_PANEL_MODE_DEFAULT;
150 }
151
edp_set_backlight_level_nits(struct dc_link * link,bool isHDR,uint32_t backlight_millinits,uint32_t transition_time_in_ms)152 bool edp_set_backlight_level_nits(struct dc_link *link,
153 bool isHDR,
154 uint32_t backlight_millinits,
155 uint32_t transition_time_in_ms)
156 {
157 struct dpcd_source_backlight_set dpcd_backlight_set;
158 uint8_t backlight_control = isHDR ? 1 : 0;
159
160 if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
161 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
162 return false;
163
164 // OLEDs have no PWM, they can only use AUX
165 if (link->dpcd_sink_ext_caps.bits.oled == 1)
166 backlight_control = 1;
167
168 *(uint32_t *)&dpcd_backlight_set.backlight_level_millinits = backlight_millinits;
169 *(uint16_t *)&dpcd_backlight_set.backlight_transition_time_ms = (uint16_t)transition_time_in_ms;
170
171
172 if (!link->dpcd_caps.panel_luminance_control) {
173 if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
174 (uint8_t *)(&dpcd_backlight_set),
175 sizeof(dpcd_backlight_set)) != DC_OK)
176 return false;
177
178 if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL,
179 &backlight_control, 1) != DC_OK)
180 return false;
181 } else {
182 const uint8_t backlight_enable = DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE;
183 struct target_luminance_value *target_luminance = NULL;
184
185 //if target luminance value is greater than 24 bits, clip the value to 24 bits
186 if (backlight_millinits > 0xFFFFFF)
187 backlight_millinits = 0xFFFFFF;
188
189 target_luminance = (struct target_luminance_value *)&backlight_millinits;
190
191 if (core_link_write_dpcd(link, DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
192 &backlight_enable,
193 sizeof(backlight_enable)) != DC_OK)
194 return false;
195
196 if (core_link_write_dpcd(link, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE,
197 (uint8_t *)(target_luminance),
198 sizeof(struct target_luminance_value)) != DC_OK)
199 return false;
200 }
201
202 return true;
203 }
204
edp_get_backlight_level_nits(struct dc_link * link,uint32_t * backlight_millinits_avg,uint32_t * backlight_millinits_peak)205 bool edp_get_backlight_level_nits(struct dc_link *link,
206 uint32_t *backlight_millinits_avg,
207 uint32_t *backlight_millinits_peak)
208 {
209 union dpcd_source_backlight_get dpcd_backlight_get;
210
211 memset(&dpcd_backlight_get, 0, sizeof(union dpcd_source_backlight_get));
212
213 if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
214 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
215 return false;
216
217 if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_CURRENT_PEAK,
218 dpcd_backlight_get.raw,
219 sizeof(union dpcd_source_backlight_get)))
220 return false;
221
222 *backlight_millinits_avg =
223 dpcd_backlight_get.bytes.backlight_millinits_avg;
224 *backlight_millinits_peak =
225 dpcd_backlight_get.bytes.backlight_millinits_peak;
226
227 /* On non-supported panels dpcd_read usually succeeds with 0 returned */
228 if (*backlight_millinits_avg == 0 ||
229 *backlight_millinits_avg > *backlight_millinits_peak)
230 return false;
231
232 return true;
233 }
234
edp_backlight_enable_aux(struct dc_link * link,bool enable)235 bool edp_backlight_enable_aux(struct dc_link *link, bool enable)
236 {
237 uint8_t backlight_enable = enable ? 1 : 0;
238
239 if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
240 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
241 return false;
242
243 if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_ENABLE,
244 &backlight_enable, 1) != DC_OK)
245 return false;
246
247 return true;
248 }
249
250 // we read default from 0x320 because we expect BIOS wrote it there
251 // regular get_backlight_nit reads from panel set at 0x326
read_default_bl_aux(struct dc_link * link,uint32_t * backlight_millinits)252 static bool read_default_bl_aux(struct dc_link *link, uint32_t *backlight_millinits)
253 {
254 if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
255 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
256 return false;
257
258 if (!link->dpcd_caps.panel_luminance_control) {
259 if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
260 (uint8_t *)backlight_millinits,
261 sizeof(uint32_t)))
262 return false;
263 } else {
264 //setting to 0 as a precaution, since target_luminance_value is 3 bytes
265 memset(backlight_millinits, 0, sizeof(uint32_t));
266
267 if (!core_link_read_dpcd(link, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE,
268 (uint8_t *)backlight_millinits,
269 sizeof(struct target_luminance_value)))
270 return false;
271 }
272
273 return true;
274 }
275
set_default_brightness_aux(struct dc_link * link)276 bool set_default_brightness_aux(struct dc_link *link)
277 {
278 uint32_t default_backlight;
279
280 if (link && link->dpcd_sink_ext_caps.bits.oled == 1) {
281 if (!read_default_bl_aux(link, &default_backlight))
282 default_backlight = 150000;
283 // if < 1 nits or > 5000, it might be wrong readback
284 if (default_backlight < 1000 || default_backlight > 5000000)
285 default_backlight = 150000;
286
287 return edp_set_backlight_level_nits(link, true,
288 default_backlight, 0);
289 }
290 return false;
291 }
292
edp_is_ilr_optimization_enabled(struct dc_link * link)293 bool edp_is_ilr_optimization_enabled(struct dc_link *link)
294 {
295 if (link->dpcd_caps.edp_supported_link_rates_count == 0 || !link->panel_config.ilr.optimize_edp_link_rate)
296 return false;
297 return true;
298 }
299
get_max_link_rate_from_ilr_table(struct dc_link * link)300 enum dc_link_rate get_max_link_rate_from_ilr_table(struct dc_link *link)
301 {
302 enum dc_link_rate link_rate = link->reported_link_cap.link_rate;
303
304 for (int i = 0; i < link->dpcd_caps.edp_supported_link_rates_count; i++) {
305 if (link_rate < link->dpcd_caps.edp_supported_link_rates[i])
306 link_rate = link->dpcd_caps.edp_supported_link_rates[i];
307 }
308
309 return link_rate;
310 }
311
edp_is_ilr_optimization_required(struct dc_link * link,struct dc_crtc_timing * crtc_timing)312 bool edp_is_ilr_optimization_required(struct dc_link *link,
313 struct dc_crtc_timing *crtc_timing)
314 {
315 struct dc_link_settings link_setting;
316 uint8_t link_bw_set;
317 uint8_t link_rate_set;
318 uint32_t req_bw;
319 union lane_count_set lane_count_set = {0};
320
321 ASSERT(link || crtc_timing); // invalid input
322
323 if (!edp_is_ilr_optimization_enabled(link))
324 return false;
325
326
327 // Read DPCD 00100h to find if standard link rates are set
328 core_link_read_dpcd(link, DP_LINK_BW_SET,
329 &link_bw_set, sizeof(link_bw_set));
330
331 if (link_bw_set) {
332 DC_LOG_EVENT_LINK_TRAINING("eDP ILR: Optimization required, VBIOS used link_bw_set\n");
333 return true;
334 }
335
336 // Read DPCD 00115h to find the edp link rate set used
337 core_link_read_dpcd(link, DP_LINK_RATE_SET,
338 &link_rate_set, sizeof(link_rate_set));
339
340 // Read DPCD 00101h to find out the number of lanes currently set
341 core_link_read_dpcd(link, DP_LANE_COUNT_SET,
342 &lane_count_set.raw, sizeof(lane_count_set));
343
344 req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing, dc_link_get_highest_encoding_format(link));
345
346 if (!crtc_timing->flags.DSC)
347 edp_decide_link_settings(link, &link_setting, req_bw);
348 else
349 decide_edp_link_settings_with_dsc(link, &link_setting, req_bw, LINK_RATE_UNKNOWN);
350
351 if (link->dpcd_caps.edp_supported_link_rates[link_rate_set] != link_setting.link_rate ||
352 lane_count_set.bits.LANE_COUNT_SET != link_setting.lane_count) {
353 DC_LOG_EVENT_LINK_TRAINING("eDP ILR: Optimization required, VBIOS link_rate_set not optimal\n");
354 return true;
355 }
356
357 DC_LOG_EVENT_LINK_TRAINING("eDP ILR: No optimization required, VBIOS set optimal link_rate_set\n");
358 return false;
359 }
360
edp_panel_backlight_power_on(struct dc_link * link,bool wait_for_hpd)361 void edp_panel_backlight_power_on(struct dc_link *link, bool wait_for_hpd)
362 {
363 if (link->connector_signal != SIGNAL_TYPE_EDP)
364 return;
365
366 link->dc->hwss.edp_power_control(link, true);
367 if (wait_for_hpd)
368 link->dc->hwss.edp_wait_for_hpd_ready(link, true);
369 if (link->dc->hwss.edp_backlight_control)
370 link->dc->hwss.edp_backlight_control(link, true);
371 }
372
edp_set_panel_power(struct dc_link * link,bool powerOn)373 void edp_set_panel_power(struct dc_link *link, bool powerOn)
374 {
375 if (powerOn) {
376 // 1. panel VDD on
377 if (!link->dc->config.edp_no_power_sequencing)
378 link->dc->hwss.edp_power_control(link, true);
379 link->dc->hwss.edp_wait_for_hpd_ready(link, true);
380
381 // 2. panel BL on
382 if (link->dc->hwss.edp_backlight_control)
383 link->dc->hwss.edp_backlight_control(link, true);
384
385 // 3. Rx power on
386 dpcd_write_rx_power_ctrl(link, true);
387 } else {
388 // 3. Rx power off
389 dpcd_write_rx_power_ctrl(link, false);
390
391 // 2. panel BL off
392 if (link->dc->hwss.edp_backlight_control)
393 link->dc->hwss.edp_backlight_control(link, false);
394
395 // 1. panel VDD off
396 if (!link->dc->config.edp_no_power_sequencing)
397 link->dc->hwss.edp_power_control(link, false);
398 }
399 }
400
edp_wait_for_t12(struct dc_link * link)401 bool edp_wait_for_t12(struct dc_link *link)
402 {
403 if (link->connector_signal == SIGNAL_TYPE_EDP && link->dc->hwss.edp_wait_for_T12) {
404 link->dc->hwss.edp_wait_for_T12(link);
405
406 return true;
407 }
408
409 return false;
410 }
411
edp_add_delay_for_T9(struct dc_link * link)412 void edp_add_delay_for_T9(struct dc_link *link)
413 {
414 if (link && link->panel_config.pps.extra_delay_backlight_off > 0)
415 fsleep(link->panel_config.pps.extra_delay_backlight_off * 1000);
416 }
417
edp_receiver_ready_T9(struct dc_link * link)418 bool edp_receiver_ready_T9(struct dc_link *link)
419 {
420 unsigned int tries = 0;
421 unsigned char sinkstatus = 0;
422 unsigned char edpRev = 0;
423 enum dc_status result = DC_OK;
424
425 result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
426
427 /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
428 if (result == DC_OK && edpRev >= DP_EDP_12) {
429 do {
430 sinkstatus = 1;
431 result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
432 if (sinkstatus == 0)
433 break;
434 if (result != DC_OK)
435 break;
436 udelay(100); //MAx T9
437 } while (++tries < 50);
438 }
439
440 return result;
441 }
442
edp_receiver_ready_T7(struct dc_link * link)443 bool edp_receiver_ready_T7(struct dc_link *link)
444 {
445 unsigned char sinkstatus = 0;
446 unsigned char edpRev = 0;
447 enum dc_status result = DC_OK;
448
449 /* use absolute time stamp to constrain max T7*/
450 unsigned long long enter_timestamp = 0;
451 unsigned long long finish_timestamp = 0;
452 unsigned long long time_taken_in_ns = 0;
453
454 result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
455
456 if (result == DC_OK && edpRev >= DP_EDP_12) {
457 /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
458 enter_timestamp = dm_get_timestamp(link->ctx);
459 do {
460 sinkstatus = 0;
461 result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
462 if (sinkstatus == 1)
463 break;
464 if (result != DC_OK)
465 break;
466 udelay(25);
467 finish_timestamp = dm_get_timestamp(link->ctx);
468 time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp, enter_timestamp);
469 } while (time_taken_in_ns < 50 * 1000000); //MAx T7 is 50ms
470 }
471
472 if (link && link->panel_config.pps.extra_t7_ms > 0)
473 fsleep(link->panel_config.pps.extra_t7_ms * 1000);
474
475 return result;
476 }
477
edp_power_alpm_dpcd_enable(struct dc_link * link,bool enable)478 bool edp_power_alpm_dpcd_enable(struct dc_link *link, bool enable)
479 {
480 bool ret = false;
481 union dpcd_alpm_configuration alpm_config;
482
483 if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) {
484 memset(&alpm_config, 0, sizeof(alpm_config));
485
486 alpm_config.bits.ENABLE = (enable ? true : false);
487 ret = dm_helpers_dp_write_dpcd(link->ctx, link,
488 DP_RECEIVER_ALPM_CONFIG, &alpm_config.raw,
489 sizeof(alpm_config.raw));
490 }
491 return ret;
492 }
493
get_pipe_from_link(const struct dc_link * link)494 static struct pipe_ctx *get_pipe_from_link(const struct dc_link *link)
495 {
496 int i;
497 struct dc *dc = link->ctx->dc;
498 struct pipe_ctx *pipe_ctx = NULL;
499
500 for (i = 0; i < MAX_PIPES; i++) {
501 if (dc->current_state->res_ctx.pipe_ctx[i].stream) {
502 if (dc->current_state->res_ctx.pipe_ctx[i].stream->link == link) {
503 pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
504 break;
505 }
506 }
507 }
508
509 return pipe_ctx;
510 }
511
edp_set_backlight_level(const struct dc_link * link,uint32_t backlight_pwm_u16_16,uint32_t frame_ramp)512 bool edp_set_backlight_level(const struct dc_link *link,
513 uint32_t backlight_pwm_u16_16,
514 uint32_t frame_ramp)
515 {
516 struct dc *dc = link->ctx->dc;
517
518 DC_LOGGER_INIT(link->ctx->logger);
519 DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
520 backlight_pwm_u16_16, backlight_pwm_u16_16);
521
522 if (dc_is_embedded_signal(link->connector_signal)) {
523 struct pipe_ctx *pipe_ctx = get_pipe_from_link(link);
524
525 if (pipe_ctx) {
526 /* Disable brightness ramping when the display is blanked
527 * as it can hang the DMCU
528 */
529 if (pipe_ctx->plane_state == NULL)
530 frame_ramp = 0;
531 } else {
532 return false;
533 }
534
535 dc->hwss.set_backlight_level(
536 pipe_ctx,
537 backlight_pwm_u16_16,
538 frame_ramp);
539 }
540 return true;
541 }
542
edp_set_psr_allow_active(struct dc_link * link,const bool * allow_active,bool wait,bool force_static,const unsigned int * power_opts)543 bool edp_set_psr_allow_active(struct dc_link *link, const bool *allow_active,
544 bool wait, bool force_static, const unsigned int *power_opts)
545 {
546 struct dc *dc = link->ctx->dc;
547 struct dmcu *dmcu = dc->res_pool->dmcu;
548 struct dmub_psr *psr = dc->res_pool->psr;
549 unsigned int panel_inst;
550
551 if (psr == NULL && force_static)
552 return false;
553
554 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
555 return false;
556
557 if ((allow_active != NULL) && (*allow_active == true) && (link->type == dc_connection_none)) {
558 // Don't enter PSR if panel is not connected
559 return false;
560 }
561
562 /* Set power optimization flag */
563 if (power_opts && link->psr_settings.psr_power_opt != *power_opts) {
564 link->psr_settings.psr_power_opt = *power_opts;
565
566 if (psr != NULL && link->psr_settings.psr_feature_enabled && psr->funcs->psr_set_power_opt)
567 psr->funcs->psr_set_power_opt(psr, link->psr_settings.psr_power_opt, panel_inst);
568 }
569
570 if (psr != NULL && link->psr_settings.psr_feature_enabled &&
571 force_static && psr->funcs->psr_force_static)
572 psr->funcs->psr_force_static(psr, panel_inst);
573
574 /* Enable or Disable PSR */
575 if (allow_active && link->psr_settings.psr_allow_active != *allow_active) {
576 link->psr_settings.psr_allow_active = *allow_active;
577
578 if (!link->psr_settings.psr_allow_active)
579 dc_z10_restore(dc);
580
581 if (psr != NULL && link->psr_settings.psr_feature_enabled) {
582 psr->funcs->psr_enable(psr, link->psr_settings.psr_allow_active, wait, panel_inst);
583 } else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) &&
584 link->psr_settings.psr_feature_enabled)
585 dmcu->funcs->set_psr_enable(dmcu, link->psr_settings.psr_allow_active, wait);
586 else
587 return false;
588 }
589 return true;
590 }
591
edp_get_psr_state(const struct dc_link * link,enum dc_psr_state * state)592 bool edp_get_psr_state(const struct dc_link *link, enum dc_psr_state *state)
593 {
594 struct dc *dc = link->ctx->dc;
595 struct dmcu *dmcu = dc->res_pool->dmcu;
596 struct dmub_psr *psr = dc->res_pool->psr;
597 unsigned int panel_inst;
598
599 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
600 return false;
601
602 if (psr != NULL && link->psr_settings.psr_feature_enabled)
603 psr->funcs->psr_get_state(psr, state, panel_inst);
604 else if (dmcu != NULL && link->psr_settings.psr_feature_enabled)
605 dmcu->funcs->get_psr_state(dmcu, state);
606
607 return true;
608 }
609
610 static inline enum physical_phy_id
transmitter_to_phy_id(struct dc_link * link)611 transmitter_to_phy_id(struct dc_link *link)
612 {
613 struct dc_context *dc_ctx = link->ctx;
614 enum transmitter transmitter_value = link->link_enc->transmitter;
615
616 switch (transmitter_value) {
617 case TRANSMITTER_UNIPHY_A:
618 return PHYLD_0;
619 case TRANSMITTER_UNIPHY_B:
620 return PHYLD_1;
621 case TRANSMITTER_UNIPHY_C:
622 return PHYLD_2;
623 case TRANSMITTER_UNIPHY_D:
624 return PHYLD_3;
625 case TRANSMITTER_UNIPHY_E:
626 return PHYLD_4;
627 case TRANSMITTER_UNIPHY_F:
628 return PHYLD_5;
629 case TRANSMITTER_NUTMEG_CRT:
630 return PHYLD_6;
631 case TRANSMITTER_TRAVIS_CRT:
632 return PHYLD_7;
633 case TRANSMITTER_TRAVIS_LCD:
634 return PHYLD_8;
635 case TRANSMITTER_UNIPHY_G:
636 return PHYLD_9;
637 case TRANSMITTER_COUNT:
638 return PHYLD_COUNT;
639 case TRANSMITTER_UNKNOWN:
640 return PHYLD_UNKNOWN;
641 default:
642 DC_ERROR("Unknown transmitter value %d\n", transmitter_value);
643 return PHYLD_UNKNOWN;
644 }
645 }
646
edp_setup_psr(struct dc_link * link,const struct dc_stream_state * stream,struct psr_config * psr_config,struct psr_context * psr_context)647 bool edp_setup_psr(struct dc_link *link,
648 const struct dc_stream_state *stream, struct psr_config *psr_config,
649 struct psr_context *psr_context)
650 {
651 struct dc *dc;
652 struct dmcu *dmcu;
653 struct dmub_psr *psr;
654 int i;
655 unsigned int panel_inst;
656 /* updateSinkPsrDpcdConfig*/
657 union dpcd_psr_configuration psr_configuration;
658 union dpcd_sink_active_vtotal_control_mode vtotal_control = {0};
659
660 psr_context->controllerId = CONTROLLER_ID_UNDEFINED;
661
662 if (!link)
663 return false;
664
665 dc = link->ctx->dc;
666 dmcu = dc->res_pool->dmcu;
667 psr = dc->res_pool->psr;
668
669 if (!dmcu && !psr)
670 return false;
671
672 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
673 return false;
674
675
676 memset(&psr_configuration, 0, sizeof(psr_configuration));
677
678 psr_configuration.bits.ENABLE = 1;
679 psr_configuration.bits.CRC_VERIFICATION = 1;
680 psr_configuration.bits.FRAME_CAPTURE_INDICATION =
681 psr_config->psr_frame_capture_indication_req;
682
683 /* Check for PSR v2*/
684 if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) {
685 /* For PSR v2 selective update.
686 * Indicates whether sink should start capturing
687 * immediately following active scan line,
688 * or starting with the 2nd active scan line.
689 */
690 psr_configuration.bits.LINE_CAPTURE_INDICATION = 0;
691 /*For PSR v2, determines whether Sink should generate
692 * IRQ_HPD when CRC mismatch is detected.
693 */
694 psr_configuration.bits.IRQ_HPD_WITH_CRC_ERROR = 1;
695 /* For PSR v2, set the bit when the Source device will
696 * be enabling PSR2 operation.
697 */
698 psr_configuration.bits.ENABLE_PSR2 = 1;
699 /* For PSR v2, the Sink device must be able to receive
700 * SU region updates early in the frame time.
701 */
702 psr_configuration.bits.EARLY_TRANSPORT_ENABLE = 1;
703 }
704
705 dm_helpers_dp_write_dpcd(
706 link->ctx,
707 link,
708 368,
709 &psr_configuration.raw,
710 sizeof(psr_configuration.raw));
711
712 if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) {
713 edp_power_alpm_dpcd_enable(link, true);
714 psr_context->su_granularity_required =
715 psr_config->su_granularity_required;
716 psr_context->su_y_granularity =
717 psr_config->su_y_granularity;
718 psr_context->line_time_in_us = psr_config->line_time_in_us;
719
720 /* linux must be able to expose AMD Source DPCD definition
721 * in order to support FreeSync PSR
722 */
723 if (link->psr_settings.psr_vtotal_control_support) {
724 psr_context->rate_control_caps = psr_config->rate_control_caps;
725 vtotal_control.bits.ENABLE = true;
726 core_link_write_dpcd(link, DP_SINK_PSR_ACTIVE_VTOTAL_CONTROL_MODE,
727 &vtotal_control.raw, sizeof(vtotal_control.raw));
728 }
729 }
730
731 psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel;
732 psr_context->transmitterId = link->link_enc->transmitter;
733 psr_context->engineId = link->link_enc->preferred_engine;
734
735 for (i = 0; i < MAX_PIPES; i++) {
736 if (dc->current_state->res_ctx.pipe_ctx[i].stream
737 == stream) {
738 /* dmcu -1 for all controller id values,
739 * therefore +1 here
740 */
741 psr_context->controllerId =
742 dc->current_state->res_ctx.
743 pipe_ctx[i].stream_res.tg->inst + 1;
744 break;
745 }
746 }
747
748 /* Hardcoded for now. Can be Pcie or Uniphy (or Unknown)*/
749 psr_context->phyType = PHY_TYPE_UNIPHY;
750 /*PhyId is associated with the transmitter id*/
751 psr_context->smuPhyId = transmitter_to_phy_id(link);
752
753 psr_context->crtcTimingVerticalTotal = stream->timing.v_total;
754 psr_context->vsync_rate_hz = div64_u64(div64_u64((stream->
755 timing.pix_clk_100hz * 100),
756 stream->timing.v_total),
757 stream->timing.h_total);
758
759 psr_context->psrSupportedDisplayConfig = true;
760 psr_context->psrExitLinkTrainingRequired =
761 psr_config->psr_exit_link_training_required;
762 psr_context->sdpTransmitLineNumDeadline =
763 psr_config->psr_sdp_transmit_line_num_deadline;
764 psr_context->psrFrameCaptureIndicationReq =
765 psr_config->psr_frame_capture_indication_req;
766
767 psr_context->skipPsrWaitForPllLock = 0; /* only = 1 in KV */
768
769 psr_context->numberOfControllers =
770 link->dc->res_pool->timing_generator_count;
771
772 psr_context->rfb_update_auto_en = true;
773
774 /* 2 frames before enter PSR. */
775 psr_context->timehyst_frames = 2;
776 /* half a frame
777 * (units in 100 lines, i.e. a value of 1 represents 100 lines)
778 */
779 psr_context->hyst_lines = stream->timing.v_total / 2 / 100;
780 psr_context->aux_repeats = 10;
781
782 psr_context->psr_level.u32all = 0;
783
784 /*skip power down the single pipe since it blocks the cstate*/
785 if (link->ctx->asic_id.chip_family >= FAMILY_RV) {
786 switch (link->ctx->asic_id.chip_family) {
787 case FAMILY_YELLOW_CARP:
788 case AMDGPU_FAMILY_GC_10_3_6:
789 case AMDGPU_FAMILY_GC_11_0_1:
790 if (dc->debug.disable_z10 || dc->debug.psr_skip_crtc_disable)
791 psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
792 break;
793 default:
794 psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true;
795 break;
796 }
797 }
798
799 /* SMU will perform additional powerdown sequence.
800 * For unsupported ASICs, set psr_level flag to skip PSR
801 * static screen notification to SMU.
802 * (Always set for DAL2, did not check ASIC)
803 */
804 psr_context->allow_smu_optimizations = psr_config->allow_smu_optimizations;
805 psr_context->allow_multi_disp_optimizations = psr_config->allow_multi_disp_optimizations;
806
807 /* Complete PSR entry before aborting to prevent intermittent
808 * freezes on certain eDPs
809 */
810 psr_context->psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1;
811
812 /* Disable ALPM first for compatible non-ALPM panel now */
813 psr_context->psr_level.bits.DISABLE_ALPM = 0;
814 psr_context->psr_level.bits.ALPM_DEFAULT_PD_MODE = 1;
815
816 /* Controls additional delay after remote frame capture before
817 * continuing power down, default = 0
818 */
819 psr_context->frame_delay = 0;
820
821 psr_context->dsc_slice_height = psr_config->dsc_slice_height;
822
823 if (psr) {
824 link->psr_settings.psr_feature_enabled = psr->funcs->psr_copy_settings(psr,
825 link, psr_context, panel_inst);
826 link->psr_settings.psr_power_opt = 0;
827 link->psr_settings.psr_allow_active = 0;
828 } else {
829 link->psr_settings.psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context);
830 }
831
832 /* psr_enabled == 0 indicates setup_psr did not succeed, but this
833 * should not happen since firmware should be running at this point
834 */
835 if (link->psr_settings.psr_feature_enabled == 0)
836 ASSERT(0);
837
838 return true;
839
840 }
841
edp_get_psr_residency(const struct dc_link * link,uint32_t * residency)842 void edp_get_psr_residency(const struct dc_link *link, uint32_t *residency)
843 {
844 struct dc *dc = link->ctx->dc;
845 struct dmub_psr *psr = dc->res_pool->psr;
846 unsigned int panel_inst;
847
848 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
849 return;
850
851 // PSR residency measurements only supported on DMCUB
852 if (psr != NULL && link->psr_settings.psr_feature_enabled)
853 psr->funcs->psr_get_residency(psr, residency, panel_inst);
854 else
855 *residency = 0;
856 }
edp_set_sink_vtotal_in_psr_active(const struct dc_link * link,uint16_t psr_vtotal_idle,uint16_t psr_vtotal_su)857 bool edp_set_sink_vtotal_in_psr_active(const struct dc_link *link, uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su)
858 {
859 struct dc *dc = link->ctx->dc;
860 struct dmub_psr *psr = dc->res_pool->psr;
861
862 if (psr == NULL || !link->psr_settings.psr_feature_enabled || !link->psr_settings.psr_vtotal_control_support)
863 return false;
864
865 psr->funcs->psr_set_sink_vtotal_in_psr_active(psr, psr_vtotal_idle, psr_vtotal_su);
866
867 return true;
868 }
869
edp_set_replay_allow_active(struct dc_link * link,const bool * allow_active,bool wait,bool force_static,const unsigned int * power_opts)870 bool edp_set_replay_allow_active(struct dc_link *link, const bool *allow_active,
871 bool wait, bool force_static, const unsigned int *power_opts)
872 {
873 struct dc *dc = link->ctx->dc;
874 struct dmub_replay *replay = dc->res_pool->replay;
875 unsigned int panel_inst;
876
877 if (replay == NULL && force_static)
878 return false;
879
880 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
881 return false;
882
883 /* Set power optimization flag */
884 if (power_opts && link->replay_settings.replay_power_opt_active != *power_opts) {
885 if (link->replay_settings.replay_feature_enabled && replay->funcs->replay_set_power_opt) {
886 replay->funcs->replay_set_power_opt(replay, *power_opts, panel_inst);
887 link->replay_settings.replay_power_opt_active = *power_opts;
888 }
889 }
890
891 /* Activate or deactivate Replay */
892 if (allow_active && link->replay_settings.replay_allow_active != *allow_active) {
893 // TODO: Handle mux change case if force_static is set
894 // If force_static is set, just change the replay_allow_active state directly
895 if (replay != NULL && link->replay_settings.replay_feature_enabled)
896 replay->funcs->replay_enable(replay, *allow_active, wait, panel_inst);
897 link->replay_settings.replay_allow_active = *allow_active;
898 }
899
900 return true;
901 }
902
edp_get_replay_state(const struct dc_link * link,uint64_t * state)903 bool edp_get_replay_state(const struct dc_link *link, uint64_t *state)
904 {
905 struct dc *dc = link->ctx->dc;
906 struct dmub_replay *replay = dc->res_pool->replay;
907 unsigned int panel_inst;
908 enum replay_state pr_state = REPLAY_STATE_0;
909
910 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
911 return false;
912
913 if (replay != NULL && link->replay_settings.replay_feature_enabled)
914 replay->funcs->replay_get_state(replay, &pr_state, panel_inst);
915 *state = pr_state;
916
917 return true;
918 }
919
edp_setup_replay(struct dc_link * link,const struct dc_stream_state * stream)920 bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream)
921 {
922 /* To-do: Setup Replay */
923 struct dc *dc;
924 struct dmub_replay *replay;
925 int i;
926 unsigned int panel_inst;
927 struct replay_context replay_context = { 0 };
928 unsigned int lineTimeInNs = 0;
929
930
931 union replay_enable_and_configuration replay_config;
932
933 union dpcd_alpm_configuration alpm_config;
934
935 replay_context.controllerId = CONTROLLER_ID_UNDEFINED;
936
937 if (!link)
938 return false;
939
940 dc = link->ctx->dc;
941
942 replay = dc->res_pool->replay;
943
944 if (!replay)
945 return false;
946
947 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
948 return false;
949
950 replay_context.aux_inst = link->ddc->ddc_pin->hw_info.ddc_channel;
951 replay_context.digbe_inst = link->link_enc->transmitter;
952 replay_context.digfe_inst = link->link_enc->preferred_engine;
953
954 for (i = 0; i < MAX_PIPES; i++) {
955 if (dc->current_state->res_ctx.pipe_ctx[i].stream
956 == stream) {
957 /* dmcu -1 for all controller id values,
958 * therefore +1 here
959 */
960 replay_context.controllerId =
961 dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg->inst + 1;
962 break;
963 }
964 }
965
966 lineTimeInNs =
967 ((stream->timing.h_total * 1000000) /
968 (stream->timing.pix_clk_100hz / 10)) + 1;
969
970 replay_context.line_time_in_ns = lineTimeInNs;
971
972 link->replay_settings.replay_feature_enabled =
973 replay->funcs->replay_copy_settings(replay, link, &replay_context, panel_inst);
974 if (link->replay_settings.replay_feature_enabled) {
975
976 replay_config.bits.FREESYNC_PANEL_REPLAY_MODE = 1;
977 replay_config.bits.TIMING_DESYNC_ERROR_VERIFICATION =
978 link->replay_settings.config.replay_timing_sync_supported;
979 replay_config.bits.STATE_TRANSITION_ERROR_DETECTION = 1;
980 dm_helpers_dp_write_dpcd(link->ctx, link,
981 DP_SINK_PR_ENABLE_AND_CONFIGURATION,
982 (uint8_t *)&(replay_config.raw), sizeof(uint8_t));
983
984 memset(&alpm_config, 0, sizeof(alpm_config));
985 alpm_config.bits.ENABLE = 1;
986 dm_helpers_dp_write_dpcd(
987 link->ctx,
988 link,
989 DP_RECEIVER_ALPM_CONFIG,
990 &alpm_config.raw,
991 sizeof(alpm_config.raw));
992 }
993 return true;
994 }
995
edp_set_coasting_vtotal(struct dc_link * link,uint16_t coasting_vtotal)996 bool edp_set_coasting_vtotal(struct dc_link *link, uint16_t coasting_vtotal)
997 {
998 struct dc *dc = link->ctx->dc;
999 struct dmub_replay *replay = dc->res_pool->replay;
1000 unsigned int panel_inst;
1001
1002 if (!replay)
1003 return false;
1004
1005 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
1006 return false;
1007
1008 if (coasting_vtotal && link->replay_settings.coasting_vtotal != coasting_vtotal) {
1009 replay->funcs->replay_set_coasting_vtotal(replay, coasting_vtotal, panel_inst);
1010 link->replay_settings.coasting_vtotal = coasting_vtotal;
1011 }
1012
1013 return true;
1014 }
1015
edp_replay_residency(const struct dc_link * link,unsigned int * residency,const bool is_start,const bool is_alpm)1016 bool edp_replay_residency(const struct dc_link *link,
1017 unsigned int *residency, const bool is_start, const bool is_alpm)
1018 {
1019 struct dc *dc = link->ctx->dc;
1020 struct dmub_replay *replay = dc->res_pool->replay;
1021 unsigned int panel_inst;
1022
1023 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
1024 return false;
1025
1026 if (replay != NULL && link->replay_settings.replay_feature_enabled)
1027 replay->funcs->replay_residency(replay, panel_inst, residency, is_start, is_alpm);
1028 else
1029 *residency = 0;
1030
1031 return true;
1032 }
1033
get_abm_from_stream_res(const struct dc_link * link)1034 static struct abm *get_abm_from_stream_res(const struct dc_link *link)
1035 {
1036 int i;
1037 struct dc *dc = link->ctx->dc;
1038 struct abm *abm = NULL;
1039
1040 for (i = 0; i < MAX_PIPES; i++) {
1041 struct pipe_ctx pipe_ctx = dc->current_state->res_ctx.pipe_ctx[i];
1042 struct dc_stream_state *stream = pipe_ctx.stream;
1043
1044 if (stream && stream->link == link) {
1045 abm = pipe_ctx.stream_res.abm;
1046 break;
1047 }
1048 }
1049 return abm;
1050 }
1051
edp_get_backlight_level(const struct dc_link * link)1052 int edp_get_backlight_level(const struct dc_link *link)
1053 {
1054 struct abm *abm = get_abm_from_stream_res(link);
1055 struct panel_cntl *panel_cntl = link->panel_cntl;
1056 struct dc *dc = link->ctx->dc;
1057 struct dmcu *dmcu = dc->res_pool->dmcu;
1058 bool fw_set_brightness = true;
1059
1060 if (dmcu)
1061 fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
1062
1063 if (!fw_set_brightness && panel_cntl->funcs->get_current_backlight)
1064 return panel_cntl->funcs->get_current_backlight(panel_cntl);
1065 else if (abm != NULL && abm->funcs->get_current_backlight != NULL)
1066 return (int) abm->funcs->get_current_backlight(abm);
1067 else
1068 return DC_ERROR_UNEXPECTED;
1069 }
1070
edp_get_target_backlight_pwm(const struct dc_link * link)1071 int edp_get_target_backlight_pwm(const struct dc_link *link)
1072 {
1073 struct abm *abm = get_abm_from_stream_res(link);
1074
1075 if (abm == NULL || abm->funcs->get_target_backlight == NULL)
1076 return DC_ERROR_UNEXPECTED;
1077
1078 return (int) abm->funcs->get_target_backlight(abm);
1079 }
1080