forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
....@@ -22,6 +22,9 @@
2222 * Authors: AMD
2323 *
2424 */
25
+
26
+#include <linux/delay.h>
27
+
2528 #include "dm_services.h"
2629 #include "dc.h"
2730 #include "dc_bios_types.h"
....@@ -46,9 +49,11 @@
4649 #include "link_encoder.h"
4750 #include "link_hwss.h"
4851 #include "clock_source.h"
52
+#include "clk_mgr.h"
4953 #include "abm.h"
5054 #include "audio.h"
5155 #include "reg_helper.h"
56
+#include "panel_cntl.h"
5257
5358 /* include DCE11 register header files */
5459 #include "dce/dce_11_0_d.h"
....@@ -56,6 +61,8 @@
5661 #include "custom_float.h"
5762
5863 #include "atomfirmware.h"
64
+
65
+#define GAMMA_HW_POINTS_NUM 256
5966
6067 /*
6168 * All values are in milliseconds;
....@@ -65,6 +72,8 @@
6572 #define PANEL_POWER_UP_TIMEOUT 300
6673 #define PANEL_POWER_DOWN_TIMEOUT 500
6774 #define HPD_CHECK_INTERVAL 10
75
+#define OLED_POST_T7_DELAY 100
76
+#define OLED_PRE_T11_DELAY 150
6877
6978 #define CTX \
7079 hws->ctx
....@@ -264,7 +273,7 @@
264273 }
265274
266275 static bool
267
-dce110_set_input_transfer_func(struct pipe_ctx *pipe_ctx,
276
+dce110_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
268277 const struct dc_plane_state *plane_state)
269278 {
270279 struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
....@@ -551,14 +560,14 @@
551560
552561 regamma_params->hw_points_num = hw_points;
553562
554
- i = 1;
555
- for (k = 0; k < 16 && i < 16; k++) {
563
+ k = 0;
564
+ for (i = 1; i < 16; i++) {
556565 if (seg_distr[k] != -1) {
557566 regamma_params->arr_curve_points[k].segments_num = seg_distr[k];
558567 regamma_params->arr_curve_points[i].offset =
559568 regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]);
560569 }
561
- i++;
570
+ k++;
562571 }
563572
564573 if (seg_distr[k] != -1)
....@@ -592,7 +601,7 @@
592601 }
593602
594603 static bool
595
-dce110_set_output_transfer_func(struct pipe_ctx *pipe_ctx,
604
+dce110_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
596605 const struct dc_stream_state *stream)
597606 {
598607 struct transform *xfm = pipe_ctx->plane_res.xfm;
....@@ -617,58 +626,9 @@
617626 return true;
618627 }
619628
620
-static enum dc_status bios_parser_crtc_source_select(
621
- struct pipe_ctx *pipe_ctx)
622
-{
623
- struct dc_bios *dcb;
624
- /* call VBIOS table to set CRTC source for the HW
625
- * encoder block
626
- * note: video bios clears all FMT setting here. */
627
- struct bp_crtc_source_select crtc_source_select = {0};
628
- const struct dc_sink *sink = pipe_ctx->stream->sink;
629
-
630
- crtc_source_select.engine_id = pipe_ctx->stream_res.stream_enc->id;
631
- crtc_source_select.controller_id = pipe_ctx->stream_res.tg->inst + 1;
632
- /*TODO: Need to un-hardcode color depth, dp_audio and account for
633
- * the case where signal and sink signal is different (translator
634
- * encoder)*/
635
- crtc_source_select.signal = pipe_ctx->stream->signal;
636
- crtc_source_select.enable_dp_audio = false;
637
- crtc_source_select.sink_signal = pipe_ctx->stream->signal;
638
-
639
- switch (pipe_ctx->stream->timing.display_color_depth) {
640
- case COLOR_DEPTH_666:
641
- crtc_source_select.display_output_bit_depth = PANEL_6BIT_COLOR;
642
- break;
643
- case COLOR_DEPTH_888:
644
- crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR;
645
- break;
646
- case COLOR_DEPTH_101010:
647
- crtc_source_select.display_output_bit_depth = PANEL_10BIT_COLOR;
648
- break;
649
- case COLOR_DEPTH_121212:
650
- crtc_source_select.display_output_bit_depth = PANEL_12BIT_COLOR;
651
- break;
652
- default:
653
- BREAK_TO_DEBUGGER();
654
- crtc_source_select.display_output_bit_depth = PANEL_8BIT_COLOR;
655
- break;
656
- }
657
-
658
- dcb = sink->ctx->dc_bios;
659
-
660
- if (BP_RESULT_OK != dcb->funcs->crtc_source_select(
661
- dcb,
662
- &crtc_source_select)) {
663
- return DC_ERROR_UNEXPECTED;
664
- }
665
-
666
- return DC_OK;
667
-}
668
-
669629 void dce110_update_info_frame(struct pipe_ctx *pipe_ctx)
670630 {
671
- bool is_hdmi;
631
+ bool is_hdmi_tmds;
672632 bool is_dp;
673633
674634 ASSERT(pipe_ctx->stream);
....@@ -676,13 +636,13 @@
676636 if (pipe_ctx->stream_res.stream_enc == NULL)
677637 return; /* this is not root pipe */
678638
679
- is_hdmi = dc_is_hdmi_signal(pipe_ctx->stream->signal);
639
+ is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
680640 is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
681641
682
- if (!is_hdmi && !is_dp)
642
+ if (!is_hdmi_tmds && !is_dp)
683643 return;
684644
685
- if (is_hdmi)
645
+ if (is_hdmi_tmds)
686646 pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(
687647 pipe_ctx->stream_res.stream_enc,
688648 &pipe_ctx->stream_res.encoder_info_frame);
....@@ -695,11 +655,10 @@
695655 void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
696656 {
697657 enum dc_lane_count lane_count =
698
- pipe_ctx->stream->sink->link->cur_link_settings.lane_count;
699
-
658
+ pipe_ctx->stream->link->cur_link_settings.lane_count;
700659 struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
701
- struct dc_link *link = pipe_ctx->stream->sink->link;
702
-
660
+ struct dc_link *link = pipe_ctx->stream->link;
661
+ const struct dc *dc = link->dc;
703662
704663 uint32_t active_total_with_borders;
705664 uint32_t early_control = 0;
....@@ -712,9 +671,7 @@
712671 link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
713672 pipe_ctx->stream_res.stream_enc->id, true);
714673
715
- /* update AVI info frame (HDMI, DP)*/
716
- /* TODO: FPGA may change to hwss.update_info_frame */
717
- dce110_update_info_frame(pipe_ctx);
674
+ dc->hwss.update_info_frame(pipe_ctx);
718675
719676 /* enable early control to avoid corruption on DP monitor*/
720677 active_total_with_borders =
....@@ -741,28 +698,6 @@
741698
742699 }
743700
744
-/*todo: cloned in stream enc, fix*/
745
-static bool is_panel_backlight_on(struct dce_hwseq *hws)
746
-{
747
- uint32_t value;
748
-
749
- REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
750
-
751
- return value;
752
-}
753
-
754
-static bool is_panel_powered_on(struct dce_hwseq *hws)
755
-{
756
- uint32_t pwr_seq_state, dig_on, dig_on_ovrd;
757
-
758
-
759
- REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &pwr_seq_state);
760
-
761
- REG_GET_2(LVTMA_PWRSEQ_CNTL, LVTMA_DIGON, &dig_on, LVTMA_DIGON_OVRD, &dig_on_ovrd);
762
-
763
- return (pwr_seq_state == 1) || (dig_on == 1 && dig_on_ovrd == 1);
764
-}
765
-
766701 static enum bp_result link_transmitter_control(
767702 struct dc_bios *bios,
768703 struct bp_transmitter_control *cntl)
....@@ -778,13 +713,14 @@
778713 * @brief
779714 * eDP only.
780715 */
781
-void hwss_edp_wait_for_hpd_ready(
716
+void dce110_edp_wait_for_hpd_ready(
782717 struct dc_link *link,
783718 bool power_up)
784719 {
785720 struct dc_context *ctx = link->ctx;
786721 struct graphics_object_id connector = link->link_enc->connector;
787722 struct gpio *hpd;
723
+ struct dc_sink *sink = link->local_sink;
788724 bool edp_hpd_high = false;
789725 uint32_t time_elapsed = 0;
790726 uint32_t timeout = power_up ?
....@@ -817,6 +753,14 @@
817753 return;
818754 }
819755
756
+ if (sink != NULL) {
757
+ if (sink->edid_caps.panel_patch.extra_t3_ms > 0) {
758
+ int extra_t3_in_ms = sink->edid_caps.panel_patch.extra_t3_ms;
759
+
760
+ msleep(extra_t3_in_ms);
761
+ }
762
+ }
763
+
820764 dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
821765
822766 /* wait until timeout or panel detected */
....@@ -846,12 +790,11 @@
846790 }
847791 }
848792
849
-void hwss_edp_power_control(
793
+void dce110_edp_power_control(
850794 struct dc_link *link,
851795 bool power_up)
852796 {
853797 struct dc_context *ctx = link->ctx;
854
- struct dce_hwseq *hwseq = ctx->dc->hwseq;
855798 struct bp_transmitter_control cntl = { 0 };
856799 enum bp_result bp_result;
857800
....@@ -862,38 +805,71 @@
862805 return;
863806 }
864807
865
- if (power_up != is_panel_powered_on(hwseq)) {
808
+ if (!link->panel_cntl)
809
+ return;
810
+
811
+ if (power_up !=
812
+ link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl)) {
813
+
814
+ unsigned long long current_ts = dm_get_timestamp(ctx);
815
+ unsigned long long time_since_edp_poweroff_ms =
816
+ div64_u64(dm_get_elapse_time_in_ns(
817
+ ctx,
818
+ current_ts,
819
+ link->link_trace.time_stamp.edp_poweroff), 1000000);
820
+ unsigned long long time_since_edp_poweron_ms =
821
+ div64_u64(dm_get_elapse_time_in_ns(
822
+ ctx,
823
+ current_ts,
824
+ link->link_trace.time_stamp.edp_poweron), 1000000);
825
+ DC_LOG_HW_RESUME_S3(
826
+ "%s: transition: power_up=%d current_ts=%llu edp_poweroff=%llu edp_poweron=%llu time_since_edp_poweroff_ms=%llu time_since_edp_poweron_ms=%llu",
827
+ __func__,
828
+ power_up,
829
+ current_ts,
830
+ link->link_trace.time_stamp.edp_poweroff,
831
+ link->link_trace.time_stamp.edp_poweron,
832
+ time_since_edp_poweroff_ms,
833
+ time_since_edp_poweron_ms);
834
+
866835 /* Send VBIOS command to prompt eDP panel power */
867836 if (power_up) {
868
- unsigned long long current_ts = dm_get_timestamp(ctx);
869
- unsigned long long duration_in_ms =
870
- div64_u64(dm_get_elapse_time_in_ns(
871
- ctx,
872
- current_ts,
873
- link->link_trace.time_stamp.edp_poweroff), 1000000);
874
- unsigned long long wait_time_ms = 0;
837
+ /* edp requires a min of 500ms from LCDVDD off to on */
838
+ unsigned long long remaining_min_edp_poweroff_time_ms = 500;
875839
876
- /* max 500ms from LCDVDD off to on */
877
- unsigned long long edp_poweroff_time_ms = 500;
878
-
840
+ /* add time defined by a patch, if any (usually patch extra_t12_ms is 0) */
879841 if (link->local_sink != NULL)
880
- edp_poweroff_time_ms =
881
- 500 + link->local_sink->edid_caps.panel_patch.extra_t12_ms;
882
- if (link->link_trace.time_stamp.edp_poweroff == 0)
883
- wait_time_ms = edp_poweroff_time_ms;
884
- else if (duration_in_ms < edp_poweroff_time_ms)
885
- wait_time_ms = edp_poweroff_time_ms - duration_in_ms;
842
+ remaining_min_edp_poweroff_time_ms +=
843
+ link->local_sink->edid_caps.panel_patch.extra_t12_ms;
886844
887
- if (wait_time_ms) {
888
- msleep(wait_time_ms);
889
- dm_output_to_console("%s: wait %lld ms to power on eDP.\n",
890
- __func__, wait_time_ms);
845
+ /* Adjust remaining_min_edp_poweroff_time_ms if this is not the first time. */
846
+ if (link->link_trace.time_stamp.edp_poweroff != 0) {
847
+ if (time_since_edp_poweroff_ms < remaining_min_edp_poweroff_time_ms)
848
+ remaining_min_edp_poweroff_time_ms =
849
+ remaining_min_edp_poweroff_time_ms - time_since_edp_poweroff_ms;
850
+ else
851
+ remaining_min_edp_poweroff_time_ms = 0;
891852 }
892853
854
+ if (remaining_min_edp_poweroff_time_ms) {
855
+ DC_LOG_HW_RESUME_S3(
856
+ "%s: remaining_min_edp_poweroff_time_ms=%llu: begin wait.\n",
857
+ __func__, remaining_min_edp_poweroff_time_ms);
858
+ msleep(remaining_min_edp_poweroff_time_ms);
859
+ DC_LOG_HW_RESUME_S3(
860
+ "%s: remaining_min_edp_poweroff_time_ms=%llu: end wait.\n",
861
+ __func__, remaining_min_edp_poweroff_time_ms);
862
+ dm_output_to_console("%s: wait %lld ms to power on eDP.\n",
863
+ __func__, remaining_min_edp_poweroff_time_ms);
864
+ } else {
865
+ DC_LOG_HW_RESUME_S3(
866
+ "%s: remaining_min_edp_poweroff_time_ms=%llu: no wait required.\n",
867
+ __func__, remaining_min_edp_poweroff_time_ms);
868
+ }
893869 }
894870
895871 DC_LOG_HW_RESUME_S3(
896
- "%s: Panel Power action: %s\n",
872
+ "%s: BEGIN: Panel Power action: %s\n",
897873 __func__, (power_up ? "On":"Off"));
898874
899875 cntl.action = power_up ?
....@@ -904,13 +880,35 @@
904880 cntl.coherent = false;
905881 cntl.lanes_number = LANE_COUNT_FOUR;
906882 cntl.hpd_sel = link->link_enc->hpd_source;
883
+
884
+ if (ctx->dc->ctx->dmub_srv &&
885
+ ctx->dc->debug.dmub_command_table) {
886
+ if (cntl.action == TRANSMITTER_CONTROL_POWER_ON)
887
+ bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
888
+ LVTMA_CONTROL_POWER_ON);
889
+ else
890
+ bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
891
+ LVTMA_CONTROL_POWER_OFF);
892
+ }
893
+
907894 bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
895
+
896
+ DC_LOG_HW_RESUME_S3(
897
+ "%s: END: Panel Power action: %s bp_result=%u\n",
898
+ __func__, (power_up ? "On":"Off"),
899
+ bp_result);
908900
909901 if (!power_up)
910902 /*save driver power off time stamp*/
911903 link->link_trace.time_stamp.edp_poweroff = dm_get_timestamp(ctx);
912904 else
913905 link->link_trace.time_stamp.edp_poweron = dm_get_timestamp(ctx);
906
+
907
+ DC_LOG_HW_RESUME_S3(
908
+ "%s: updated values: edp_poweroff=%llu edp_poweron=%llu\n",
909
+ __func__,
910
+ link->link_trace.time_stamp.edp_poweroff,
911
+ link->link_trace.time_stamp.edp_poweron);
914912
915913 if (bp_result != BP_RESULT_OK)
916914 DC_LOG_ERROR(
....@@ -928,12 +926,11 @@
928926 * @brief
929927 * eDP only. Control the backlight of the eDP panel
930928 */
931
-void hwss_edp_backlight_control(
929
+void dce110_edp_backlight_control(
932930 struct dc_link *link,
933931 bool enable)
934932 {
935933 struct dc_context *ctx = link->ctx;
936
- struct dce_hwseq *hws = ctx->dc->hwseq;
937934 struct bp_transmitter_control cntl = { 0 };
938935
939936 if (dal_graphics_object_id_get_connector_id(link->link_enc->connector)
....@@ -942,7 +939,8 @@
942939 return;
943940 }
944941
945
- if (enable && is_panel_backlight_on(hws)) {
942
+ if (enable && link->panel_cntl &&
943
+ link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl)) {
946944 DC_LOG_HW_RESUME_S3(
947945 "%s: panel already powered up. Do nothing.\n",
948946 __func__);
....@@ -981,52 +979,92 @@
981979 /*edp 1.2*/
982980 if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON)
983981 edp_receiver_ready_T7(link);
982
+
983
+ if (ctx->dc->ctx->dmub_srv &&
984
+ ctx->dc->debug.dmub_command_table) {
985
+ if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON)
986
+ ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
987
+ LVTMA_CONTROL_LCD_BLON);
988
+ else
989
+ ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios,
990
+ LVTMA_CONTROL_LCD_BLOFF);
991
+ }
992
+
984993 link_transmitter_control(ctx->dc_bios, &cntl);
994
+
995
+
996
+
997
+ if (enable && link->dpcd_sink_ext_caps.bits.oled)
998
+ msleep(OLED_POST_T7_DELAY);
999
+
1000
+ if (link->dpcd_sink_ext_caps.bits.oled ||
1001
+ link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 ||
1002
+ link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)
1003
+ dc_link_backlight_enable_aux(link, enable);
1004
+
9851005 /*edp 1.2*/
9861006 if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF)
9871007 edp_receiver_ready_T9(link);
1008
+
1009
+ if (!enable && link->dpcd_sink_ext_caps.bits.oled)
1010
+ msleep(OLED_PRE_T11_DELAY);
9881011 }
9891012
9901013 void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
9911014 {
992
- struct dc *core_dc = pipe_ctx->stream->ctx->dc;
9931015 /* notify audio driver for audio modes of monitor */
994
- struct pp_smu_funcs_rv *pp_smu = core_dc->res_pool->pp_smu;
1016
+ struct dc *dc;
1017
+ struct clk_mgr *clk_mgr;
9951018 unsigned int i, num_audio = 1;
1019
+
1020
+ if (!pipe_ctx->stream)
1021
+ return;
1022
+
1023
+ dc = pipe_ctx->stream->ctx->dc;
1024
+ clk_mgr = dc->clk_mgr;
1025
+
1026
+ if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == true)
1027
+ return;
9961028
9971029 if (pipe_ctx->stream_res.audio) {
9981030 for (i = 0; i < MAX_PIPES; i++) {
9991031 /*current_state not updated yet*/
1000
- if (core_dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL)
1032
+ if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL)
10011033 num_audio++;
10021034 }
10031035
10041036 pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio);
10051037
1006
- if (num_audio >= 1 && pp_smu != NULL && pp_smu->set_pme_wa_enable != NULL)
1038
+ if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa)
10071039 /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
1008
- pp_smu->set_pme_wa_enable(&pp_smu->pp_smu);
1040
+ clk_mgr->funcs->enable_pme_wa(clk_mgr);
10091041 /* un-mute audio */
10101042 /* TODO: audio should be per stream rather than per link */
10111043 pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
1012
- pipe_ctx->stream_res.stream_enc, false);
1044
+ pipe_ctx->stream_res.stream_enc, false);
1045
+ if (pipe_ctx->stream_res.audio)
1046
+ pipe_ctx->stream_res.audio->enabled = true;
10131047 }
10141048 }
10151049
1016
-void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option)
1050
+void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx)
10171051 {
1018
- struct dc *dc = pipe_ctx->stream->ctx->dc;
1052
+ struct dc *dc;
1053
+ struct clk_mgr *clk_mgr;
1054
+
1055
+ if (!pipe_ctx || !pipe_ctx->stream)
1056
+ return;
1057
+
1058
+ dc = pipe_ctx->stream->ctx->dc;
1059
+ clk_mgr = dc->clk_mgr;
1060
+
1061
+ if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false)
1062
+ return;
10191063
10201064 pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
10211065 pipe_ctx->stream_res.stream_enc, true);
10221066 if (pipe_ctx->stream_res.audio) {
1023
- struct pp_smu_funcs_rv *pp_smu = dc->res_pool->pp_smu;
1024
-
1025
- if (option != KEEP_ACQUIRED_RESOURCE ||
1026
- !dc->debug.az_endpoint_mute_only) {
1027
- /*only disalbe az_endpoint if power down or free*/
1028
- pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
1029
- }
1067
+ pipe_ctx->stream_res.audio->enabled = false;
10301068
10311069 if (dc_is_dp_signal(pipe_ctx->stream->signal))
10321070 pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable(
....@@ -1034,16 +1072,10 @@
10341072 else
10351073 pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable(
10361074 pipe_ctx->stream_res.stream_enc);
1037
- /*don't free audio if it is from retrain or internal disable stream*/
1038
- if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) {
1039
- /*we have to dynamic arbitrate the audio endpoints*/
1040
- /*we free the resource, need reset is_audio_acquired*/
1041
- update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false);
1042
- pipe_ctx->stream_res.audio = NULL;
1043
- }
1044
- if (pp_smu != NULL && pp_smu->set_pme_wa_enable != NULL)
1075
+
1076
+ if (clk_mgr->funcs->enable_pme_wa)
10451077 /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
1046
- pp_smu->set_pme_wa_enable(&pp_smu->pp_smu);
1078
+ clk_mgr->funcs->enable_pme_wa(clk_mgr);
10471079
10481080 /* TODO: notify audio driver for if audio modes list changed
10491081 * add audio mode list change flag */
....@@ -1053,21 +1085,24 @@
10531085 }
10541086 }
10551087
1056
-void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option)
1088
+void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
10571089 {
10581090 struct dc_stream_state *stream = pipe_ctx->stream;
1059
- struct dc_link *link = stream->sink->link;
1091
+ struct dc_link *link = stream->link;
10601092 struct dc *dc = pipe_ctx->stream->ctx->dc;
10611093
1062
- if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
1094
+ if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) {
10631095 pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets(
10641096 pipe_ctx->stream_res.stream_enc);
1097
+ pipe_ctx->stream_res.stream_enc->funcs->hdmi_reset_stream_attribute(
1098
+ pipe_ctx->stream_res.stream_enc);
1099
+ }
10651100
10661101 if (dc_is_dp_signal(pipe_ctx->stream->signal))
10671102 pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets(
10681103 pipe_ctx->stream_res.stream_enc);
10691104
1070
- dc->hwss.disable_audio_stream(pipe_ctx, option);
1105
+ dc->hwss.disable_audio_stream(pipe_ctx);
10711106
10721107 link->link_enc->funcs->connect_dig_be_to_fe(
10731108 link->link_enc,
....@@ -1081,33 +1116,43 @@
10811116 {
10821117 struct encoder_unblank_param params = { { 0 } };
10831118 struct dc_stream_state *stream = pipe_ctx->stream;
1084
- struct dc_link *link = stream->sink->link;
1119
+ struct dc_link *link = stream->link;
1120
+ struct dce_hwseq *hws = link->dc->hwseq;
10851121
10861122 /* only 3 items below are used by unblank */
1087
- params.pixel_clk_khz =
1088
- pipe_ctx->stream->timing.pix_clk_khz;
1123
+ params.timing = pipe_ctx->stream->timing;
10891124 params.link_settings.link_rate = link_settings->link_rate;
10901125
10911126 if (dc_is_dp_signal(pipe_ctx->stream->signal))
10921127 pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, &params);
10931128
10941129 if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
1095
- link->dc->hwss.edp_backlight_control(link, true);
1096
- stream->bl_pwm_level = EDP_BACKLIGHT_RAMP_DISABLE_LEVEL;
1130
+ hws->funcs.edp_backlight_control(link, true);
10971131 }
10981132 }
1133
+
10991134 void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
11001135 {
11011136 struct dc_stream_state *stream = pipe_ctx->stream;
1102
- struct dc_link *link = stream->sink->link;
1137
+ struct dc_link *link = stream->link;
1138
+ struct dce_hwseq *hws = link->dc->hwseq;
11031139
11041140 if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
1105
- link->dc->hwss.edp_backlight_control(link, false);
1106
- dc_link_set_abm_disable(link);
1141
+ hws->funcs.edp_backlight_control(link, false);
1142
+ link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
11071143 }
11081144
1109
- if (dc_is_dp_signal(pipe_ctx->stream->signal))
1145
+ if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
11101146 pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
1147
+
1148
+ /*
1149
+ * After output is idle pattern some sinks need time to recognize the stream
1150
+ * has changed or they enter protection state and hang.
1151
+ */
1152
+ if (!dc_is_embedded_signal(pipe_ctx->stream->signal))
1153
+ msleep(60);
1154
+ }
1155
+
11111156 }
11121157
11131158
....@@ -1172,36 +1217,37 @@
11721217 stream->timing.flags.INTERLACE;
11731218
11741219 audio_output->crtc_info.refresh_rate =
1175
- (stream->timing.pix_clk_khz*1000)/
1220
+ (stream->timing.pix_clk_100hz*100)/
11761221 (stream->timing.h_total*stream->timing.v_total);
11771222
11781223 audio_output->crtc_info.color_depth =
11791224 stream->timing.display_color_depth;
11801225
1181
- audio_output->crtc_info.requested_pixel_clock =
1182
- pipe_ctx->stream_res.pix_clk_params.requested_pix_clk;
1226
+ audio_output->crtc_info.requested_pixel_clock_100Hz =
1227
+ pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz;
11831228
1184
- audio_output->crtc_info.calculated_pixel_clock =
1185
- pipe_ctx->stream_res.pix_clk_params.requested_pix_clk;
1229
+ audio_output->crtc_info.calculated_pixel_clock_100Hz =
1230
+ pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz;
11861231
11871232 /*for HDMI, audio ACR is with deep color ratio factor*/
1188
- if (dc_is_hdmi_signal(pipe_ctx->stream->signal) &&
1189
- audio_output->crtc_info.requested_pixel_clock ==
1190
- stream->timing.pix_clk_khz) {
1233
+ if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) &&
1234
+ audio_output->crtc_info.requested_pixel_clock_100Hz ==
1235
+ (stream->timing.pix_clk_100hz)) {
11911236 if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
1192
- audio_output->crtc_info.requested_pixel_clock =
1193
- audio_output->crtc_info.requested_pixel_clock/2;
1194
- audio_output->crtc_info.calculated_pixel_clock =
1195
- pipe_ctx->stream_res.pix_clk_params.requested_pix_clk/2;
1237
+ audio_output->crtc_info.requested_pixel_clock_100Hz =
1238
+ audio_output->crtc_info.requested_pixel_clock_100Hz/2;
1239
+ audio_output->crtc_info.calculated_pixel_clock_100Hz =
1240
+ pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz/2;
11961241
11971242 }
11981243 }
11991244
1200
- if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
1201
- pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
1245
+ if (state->clk_mgr &&
1246
+ (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
1247
+ pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) {
12021248 audio_output->pll_info.dp_dto_source_clock_in_khz =
1203
- state->dis_clk->funcs->get_dp_ref_clk_frequency(
1204
- state->dis_clk);
1249
+ state->clk_mgr->funcs->get_dp_ref_clk_frequency(
1250
+ state->clk_mgr);
12051251 }
12061252
12071253 audio_output->pll_info.feed_back_divider =
....@@ -1258,7 +1304,7 @@
12581304 {
12591305 struct tg_color color = {0};
12601306
1261
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
1307
+#if defined(CONFIG_DRM_AMD_DC_DCN)
12621308 /* TOFPGA */
12631309 if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL)
12641310 return;
....@@ -1330,11 +1376,12 @@
13301376 pipe_ctx->stream_res.tg->funcs->program_timing(
13311377 pipe_ctx->stream_res.tg,
13321378 &stream->timing,
1379
+ 0,
1380
+ 0,
1381
+ 0,
1382
+ 0,
1383
+ pipe_ctx->stream->signal,
13331384 true);
1334
-
1335
- pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
1336
- pipe_ctx->stream_res.tg,
1337
- 0x182);
13381385 }
13391386
13401387 if (!pipe_ctx_old->stream) {
....@@ -1345,8 +1392,6 @@
13451392 }
13461393 }
13471394
1348
-
1349
-
13501395 return DC_OK;
13511396 }
13521397
....@@ -1356,8 +1401,14 @@
13561401 struct dc *dc)
13571402 {
13581403 struct dc_stream_state *stream = pipe_ctx->stream;
1359
- struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx.
1360
- pipe_ctx[pipe_ctx->pipe_idx];
1404
+ struct drr_params params = {0};
1405
+ unsigned int event_triggers = 0;
1406
+ struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
1407
+ struct dce_hwseq *hws = dc->hwseq;
1408
+
1409
+ if (hws->funcs.disable_stream_gating) {
1410
+ hws->funcs.disable_stream_gating(dc, pipe_ctx);
1411
+ }
13611412
13621413 if (pipe_ctx->stream_res.audio != NULL) {
13631414 struct audio_output audio_output;
....@@ -1384,79 +1435,65 @@
13841435 }
13851436
13861437 /* */
1387
- dc->hwss.enable_stream_timing(pipe_ctx, context, dc);
1438
+ /* Do not touch stream timing on seamless boot optimization. */
1439
+ if (!pipe_ctx->stream->apply_seamless_boot_optimization)
1440
+ hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
13881441
1389
- /* FPGA does not program backend */
1390
- if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
1391
- pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
1392
- pipe_ctx->stream_res.opp,
1393
- COLOR_SPACE_YCBCR601,
1394
- stream->timing.display_color_depth,
1395
- pipe_ctx->stream->signal);
1442
+ if (hws->funcs.setup_vupdate_interrupt)
1443
+ hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
13961444
1397
- pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
1398
- pipe_ctx->stream_res.opp,
1399
- &stream->bit_depth_params,
1400
- &stream->clamping);
1401
- return DC_OK;
1402
- }
1403
- /* TODO: move to stream encoder */
1404
- if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL)
1405
- if (DC_OK != bios_parser_crtc_source_select(pipe_ctx)) {
1406
- BREAK_TO_DEBUGGER();
1407
- return DC_ERROR_UNEXPECTED;
1408
- }
1445
+ params.vertical_total_min = stream->adjust.v_total_min;
1446
+ params.vertical_total_max = stream->adjust.v_total_max;
1447
+ if (pipe_ctx->stream_res.tg->funcs->set_drr)
1448
+ pipe_ctx->stream_res.tg->funcs->set_drr(
1449
+ pipe_ctx->stream_res.tg, &params);
1450
+
1451
+ // DRR should set trigger event to monitor surface update event
1452
+ if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
1453
+ event_triggers = 0x80;
1454
+ /* Event triggers and num frames initialized for DRR, but can be
1455
+ * later updated for PSR use. Note DRR trigger events are generated
1456
+ * regardless of whether num frames met.
1457
+ */
1458
+ if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
1459
+ pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
1460
+ pipe_ctx->stream_res.tg, event_triggers, 2);
1461
+
1462
+ if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
1463
+ pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg(
1464
+ pipe_ctx->stream_res.stream_enc,
1465
+ pipe_ctx->stream_res.tg->inst);
1466
+
14091467 pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion(
14101468 pipe_ctx->stream_res.opp,
14111469 COLOR_SPACE_YCBCR601,
14121470 stream->timing.display_color_depth,
1413
- pipe_ctx->stream->signal);
1414
-
1415
- if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL)
1416
- stream->sink->link->link_enc->funcs->setup(
1417
- stream->sink->link->link_enc,
1418
- pipe_ctx->stream->signal);
1419
-
1420
- if (pipe_ctx->stream->signal != SIGNAL_TYPE_VIRTUAL)
1421
- pipe_ctx->stream_res.stream_enc->funcs->setup_stereo_sync(
1422
- pipe_ctx->stream_res.stream_enc,
1423
- pipe_ctx->stream_res.tg->inst,
1424
- stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE);
1425
-
1471
+ stream->signal);
14261472
14271473 pipe_ctx->stream_res.opp->funcs->opp_program_fmt(
14281474 pipe_ctx->stream_res.opp,
14291475 &stream->bit_depth_params,
14301476 &stream->clamping);
1477
+ while (odm_pipe) {
1478
+ odm_pipe->stream_res.opp->funcs->opp_set_dyn_expansion(
1479
+ odm_pipe->stream_res.opp,
1480
+ COLOR_SPACE_YCBCR601,
1481
+ stream->timing.display_color_depth,
1482
+ stream->signal);
14311483
1432
- if (dc_is_dp_signal(pipe_ctx->stream->signal))
1433
- pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(
1434
- pipe_ctx->stream_res.stream_enc,
1435
- &stream->timing,
1436
- stream->output_color_space);
1484
+ odm_pipe->stream_res.opp->funcs->opp_program_fmt(
1485
+ odm_pipe->stream_res.opp,
1486
+ &stream->bit_depth_params,
1487
+ &stream->clamping);
1488
+ odm_pipe = odm_pipe->next_odm_pipe;
1489
+ }
14371490
1438
- if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
1439
- pipe_ctx->stream_res.stream_enc->funcs->hdmi_set_stream_attribute(
1440
- pipe_ctx->stream_res.stream_enc,
1441
- &stream->timing,
1442
- stream->phy_pix_clk,
1443
- pipe_ctx->stream_res.audio != NULL);
1444
-
1445
- if (dc_is_dvi_signal(pipe_ctx->stream->signal))
1446
- pipe_ctx->stream_res.stream_enc->funcs->dvi_set_stream_attribute(
1447
- pipe_ctx->stream_res.stream_enc,
1448
- &stream->timing,
1449
- (pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ?
1450
- true : false);
1451
-
1452
- resource_build_info_frame(pipe_ctx);
1453
- dce110_update_info_frame(pipe_ctx);
1454
- if (!pipe_ctx_old->stream)
1491
+ if (!stream->dpms_off)
14551492 core_link_enable_stream(context, pipe_ctx);
14561493
14571494 pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
14581495
1459
- pipe_ctx->stream->sink->link->psr_enabled = false;
1496
+ pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false;
14601497
14611498 return DC_OK;
14621499 }
....@@ -1466,8 +1503,6 @@
14661503 static void power_down_encoders(struct dc *dc)
14671504 {
14681505 int i;
1469
- enum connector_id connector_id;
1470
- enum signal_type signal = SIGNAL_TYPE_NONE;
14711506
14721507 /* do not know BIOS back-front mapping, simply blank all. It will not
14731508 * hurt for non-DP
....@@ -1478,18 +1513,20 @@
14781513 }
14791514
14801515 for (i = 0; i < dc->link_count; i++) {
1481
- connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id);
1482
- if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
1483
- (connector_id == CONNECTOR_ID_EDP)) {
1516
+ enum signal_type signal = dc->links[i]->connector_signal;
14841517
1518
+ if ((signal == SIGNAL_TYPE_EDP) ||
1519
+ (signal == SIGNAL_TYPE_DISPLAY_PORT))
14851520 if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
14861521 dp_receiver_power_ctrl(dc->links[i], false);
1487
- if (connector_id == CONNECTOR_ID_EDP)
1488
- signal = SIGNAL_TYPE_EDP;
1489
- }
1522
+
1523
+ if (signal != SIGNAL_TYPE_EDP)
1524
+ signal = SIGNAL_TYPE_NONE;
14901525
14911526 dc->links[i]->link_enc->funcs->disable_output(
14921527 dc->links[i]->link_enc, signal);
1528
+
1529
+ dc->links[i]->link_status.link_active = false;
14931530 }
14941531 }
14951532
....@@ -1555,29 +1592,24 @@
15551592 }
15561593 }
15571594
1558
-static struct dc_link *get_link_for_edp(struct dc *dc)
1595
+
1596
+static struct dc_stream_state *get_edp_stream(struct dc_state *context)
15591597 {
15601598 int i;
15611599
1562
- for (i = 0; i < dc->link_count; i++) {
1563
- if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP)
1564
- return dc->links[i];
1600
+ for (i = 0; i < context->stream_count; i++) {
1601
+ if (context->streams[i]->signal == SIGNAL_TYPE_EDP)
1602
+ return context->streams[i];
15651603 }
15661604 return NULL;
15671605 }
15681606
1569
-static struct dc_link *get_link_for_edp_not_in_use(
1607
+static struct dc_link *get_edp_link_with_sink(
15701608 struct dc *dc,
15711609 struct dc_state *context)
15721610 {
15731611 int i;
15741612 struct dc_link *link = NULL;
1575
-
1576
- /* check if eDP panel is suppose to be set mode, if yes, no need to disable */
1577
- for (i = 0; i < context->stream_count; i++) {
1578
- if (context->streams[i]->signal == SIGNAL_TYPE_EDP)
1579
- return NULL;
1580
- }
15811613
15821614 /* check if there is an eDP panel not in use */
15831615 for (i = 0; i < dc->link_count; i++) {
....@@ -1600,41 +1632,60 @@
16001632 */
16011633 void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
16021634 {
1603
- struct dc_link *edp_link_to_turnoff = NULL;
1604
- struct dc_link *edp_link = get_link_for_edp(dc);
1605
- bool can_eDP_fast_boot_optimize = false;
1635
+ int i;
1636
+ struct dc_link *edp_link_with_sink = get_edp_link_with_sink(dc, context);
1637
+ struct dc_link *edp_link = get_edp_link(dc);
1638
+ struct dc_stream_state *edp_stream = NULL;
1639
+ bool can_apply_edp_fast_boot = false;
1640
+ bool can_apply_seamless_boot = false;
1641
+ bool keep_edp_vdd_on = false;
1642
+ struct dce_hwseq *hws = dc->hwseq;
16061643
1607
- if (edp_link) {
1608
- /* this seems to cause blank screens on DCE8 */
1609
- if ((dc->ctx->dce_version == DCE_VERSION_8_0) ||
1610
- (dc->ctx->dce_version == DCE_VERSION_8_1) ||
1611
- (dc->ctx->dce_version == DCE_VERSION_8_3))
1612
- can_eDP_fast_boot_optimize = false;
1613
- else
1614
- can_eDP_fast_boot_optimize =
1615
- edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc);
1644
+ if (hws->funcs.init_pipes)
1645
+ hws->funcs.init_pipes(dc, context);
1646
+
1647
+ edp_stream = get_edp_stream(context);
1648
+
1649
+ // Check fastboot support, disable on DCE8 because of blank screens
1650
+ if (edp_link && dc->ctx->dce_version != DCE_VERSION_8_0 &&
1651
+ dc->ctx->dce_version != DCE_VERSION_8_1 &&
1652
+ dc->ctx->dce_version != DCE_VERSION_8_3) {
1653
+
1654
+ // enable fastboot if backend is enabled on eDP
1655
+ if (edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc)) {
1656
+ /* Set optimization flag on eDP stream*/
1657
+ if (edp_stream && edp_link->link_status.link_active) {
1658
+ edp_stream->apply_edp_fast_boot_optimization = true;
1659
+ can_apply_edp_fast_boot = true;
1660
+ }
1661
+ }
1662
+
1663
+ // We are trying to enable eDP, don't power down VDD
1664
+ if (edp_stream)
1665
+ keep_edp_vdd_on = true;
16161666 }
16171667
1618
- if (can_eDP_fast_boot_optimize) {
1619
- edp_link_to_turnoff = get_link_for_edp_not_in_use(dc, context);
1620
-
1621
- /* if OS doesn't light up eDP and eDP link is available, we want to disable
1622
- * If resume from S4/S5, should optimization.
1623
- */
1624
- if (!edp_link_to_turnoff)
1625
- dc->apply_edp_fast_boot_optimization = true;
1668
+ // Check seamless boot support
1669
+ for (i = 0; i < context->stream_count; i++) {
1670
+ if (context->streams[i]->apply_seamless_boot_optimization) {
1671
+ can_apply_seamless_boot = true;
1672
+ break;
1673
+ }
16261674 }
16271675
1628
- if (!dc->apply_edp_fast_boot_optimization) {
1629
- if (edp_link_to_turnoff) {
1676
+ /* eDP should not have stream in resume from S4 and so even with VBios post
1677
+ * it should get turned off
1678
+ */
1679
+ if (!can_apply_edp_fast_boot && !can_apply_seamless_boot) {
1680
+ if (edp_link_with_sink && !keep_edp_vdd_on) {
16301681 /*turn off backlight before DP_blank and encoder powered down*/
1631
- dc->hwss.edp_backlight_control(edp_link_to_turnoff, false);
1682
+ hws->funcs.edp_backlight_control(edp_link_with_sink, false);
16321683 }
16331684 /*resume from S3, no vbios posting, no need to power down again*/
16341685 power_down_all_hw_blocks(dc);
16351686 disable_vga_and_power_gate_all_controllers(dc);
1636
- if (edp_link_to_turnoff)
1637
- dc->hwss.edp_power_control(edp_link_to_turnoff, false);
1687
+ if (edp_link_with_sink && !keep_edp_vdd_on)
1688
+ dc->hwss.edp_power_control(edp_link_with_sink, false);
16381689 }
16391690 bios_set_scratch_acc_mode_change(dc->ctx->dc_bios);
16401691 }
....@@ -1649,8 +1700,8 @@
16491700 pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24;
16501701
16511702 total_dest_line_time_ns = 1000000UL *
1652
- stream->timing.h_total /
1653
- stream->timing.pix_clk_khz +
1703
+ (stream->timing.h_total * 10) /
1704
+ stream->timing.pix_clk_100hz +
16541705 pstate_blackout_duration_ns;
16551706
16561707 return total_dest_line_time_ns;
....@@ -1674,18 +1725,18 @@
16741725 dc->bw_vbios->blackout_duration, pipe_ctx->stream);
16751726 pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks(
16761727 pipe_ctx->plane_res.mi,
1677
- context->bw.dce.nbp_state_change_wm_ns[num_pipes],
1678
- context->bw.dce.stutter_exit_wm_ns[num_pipes],
1679
- context->bw.dce.stutter_entry_wm_ns[num_pipes],
1680
- context->bw.dce.urgent_wm_ns[num_pipes],
1728
+ context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
1729
+ context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
1730
+ context->bw_ctx.bw.dce.stutter_entry_wm_ns[num_pipes],
1731
+ context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
16811732 total_dest_line_time_ns);
16821733 if (i == underlay_idx) {
16831734 num_pipes++;
16841735 pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks(
16851736 pipe_ctx->plane_res.mi,
1686
- context->bw.dce.nbp_state_change_wm_ns[num_pipes],
1687
- context->bw.dce.stutter_exit_wm_ns[num_pipes],
1688
- context->bw.dce.urgent_wm_ns[num_pipes],
1737
+ context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
1738
+ context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
1739
+ context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
16891740 total_dest_line_time_ns);
16901741 }
16911742 num_pipes++;
....@@ -1732,20 +1783,31 @@
17321783 ******************************************************************************/
17331784
17341785 static void set_drr(struct pipe_ctx **pipe_ctx,
1735
- int num_pipes, int vmin, int vmax)
1786
+ int num_pipes, unsigned int vmin, unsigned int vmax,
1787
+ unsigned int vmid, unsigned int vmid_frame_number)
17361788 {
17371789 int i = 0;
17381790 struct drr_params params = {0};
1791
+ // DRR should set trigger event to monitor surface update event
1792
+ unsigned int event_triggers = 0x80;
1793
+ // Note DRR trigger events are generated regardless of whether num frames met.
1794
+ unsigned int num_frames = 2;
17391795
17401796 params.vertical_total_max = vmax;
17411797 params.vertical_total_min = vmin;
17421798
17431799 /* TODO: If multiple pipes are to be supported, you need
1744
- * some GSL stuff
1800
+ * some GSL stuff. Static screen triggers may be programmed differently
1801
+ * as well.
17451802 */
1746
-
17471803 for (i = 0; i < num_pipes; i++) {
1748
- pipe_ctx[i]->stream_res.tg->funcs->set_drr(pipe_ctx[i]->stream_res.tg, &params);
1804
+ pipe_ctx[i]->stream_res.tg->funcs->set_drr(
1805
+ pipe_ctx[i]->stream_res.tg, &params);
1806
+
1807
+ if (vmax != 0 && vmin != 0)
1808
+ pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
1809
+ pipe_ctx[i]->stream_res.tg,
1810
+ event_triggers, num_frames);
17491811 }
17501812 }
17511813
....@@ -1762,65 +1824,44 @@
17621824 }
17631825
17641826 static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
1765
- int num_pipes, const struct dc_static_screen_events *events)
1827
+ int num_pipes, const struct dc_static_screen_params *params)
17661828 {
17671829 unsigned int i;
1768
- unsigned int value = 0;
1830
+ unsigned int triggers = 0;
17691831
1770
- if (events->overlay_update)
1771
- value |= 0x100;
1772
- if (events->surface_update)
1773
- value |= 0x80;
1774
- if (events->cursor_update)
1775
- value |= 0x2;
1776
- if (events->force_trigger)
1777
- value |= 0x1;
1832
+ if (params->triggers.overlay_update)
1833
+ triggers |= 0x100;
1834
+ if (params->triggers.surface_update)
1835
+ triggers |= 0x80;
1836
+ if (params->triggers.cursor_update)
1837
+ triggers |= 0x2;
1838
+ if (params->triggers.force_trigger)
1839
+ triggers |= 0x1;
17781840
1779
- value |= 0x84;
1841
+ if (num_pipes) {
1842
+ struct dc *dc = pipe_ctx[0]->stream->ctx->dc;
1843
+
1844
+ if (dc->fbc_compressor)
1845
+ triggers |= 0x84;
1846
+ }
17801847
17811848 for (i = 0; i < num_pipes; i++)
17821849 pipe_ctx[i]->stream_res.tg->funcs->
1783
- set_static_screen_control(pipe_ctx[i]->stream_res.tg, value);
1784
-}
1785
-
1786
-/* unit: in_khz before mode set, get pixel clock from context. ASIC register
1787
- * may not be programmed yet
1788
- */
1789
-static uint32_t get_max_pixel_clock_for_all_paths(
1790
- struct dc *dc,
1791
- struct dc_state *context)
1792
-{
1793
- uint32_t max_pix_clk = 0;
1794
- int i;
1795
-
1796
- for (i = 0; i < MAX_PIPES; i++) {
1797
- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
1798
-
1799
- if (pipe_ctx->stream == NULL)
1800
- continue;
1801
-
1802
- /* do not check under lay */
1803
- if (pipe_ctx->top_pipe)
1804
- continue;
1805
-
1806
- if (pipe_ctx->stream_res.pix_clk_params.requested_pix_clk > max_pix_clk)
1807
- max_pix_clk =
1808
- pipe_ctx->stream_res.pix_clk_params.requested_pix_clk;
1809
- }
1810
-
1811
- return max_pix_clk;
1850
+ set_static_screen_control(pipe_ctx[i]->stream_res.tg,
1851
+ triggers, params->num_frames);
18121852 }
18131853
18141854 /*
18151855 * Check if FBC can be enabled
18161856 */
18171857 static bool should_enable_fbc(struct dc *dc,
1818
- struct dc_state *context,
1819
- uint32_t *pipe_idx)
1858
+ struct dc_state *context,
1859
+ uint32_t *pipe_idx)
18201860 {
18211861 uint32_t i;
18221862 struct pipe_ctx *pipe_ctx = NULL;
18231863 struct resource_context *res_ctx = &context->res_ctx;
1864
+ unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
18241865
18251866
18261867 ASSERT(dc->fbc_compressor);
....@@ -1835,21 +1876,32 @@
18351876
18361877 for (i = 0; i < dc->res_pool->pipe_count; i++) {
18371878 if (res_ctx->pipe_ctx[i].stream) {
1879
+
18381880 pipe_ctx = &res_ctx->pipe_ctx[i];
1839
- *pipe_idx = i;
1840
- break;
1881
+
1882
+ if (!pipe_ctx)
1883
+ continue;
1884
+
1885
+ /* fbc not applicable on underlay pipe */
1886
+ if (pipe_ctx->pipe_idx != underlay_idx) {
1887
+ *pipe_idx = i;
1888
+ break;
1889
+ }
18411890 }
18421891 }
18431892
1844
- /* Pipe context should be found */
1845
- ASSERT(pipe_ctx);
1893
+ if (i == dc->res_pool->pipe_count)
1894
+ return false;
1895
+
1896
+ if (!pipe_ctx->stream->link)
1897
+ return false;
18461898
18471899 /* Only supports eDP */
1848
- if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP)
1900
+ if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP)
18491901 return false;
18501902
18511903 /* PSR should not be enabled */
1852
- if (pipe_ctx->stream->sink->link->psr_enabled)
1904
+ if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled)
18531905 return false;
18541906
18551907 /* Nothing to compress */
....@@ -1866,8 +1918,9 @@
18661918 /*
18671919 * Enable FBC
18681920 */
1869
-static void enable_fbc(struct dc *dc,
1870
- struct dc_state *context)
1921
+static void enable_fbc(
1922
+ struct dc *dc,
1923
+ struct dc_state *context)
18711924 {
18721925 uint32_t pipe_idx = 0;
18731926
....@@ -1877,10 +1930,9 @@
18771930 struct compressor *compr = dc->fbc_compressor;
18781931 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
18791932
1880
-
18811933 params.source_view_width = pipe_ctx->stream->timing.h_addressable;
18821934 params.source_view_height = pipe_ctx->stream->timing.v_addressable;
1883
-
1935
+ params.inst = pipe_ctx->stream_res.tg->inst;
18841936 compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr;
18851937
18861938 compr->funcs->surface_address_and_pitch(compr, &params);
....@@ -1919,8 +1971,25 @@
19191971 /* Disable if new stream is null. O/w, if stream is
19201972 * disabled already, no need to disable again.
19211973 */
1922
- if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off)
1923
- core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE);
1974
+ if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) {
1975
+ core_link_disable_stream(pipe_ctx_old);
1976
+
1977
+ /* free acquired resources*/
1978
+ if (pipe_ctx_old->stream_res.audio) {
1979
+ /*disable az_endpoint*/
1980
+ pipe_ctx_old->stream_res.audio->funcs->
1981
+ az_disable(pipe_ctx_old->stream_res.audio);
1982
+
1983
+ /*free audio*/
1984
+ if (dc->caps.dynamic_audio == true) {
1985
+ /*we have to dynamic arbitrate the audio endpoints*/
1986
+ /*we free the resource, need reset is_audio_acquired*/
1987
+ update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
1988
+ pipe_ctx_old->stream_res.audio, false);
1989
+ pipe_ctx_old->stream_res.audio = NULL;
1990
+ }
1991
+ }
1992
+ }
19241993
19251994 pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
19261995 if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
....@@ -1976,11 +2045,10 @@
19762045
19772046 if (pipe_ctx->top_pipe)
19782047 continue;
1979
-
19802048 if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A)
19812049 continue;
1982
-
1983
- if (pipe_ctx->stream_res.audio != NULL) {
2050
+ if (pipe_ctx->stream_res.audio != NULL &&
2051
+ pipe_ctx->stream_res.audio->enabled == false) {
19842052 struct audio_output audio_output;
19852053
19862054 build_audio_output(context, pipe_ctx, &audio_output);
....@@ -2008,7 +2076,8 @@
20082076 if (!dc_is_dp_signal(pipe_ctx->stream->signal))
20092077 continue;
20102078
2011
- if (pipe_ctx->stream_res.audio != NULL) {
2079
+ if (pipe_ctx->stream_res.audio != NULL &&
2080
+ pipe_ctx->stream_res.audio->enabled == false) {
20122081 struct audio_output audio_output;
20132082
20142083 build_audio_output(context, pipe_ctx, &audio_output);
....@@ -2028,13 +2097,14 @@
20282097 struct dc *dc,
20292098 struct dc_state *context)
20302099 {
2100
+ struct dce_hwseq *hws = dc->hwseq;
20312101 struct dc_bios *dcb = dc->ctx->dc_bios;
20322102 enum dc_status status;
20332103 int i;
20342104
20352105 /* Reset old context */
20362106 /* look up the targets that have been removed since last commit */
2037
- dc->hwss.reset_hw_ctx_wrap(dc, context);
2107
+ hws->funcs.reset_hw_ctx_wrap(dc, context);
20382108
20392109 /* Skip applying if no targets */
20402110 if (context->stream_count <= 0)
....@@ -2059,7 +2129,7 @@
20592129 continue;
20602130 }
20612131
2062
- dc->hwss.enable_display_power_gating(
2132
+ hws->funcs.enable_display_power_gating(
20632133 dc, i, dc->ctx->dc_bios,
20642134 PIPE_GATING_CONTROL_DISABLE);
20652135 }
....@@ -2077,13 +2147,15 @@
20772147 if (pipe_ctx->stream == NULL)
20782148 continue;
20792149
2080
- if (pipe_ctx->stream == pipe_ctx_old->stream)
2150
+ if (pipe_ctx->stream == pipe_ctx_old->stream &&
2151
+ pipe_ctx->stream->link->link_state_valid) {
20812152 continue;
2153
+ }
20822154
20832155 if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
20842156 continue;
20852157
2086
- if (pipe_ctx->top_pipe)
2158
+ if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe)
20872159 continue;
20882160
20892161 status = apply_single_controller_ctx_to_hw(
....@@ -2095,10 +2167,10 @@
20952167 return status;
20962168 }
20972169
2098
- dcb->funcs->set_scratch_critical_state(dcb, false);
2099
-
21002170 if (dc->fbc_compressor)
2101
- enable_fbc(dc, context);
2171
+ enable_fbc(dc, dc->current_state);
2172
+
2173
+ dcb->funcs->set_scratch_critical_state(dcb, false);
21022174
21032175 return DC_OK;
21042176 }
....@@ -2331,7 +2403,7 @@
23312403 int i;
23322404
23332405 gsl_params.gsl_group = 0;
2334
- gsl_params.gsl_master = grouped_pipes[0]->stream->triggered_crtc_reset.event_source->status.primary_otg_inst;
2406
+ gsl_params.gsl_master = 0;
23352407
23362408 for (i = 0; i < group_size; i++)
23372409 grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
....@@ -2354,25 +2426,33 @@
23542426
23552427 }
23562428
2429
+static void init_pipes(struct dc *dc, struct dc_state *context)
2430
+{
2431
+ // Do nothing
2432
+}
2433
+
23572434 static void init_hw(struct dc *dc)
23582435 {
23592436 int i;
23602437 struct dc_bios *bp;
23612438 struct transform *xfm;
23622439 struct abm *abm;
2440
+ struct dmcu *dmcu;
2441
+ struct dce_hwseq *hws = dc->hwseq;
2442
+ uint32_t backlight = MAX_BACKLIGHT_LEVEL;
23632443
23642444 bp = dc->ctx->dc_bios;
23652445 for (i = 0; i < dc->res_pool->pipe_count; i++) {
23662446 xfm = dc->res_pool->transforms[i];
23672447 xfm->funcs->transform_reset(xfm);
23682448
2369
- dc->hwss.enable_display_power_gating(
2449
+ hws->funcs.enable_display_power_gating(
23702450 dc, i, bp,
23712451 PIPE_GATING_CONTROL_INIT);
2372
- dc->hwss.enable_display_power_gating(
2452
+ hws->funcs.enable_display_power_gating(
23732453 dc, i, bp,
23742454 PIPE_GATING_CONTROL_DISABLE);
2375
- dc->hwss.enable_display_pipe_clock_gating(
2455
+ hws->funcs.enable_display_pipe_clock_gating(
23762456 dc->ctx,
23772457 true);
23782458 }
....@@ -2386,9 +2466,6 @@
23862466 * required signal (which may be different from the
23872467 * default signal on connector). */
23882468 struct dc_link *link = dc->links[i];
2389
-
2390
- if (link->link_enc->connector.id == CONNECTOR_ID_EDP)
2391
- dc->hwss.edp_power_control(link, true);
23922469
23932470 link->link_enc->funcs->hw_init(link->link_enc);
23942471 }
....@@ -2409,213 +2486,67 @@
24092486 audio->funcs->hw_init(audio);
24102487 }
24112488
2412
- abm = dc->res_pool->abm;
2413
- if (abm != NULL) {
2414
- abm->funcs->init_backlight(abm);
2415
- abm->funcs->abm_init(abm);
2489
+ for (i = 0; i < dc->link_count; i++) {
2490
+ struct dc_link *link = dc->links[i];
2491
+
2492
+ if (link->panel_cntl)
2493
+ backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
24162494 }
2495
+
2496
+ abm = dc->res_pool->abm;
2497
+ if (abm != NULL)
2498
+ abm->funcs->abm_init(abm, backlight);
2499
+
2500
+ dmcu = dc->res_pool->dmcu;
2501
+ if (dmcu != NULL && abm != NULL)
2502
+ abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
24172503
24182504 if (dc->fbc_compressor)
24192505 dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);
24202506
24212507 }
24222508
2423
-void dce110_fill_display_configs(
2424
- const struct dc_state *context,
2425
- struct dm_pp_display_configuration *pp_display_cfg)
2426
-{
2427
- int j;
2428
- int num_cfgs = 0;
24292509
2430
- for (j = 0; j < context->stream_count; j++) {
2431
- int k;
2432
-
2433
- const struct dc_stream_state *stream = context->streams[j];
2434
- struct dm_pp_single_disp_config *cfg =
2435
- &pp_display_cfg->disp_configs[num_cfgs];
2436
- const struct pipe_ctx *pipe_ctx = NULL;
2437
-
2438
- for (k = 0; k < MAX_PIPES; k++)
2439
- if (stream == context->res_ctx.pipe_ctx[k].stream) {
2440
- pipe_ctx = &context->res_ctx.pipe_ctx[k];
2441
- break;
2442
- }
2443
-
2444
- ASSERT(pipe_ctx != NULL);
2445
-
2446
- /* only notify active stream */
2447
- if (stream->dpms_off)
2448
- continue;
2449
-
2450
- num_cfgs++;
2451
- cfg->signal = pipe_ctx->stream->signal;
2452
- cfg->pipe_idx = pipe_ctx->stream_res.tg->inst;
2453
- cfg->src_height = stream->src.height;
2454
- cfg->src_width = stream->src.width;
2455
- cfg->ddi_channel_mapping =
2456
- stream->sink->link->ddi_channel_mapping.raw;
2457
- cfg->transmitter =
2458
- stream->sink->link->link_enc->transmitter;
2459
- cfg->link_settings.lane_count =
2460
- stream->sink->link->cur_link_settings.lane_count;
2461
- cfg->link_settings.link_rate =
2462
- stream->sink->link->cur_link_settings.link_rate;
2463
- cfg->link_settings.link_spread =
2464
- stream->sink->link->cur_link_settings.link_spread;
2465
- cfg->sym_clock = stream->phy_pix_clk;
2466
- /* Round v_refresh*/
2467
- cfg->v_refresh = stream->timing.pix_clk_khz * 1000;
2468
- cfg->v_refresh /= stream->timing.h_total;
2469
- cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2)
2470
- / stream->timing.v_total;
2471
- }
2472
-
2473
- pp_display_cfg->display_count = num_cfgs;
2474
-}
2475
-
2476
-uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context)
2477
-{
2478
- uint8_t j;
2479
- uint32_t min_vertical_blank_time = -1;
2480
-
2481
- for (j = 0; j < context->stream_count; j++) {
2482
- struct dc_stream_state *stream = context->streams[j];
2483
- uint32_t vertical_blank_in_pixels = 0;
2484
- uint32_t vertical_blank_time = 0;
2485
-
2486
- vertical_blank_in_pixels = stream->timing.h_total *
2487
- (stream->timing.v_total
2488
- - stream->timing.v_addressable);
2489
-
2490
- vertical_blank_time = vertical_blank_in_pixels
2491
- * 1000 / stream->timing.pix_clk_khz;
2492
-
2493
- if (min_vertical_blank_time > vertical_blank_time)
2494
- min_vertical_blank_time = vertical_blank_time;
2495
- }
2496
-
2497
- return min_vertical_blank_time;
2498
-}
2499
-
2500
-static int determine_sclk_from_bounding_box(
2501
- const struct dc *dc,
2502
- int required_sclk)
2503
-{
2504
- int i;
2505
-
2506
- /*
2507
- * Some asics do not give us sclk levels, so we just report the actual
2508
- * required sclk
2509
- */
2510
- if (dc->sclk_lvls.num_levels == 0)
2511
- return required_sclk;
2512
-
2513
- for (i = 0; i < dc->sclk_lvls.num_levels; i++) {
2514
- if (dc->sclk_lvls.clocks_in_khz[i] >= required_sclk)
2515
- return dc->sclk_lvls.clocks_in_khz[i];
2516
- }
2517
- /*
2518
- * even maximum level could not satisfy requirement, this
2519
- * is unexpected at this stage, should have been caught at
2520
- * validation time
2521
- */
2522
- ASSERT(0);
2523
- return dc->sclk_lvls.clocks_in_khz[dc->sclk_lvls.num_levels - 1];
2524
-}
2525
-
2526
-static void pplib_apply_display_requirements(
2527
- struct dc *dc,
2528
- struct dc_state *context)
2529
-{
2530
- struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg;
2531
-
2532
- pp_display_cfg->all_displays_in_sync =
2533
- context->bw.dce.all_displays_in_sync;
2534
- pp_display_cfg->nb_pstate_switch_disable =
2535
- context->bw.dce.nbp_state_change_enable == false;
2536
- pp_display_cfg->cpu_cc6_disable =
2537
- context->bw.dce.cpuc_state_change_enable == false;
2538
- pp_display_cfg->cpu_pstate_disable =
2539
- context->bw.dce.cpup_state_change_enable == false;
2540
- pp_display_cfg->cpu_pstate_separation_time =
2541
- context->bw.dce.blackout_recovery_time_us;
2542
-
2543
- pp_display_cfg->min_memory_clock_khz = context->bw.dce.yclk_khz
2544
- / MEMORY_TYPE_MULTIPLIER;
2545
-
2546
- pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box(
2547
- dc,
2548
- context->bw.dce.sclk_khz);
2549
-
2550
- pp_display_cfg->min_dcfclock_khz = pp_display_cfg->min_engine_clock_khz;
2551
-
2552
- pp_display_cfg->min_engine_clock_deep_sleep_khz
2553
- = context->bw.dce.sclk_deep_sleep_khz;
2554
-
2555
- pp_display_cfg->avail_mclk_switch_time_us =
2556
- dce110_get_min_vblank_time_us(context);
2557
- /* TODO: dce11.2*/
2558
- pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0;
2559
-
2560
- pp_display_cfg->disp_clk_khz = dc->res_pool->dccg->clks.dispclk_khz;
2561
-
2562
- dce110_fill_display_configs(context, pp_display_cfg);
2563
-
2564
- /* TODO: is this still applicable?*/
2565
- if (pp_display_cfg->display_count == 1) {
2566
- const struct dc_crtc_timing *timing =
2567
- &context->streams[0]->timing;
2568
-
2569
- pp_display_cfg->crtc_index =
2570
- pp_display_cfg->disp_configs[0].pipe_idx;
2571
- pp_display_cfg->line_time_in_us = timing->h_total * 1000
2572
- / timing->pix_clk_khz;
2573
- }
2574
-
2575
- if (memcmp(&dc->prev_display_config, pp_display_cfg, sizeof(
2576
- struct dm_pp_display_configuration)) != 0)
2577
- dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg);
2578
-
2579
- dc->prev_display_config = *pp_display_cfg;
2580
-}
2581
-
2582
-static void dce110_set_bandwidth(
2510
+void dce110_prepare_bandwidth(
25832511 struct dc *dc,
2584
- struct dc_state *context,
2585
- bool decrease_allowed)
2512
+ struct dc_state *context)
25862513 {
2587
- struct dc_clocks req_clks;
2514
+ struct clk_mgr *dccg = dc->clk_mgr;
25882515
2589
- req_clks.dispclk_khz = context->bw.dce.dispclk_khz;
2590
- req_clks.phyclk_khz = get_max_pixel_clock_for_all_paths(dc, context);
2516
+ dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
25912517
2592
- if (decrease_allowed)
2593
- dce110_set_displaymarks(dc, context);
2594
- else
2595
- dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
2518
+ dccg->funcs->update_clocks(
2519
+ dccg,
2520
+ context,
2521
+ false);
2522
+}
25962523
2597
- dc->res_pool->dccg->funcs->update_clocks(
2598
- dc->res_pool->dccg,
2599
- &req_clks,
2600
- decrease_allowed);
2601
- pplib_apply_display_requirements(dc, context);
2524
+void dce110_optimize_bandwidth(
2525
+ struct dc *dc,
2526
+ struct dc_state *context)
2527
+{
2528
+ struct clk_mgr *dccg = dc->clk_mgr;
2529
+
2530
+ dce110_set_displaymarks(dc, context);
2531
+
2532
+ dccg->funcs->update_clocks(
2533
+ dccg,
2534
+ context,
2535
+ true);
26022536 }
26032537
26042538 static void dce110_program_front_end_for_pipe(
26052539 struct dc *dc, struct pipe_ctx *pipe_ctx)
26062540 {
26072541 struct mem_input *mi = pipe_ctx->plane_res.mi;
2608
- struct pipe_ctx *old_pipe = NULL;
26092542 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
26102543 struct xfm_grph_csc_adjustment adjust;
26112544 struct out_csc_color_matrix tbl_entry;
2612
- unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
26132545 unsigned int i;
2546
+ struct dce_hwseq *hws = dc->hwseq;
2547
+
26142548 DC_LOGGER_INIT();
26152549 memset(&tbl_entry, 0, sizeof(tbl_entry));
2616
-
2617
- if (dc->current_state)
2618
- old_pipe = &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
26192550
26202551 memset(&adjust, 0, sizeof(adjust));
26212552 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
....@@ -2650,15 +2581,6 @@
26502581
26512582 program_scaler(dc, pipe_ctx);
26522583
2653
- /* fbc not applicable on Underlay pipe */
2654
- if (dc->fbc_compressor && old_pipe->stream &&
2655
- pipe_ctx->pipe_idx != underlay_idx) {
2656
- if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
2657
- dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
2658
- else
2659
- enable_fbc(dc, dc->current_state);
2660
- }
2661
-
26622584 mi->funcs->mem_input_program_surface_config(
26632585 mi,
26642586 plane_state->format,
....@@ -2681,10 +2603,10 @@
26812603 if (pipe_ctx->plane_state->update_flags.bits.full_update ||
26822604 pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
26832605 pipe_ctx->plane_state->update_flags.bits.gamma_change)
2684
- dc->hwss.set_input_transfer_func(pipe_ctx, pipe_ctx->plane_state);
2606
+ hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
26852607
26862608 if (pipe_ctx->plane_state->update_flags.bits.full_update)
2687
- dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream);
2609
+ hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
26882610
26892611 DC_LOG_SURFACE(
26902612 "Pipe:%d %p: addr hi:0x%x, "
....@@ -2735,16 +2657,8 @@
27352657 if (num_planes == 0)
27362658 return;
27372659
2738
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
2739
- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2740
- struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
2741
-
2742
- if (stream == pipe_ctx->stream) {
2743
- if (!pipe_ctx->top_pipe &&
2744
- (pipe_ctx->plane_state || old_pipe_ctx->plane_state))
2745
- dc->hwss.pipe_control_lock(dc, pipe_ctx, true);
2746
- }
2747
- }
2660
+ if (dc->fbc_compressor)
2661
+ dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
27482662
27492663 for (i = 0; i < dc->res_pool->pipe_count; i++) {
27502664 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
....@@ -2757,7 +2671,7 @@
27572671 pipe_ctx->plane_res.mi,
27582672 pipe_ctx->stream->timing.h_total,
27592673 pipe_ctx->stream->timing.v_total,
2760
- pipe_ctx->stream->timing.pix_clk_khz,
2674
+ pipe_ctx->stream->timing.pix_clk_100hz / 10,
27612675 context->stream_count);
27622676
27632677 dce110_program_front_end_for_pipe(dc, pipe_ctx);
....@@ -2768,19 +2682,19 @@
27682682
27692683 }
27702684
2771
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
2772
- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
2773
- struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
2685
+ if (dc->fbc_compressor)
2686
+ enable_fbc(dc, context);
2687
+}
27742688
2775
- if ((stream == pipe_ctx->stream) &&
2776
- (!pipe_ctx->top_pipe) &&
2777
- (pipe_ctx->plane_state || old_pipe_ctx->plane_state))
2778
- dc->hwss.pipe_control_lock(dc, pipe_ctx, false);
2779
- }
2689
+static void dce110_post_unlock_program_front_end(
2690
+ struct dc *dc,
2691
+ struct dc_state *context)
2692
+{
27802693 }
27812694
27822695 static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
27832696 {
2697
+ struct dce_hwseq *hws = dc->hwseq;
27842698 int fe_idx = pipe_ctx->plane_res.mi ?
27852699 pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx;
27862700
....@@ -2788,7 +2702,7 @@
27882702 if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream)
27892703 return;
27902704
2791
- dc->hwss.enable_display_power_gating(
2705
+ hws->funcs.enable_display_power_gating(
27922706 dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE);
27932707
27942708 dc->res_pool->transforms[fe_idx]->funcs->transform_reset(
....@@ -2803,42 +2717,59 @@
28032717 /* do nothing*/
28042718 }
28052719
2806
-static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
2720
+static void program_output_csc(struct dc *dc,
2721
+ struct pipe_ctx *pipe_ctx,
28072722 enum dc_color_space colorspace,
2808
- uint16_t *matrix)
2723
+ uint16_t *matrix,
2724
+ int opp_id)
28092725 {
28102726 int i;
28112727 struct out_csc_color_matrix tbl_entry;
28122728
2813
- if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
2814
- == true) {
2815
- enum dc_color_space color_space =
2816
- pipe_ctx->stream->output_color_space;
2729
+ if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
2730
+ enum dc_color_space color_space = pipe_ctx->stream->output_color_space;
28172731
2818
- //uint16_t matrix[12];
2819
- for (i = 0; i < 12; i++)
2820
- tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i];
2732
+ for (i = 0; i < 12; i++)
2733
+ tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i];
28212734
2822
- tbl_entry.color_space = color_space;
2823
- //tbl_entry.regval = matrix;
2824
- pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.xfm, &tbl_entry);
2735
+ tbl_entry.color_space = color_space;
2736
+
2737
+ pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(
2738
+ pipe_ctx->plane_res.xfm, &tbl_entry);
28252739 }
28262740 }
28272741
2828
-void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
2742
+static void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
28292743 {
28302744 struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
28312745 struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
28322746 struct mem_input *mi = pipe_ctx->plane_res.mi;
28332747 struct dc_cursor_mi_param param = {
2834
- .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz,
2835
- .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz,
2748
+ .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10,
2749
+ .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.xtalin_clock_inKhz,
28362750 .viewport = pipe_ctx->plane_res.scl_data.viewport,
28372751 .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz,
28382752 .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert,
28392753 .rotation = pipe_ctx->plane_state->rotation,
28402754 .mirror = pipe_ctx->plane_state->horizontal_mirror
28412755 };
2756
+
2757
+ /**
2758
+ * If the cursor's source viewport is clipped then we need to
2759
+ * translate the cursor to appear in the correct position on
2760
+ * the screen.
2761
+ *
2762
+ * This translation isn't affected by scaling so it needs to be
2763
+ * done *after* we adjust the position for the scale factor.
2764
+ *
2765
+ * This is only done by opt-in for now since there are still
2766
+ * some usecases like tiled display that might enable the
2767
+ * cursor on both streams while expecting dc to clip it.
2768
+ */
2769
+ if (pos_cpy.translate_by_source) {
2770
+ pos_cpy.x += pipe_ctx->plane_state->src_rect.x;
2771
+ pos_cpy.y += pipe_ctx->plane_state->src_rect.y;
2772
+ }
28422773
28432774 if (pipe_ctx->plane_state->address.type
28442775 == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
....@@ -2853,7 +2784,7 @@
28532784 mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
28542785 }
28552786
2856
-void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
2787
+static void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
28572788 {
28582789 struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
28592790
....@@ -2873,21 +2804,72 @@
28732804 pipe_ctx->plane_res.xfm, attributes);
28742805 }
28752806
2876
-static void ready_shared_resources(struct dc *dc, struct dc_state *context) {}
2807
+bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
2808
+ uint32_t backlight_pwm_u16_16,
2809
+ uint32_t frame_ramp)
2810
+{
2811
+ struct dc_link *link = pipe_ctx->stream->link;
2812
+ struct dc *dc = link->ctx->dc;
2813
+ struct abm *abm = pipe_ctx->stream_res.abm;
2814
+ struct panel_cntl *panel_cntl = link->panel_cntl;
2815
+ struct dmcu *dmcu = dc->res_pool->dmcu;
2816
+ bool fw_set_brightness = true;
2817
+ /* DMCU -1 for all controller id values,
2818
+ * therefore +1 here
2819
+ */
2820
+ uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1;
28772821
2878
-static void optimize_shared_resources(struct dc *dc) {}
2822
+ if (abm == NULL || panel_cntl == NULL || (abm->funcs->set_backlight_level_pwm == NULL))
2823
+ return false;
2824
+
2825
+ if (dmcu)
2826
+ fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
2827
+
2828
+ if (!fw_set_brightness && panel_cntl->funcs->driver_set_backlight)
2829
+ panel_cntl->funcs->driver_set_backlight(panel_cntl, backlight_pwm_u16_16);
2830
+ else
2831
+ abm->funcs->set_backlight_level_pwm(
2832
+ abm,
2833
+ backlight_pwm_u16_16,
2834
+ frame_ramp,
2835
+ controller_id,
2836
+ link->panel_cntl->inst);
2837
+
2838
+ return true;
2839
+}
2840
+
2841
+void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
2842
+{
2843
+ struct abm *abm = pipe_ctx->stream_res.abm;
2844
+ struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
2845
+
2846
+ if (abm)
2847
+ abm->funcs->set_abm_immediate_disable(abm,
2848
+ pipe_ctx->stream->link->panel_cntl->inst);
2849
+
2850
+ if (panel_cntl)
2851
+ panel_cntl->funcs->store_backlight_level(panel_cntl);
2852
+}
2853
+
2854
+void dce110_set_pipe(struct pipe_ctx *pipe_ctx)
2855
+{
2856
+ struct abm *abm = pipe_ctx->stream_res.abm;
2857
+ struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
2858
+ uint32_t otg_inst = pipe_ctx->stream_res.tg->inst + 1;
2859
+
2860
+ if (abm && panel_cntl)
2861
+ abm->funcs->set_pipe(abm, otg_inst, panel_cntl->inst);
2862
+}
28792863
28802864 static const struct hw_sequencer_funcs dce110_funcs = {
28812865 .program_gamut_remap = program_gamut_remap,
2882
- .program_csc_matrix = program_csc_matrix,
2866
+ .program_output_csc = program_output_csc,
28832867 .init_hw = init_hw,
28842868 .apply_ctx_to_hw = dce110_apply_ctx_to_hw,
28852869 .apply_ctx_for_surface = dce110_apply_ctx_for_surface,
2870
+ .post_unlock_program_front_end = dce110_post_unlock_program_front_end,
28862871 .update_plane_addr = update_plane_addr,
28872872 .update_pending_status = dce110_update_pending_status,
2888
- .set_input_transfer_func = dce110_set_input_transfer_func,
2889
- .set_output_transfer_func = dce110_set_output_transfer_func,
2890
- .power_down = dce110_power_down,
28912873 .enable_accelerated_mode = dce110_enable_accelerated_mode,
28922874 .enable_timing_synchronization = dce110_enable_timing_synchronization,
28932875 .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset,
....@@ -2898,31 +2880,46 @@
28982880 .blank_stream = dce110_blank_stream,
28992881 .enable_audio_stream = dce110_enable_audio_stream,
29002882 .disable_audio_stream = dce110_disable_audio_stream,
2901
- .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating,
2902
- .enable_display_power_gating = dce110_enable_display_power_gating,
29032883 .disable_plane = dce110_power_down_fe,
29042884 .pipe_control_lock = dce_pipe_control_lock,
2905
- .set_bandwidth = dce110_set_bandwidth,
2885
+ .interdependent_update_lock = NULL,
2886
+ .cursor_lock = dce_pipe_control_lock,
2887
+ .prepare_bandwidth = dce110_prepare_bandwidth,
2888
+ .optimize_bandwidth = dce110_optimize_bandwidth,
29062889 .set_drr = set_drr,
29072890 .get_position = get_position,
29082891 .set_static_screen_control = set_static_screen_control,
2909
- .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap,
2910
- .enable_stream_timing = dce110_enable_stream_timing,
29112892 .setup_stereo = NULL,
29122893 .set_avmute = dce110_set_avmute,
29132894 .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
2914
- .ready_shared_resources = ready_shared_resources,
2915
- .optimize_shared_resources = optimize_shared_resources,
2916
- .pplib_apply_display_requirements = pplib_apply_display_requirements,
2917
- .edp_backlight_control = hwss_edp_backlight_control,
2918
- .edp_power_control = hwss_edp_power_control,
2919
- .edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
2895
+ .edp_backlight_control = dce110_edp_backlight_control,
2896
+ .edp_power_control = dce110_edp_power_control,
2897
+ .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
29202898 .set_cursor_position = dce110_set_cursor_position,
2921
- .set_cursor_attribute = dce110_set_cursor_attribute
2899
+ .set_cursor_attribute = dce110_set_cursor_attribute,
2900
+ .set_backlight_level = dce110_set_backlight_level,
2901
+ .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
2902
+ .set_pipe = dce110_set_pipe,
2903
+};
2904
+
2905
+static const struct hwseq_private_funcs dce110_private_funcs = {
2906
+ .init_pipes = init_pipes,
2907
+ .update_plane_addr = update_plane_addr,
2908
+ .set_input_transfer_func = dce110_set_input_transfer_func,
2909
+ .set_output_transfer_func = dce110_set_output_transfer_func,
2910
+ .power_down = dce110_power_down,
2911
+ .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating,
2912
+ .enable_display_power_gating = dce110_enable_display_power_gating,
2913
+ .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap,
2914
+ .enable_stream_timing = dce110_enable_stream_timing,
2915
+ .disable_stream_gating = NULL,
2916
+ .enable_stream_gating = NULL,
2917
+ .edp_backlight_control = dce110_edp_backlight_control,
29222918 };
29232919
29242920 void dce110_hw_sequencer_construct(struct dc *dc)
29252921 {
29262922 dc->hwss = dce110_funcs;
2923
+ dc->hwseq->funcs = dce110_private_funcs;
29272924 }
29282925