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

source code of linux/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c