forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
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,63 @@
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*/
1685
+ clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
1686
+
16341687 power_down_all_hw_blocks(dc);
16351688 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);
1689
+ if (edp_link_with_sink && !keep_edp_vdd_on)
1690
+ dc->hwss.edp_power_control(edp_link_with_sink, false);
1691
+ clk_mgr_optimize_pwr_state(dc, dc->clk_mgr);
16381692 }
16391693 bios_set_scratch_acc_mode_change(dc->ctx->dc_bios);
16401694 }
....@@ -1649,8 +1703,8 @@
16491703 pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24;
16501704
16511705 total_dest_line_time_ns = 1000000UL *
1652
- stream->timing.h_total /
1653
- stream->timing.pix_clk_khz +
1706
+ (stream->timing.h_total * 10) /
1707
+ stream->timing.pix_clk_100hz +
16541708 pstate_blackout_duration_ns;
16551709
16561710 return total_dest_line_time_ns;
....@@ -1674,18 +1728,18 @@
16741728 dc->bw_vbios->blackout_duration, pipe_ctx->stream);
16751729 pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks(
16761730 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],
1731
+ context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
1732
+ context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
1733
+ context->bw_ctx.bw.dce.stutter_entry_wm_ns[num_pipes],
1734
+ context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
16811735 total_dest_line_time_ns);
16821736 if (i == underlay_idx) {
16831737 num_pipes++;
16841738 pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks(
16851739 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],
1740
+ context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes],
1741
+ context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes],
1742
+ context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes],
16891743 total_dest_line_time_ns);
16901744 }
16911745 num_pipes++;
....@@ -1732,20 +1786,31 @@
17321786 ******************************************************************************/
17331787
17341788 static void set_drr(struct pipe_ctx **pipe_ctx,
1735
- int num_pipes, int vmin, int vmax)
1789
+ int num_pipes, unsigned int vmin, unsigned int vmax,
1790
+ unsigned int vmid, unsigned int vmid_frame_number)
17361791 {
17371792 int i = 0;
17381793 struct drr_params params = {0};
1794
+ // DRR should set trigger event to monitor surface update event
1795
+ unsigned int event_triggers = 0x80;
1796
+ // Note DRR trigger events are generated regardless of whether num frames met.
1797
+ unsigned int num_frames = 2;
17391798
17401799 params.vertical_total_max = vmax;
17411800 params.vertical_total_min = vmin;
17421801
17431802 /* TODO: If multiple pipes are to be supported, you need
1744
- * some GSL stuff
1803
+ * some GSL stuff. Static screen triggers may be programmed differently
1804
+ * as well.
17451805 */
1746
-
17471806 for (i = 0; i < num_pipes; i++) {
1748
- pipe_ctx[i]->stream_res.tg->funcs->set_drr(pipe_ctx[i]->stream_res.tg, &params);
1807
+ pipe_ctx[i]->stream_res.tg->funcs->set_drr(
1808
+ pipe_ctx[i]->stream_res.tg, &params);
1809
+
1810
+ if (vmax != 0 && vmin != 0)
1811
+ pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
1812
+ pipe_ctx[i]->stream_res.tg,
1813
+ event_triggers, num_frames);
17491814 }
17501815 }
17511816
....@@ -1762,65 +1827,44 @@
17621827 }
17631828
17641829 static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
1765
- int num_pipes, const struct dc_static_screen_events *events)
1830
+ int num_pipes, const struct dc_static_screen_params *params)
17661831 {
17671832 unsigned int i;
1768
- unsigned int value = 0;
1833
+ unsigned int triggers = 0;
17691834
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;
1835
+ if (params->triggers.overlay_update)
1836
+ triggers |= 0x100;
1837
+ if (params->triggers.surface_update)
1838
+ triggers |= 0x80;
1839
+ if (params->triggers.cursor_update)
1840
+ triggers |= 0x2;
1841
+ if (params->triggers.force_trigger)
1842
+ triggers |= 0x1;
17781843
1779
- value |= 0x84;
1844
+ if (num_pipes) {
1845
+ struct dc *dc = pipe_ctx[0]->stream->ctx->dc;
1846
+
1847
+ if (dc->fbc_compressor)
1848
+ triggers |= 0x84;
1849
+ }
17801850
17811851 for (i = 0; i < num_pipes; i++)
17821852 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;
1853
+ set_static_screen_control(pipe_ctx[i]->stream_res.tg,
1854
+ triggers, params->num_frames);
18121855 }
18131856
18141857 /*
18151858 * Check if FBC can be enabled
18161859 */
18171860 static bool should_enable_fbc(struct dc *dc,
1818
- struct dc_state *context,
1819
- uint32_t *pipe_idx)
1861
+ struct dc_state *context,
1862
+ uint32_t *pipe_idx)
18201863 {
18211864 uint32_t i;
18221865 struct pipe_ctx *pipe_ctx = NULL;
18231866 struct resource_context *res_ctx = &context->res_ctx;
1867
+ unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
18241868
18251869
18261870 ASSERT(dc->fbc_compressor);
....@@ -1835,21 +1879,32 @@
18351879
18361880 for (i = 0; i < dc->res_pool->pipe_count; i++) {
18371881 if (res_ctx->pipe_ctx[i].stream) {
1882
+
18381883 pipe_ctx = &res_ctx->pipe_ctx[i];
1839
- *pipe_idx = i;
1840
- break;
1884
+
1885
+ if (!pipe_ctx)
1886
+ continue;
1887
+
1888
+ /* fbc not applicable on underlay pipe */
1889
+ if (pipe_ctx->pipe_idx != underlay_idx) {
1890
+ *pipe_idx = i;
1891
+ break;
1892
+ }
18411893 }
18421894 }
18431895
1844
- /* Pipe context should be found */
1845
- ASSERT(pipe_ctx);
1896
+ if (i == dc->res_pool->pipe_count)
1897
+ return false;
1898
+
1899
+ if (!pipe_ctx->stream->link)
1900
+ return false;
18461901
18471902 /* Only supports eDP */
1848
- if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP)
1903
+ if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP)
18491904 return false;
18501905
18511906 /* PSR should not be enabled */
1852
- if (pipe_ctx->stream->sink->link->psr_enabled)
1907
+ if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled)
18531908 return false;
18541909
18551910 /* Nothing to compress */
....@@ -1866,8 +1921,9 @@
18661921 /*
18671922 * Enable FBC
18681923 */
1869
-static void enable_fbc(struct dc *dc,
1870
- struct dc_state *context)
1924
+static void enable_fbc(
1925
+ struct dc *dc,
1926
+ struct dc_state *context)
18711927 {
18721928 uint32_t pipe_idx = 0;
18731929
....@@ -1877,10 +1933,9 @@
18771933 struct compressor *compr = dc->fbc_compressor;
18781934 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
18791935
1880
-
18811936 params.source_view_width = pipe_ctx->stream->timing.h_addressable;
18821937 params.source_view_height = pipe_ctx->stream->timing.v_addressable;
1883
-
1938
+ params.inst = pipe_ctx->stream_res.tg->inst;
18841939 compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr;
18851940
18861941 compr->funcs->surface_address_and_pitch(compr, &params);
....@@ -1919,8 +1974,25 @@
19191974 /* Disable if new stream is null. O/w, if stream is
19201975 * disabled already, no need to disable again.
19211976 */
1922
- if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off)
1923
- core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE);
1977
+ if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) {
1978
+ core_link_disable_stream(pipe_ctx_old);
1979
+
1980
+ /* free acquired resources*/
1981
+ if (pipe_ctx_old->stream_res.audio) {
1982
+ /*disable az_endpoint*/
1983
+ pipe_ctx_old->stream_res.audio->funcs->
1984
+ az_disable(pipe_ctx_old->stream_res.audio);
1985
+
1986
+ /*free audio*/
1987
+ if (dc->caps.dynamic_audio == true) {
1988
+ /*we have to dynamic arbitrate the audio endpoints*/
1989
+ /*we free the resource, need reset is_audio_acquired*/
1990
+ update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,
1991
+ pipe_ctx_old->stream_res.audio, false);
1992
+ pipe_ctx_old->stream_res.audio = NULL;
1993
+ }
1994
+ }
1995
+ }
19241996
19251997 pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
19261998 if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
....@@ -1976,11 +2048,10 @@
19762048
19772049 if (pipe_ctx->top_pipe)
19782050 continue;
1979
-
19802051 if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A)
19812052 continue;
1982
-
1983
- if (pipe_ctx->stream_res.audio != NULL) {
2053
+ if (pipe_ctx->stream_res.audio != NULL &&
2054
+ pipe_ctx->stream_res.audio->enabled == false) {
19842055 struct audio_output audio_output;
19852056
19862057 build_audio_output(context, pipe_ctx, &audio_output);
....@@ -2008,7 +2079,8 @@
20082079 if (!dc_is_dp_signal(pipe_ctx->stream->signal))
20092080 continue;
20102081
2011
- if (pipe_ctx->stream_res.audio != NULL) {
2082
+ if (pipe_ctx->stream_res.audio != NULL &&
2083
+ pipe_ctx->stream_res.audio->enabled == false) {
20122084 struct audio_output audio_output;
20132085
20142086 build_audio_output(context, pipe_ctx, &audio_output);
....@@ -2028,13 +2100,14 @@
20282100 struct dc *dc,
20292101 struct dc_state *context)
20302102 {
2103
+ struct dce_hwseq *hws = dc->hwseq;
20312104 struct dc_bios *dcb = dc->ctx->dc_bios;
20322105 enum dc_status status;
20332106 int i;
20342107
20352108 /* Reset old context */
20362109 /* look up the targets that have been removed since last commit */
2037
- dc->hwss.reset_hw_ctx_wrap(dc, context);
2110
+ hws->funcs.reset_hw_ctx_wrap(dc, context);
20382111
20392112 /* Skip applying if no targets */
20402113 if (context->stream_count <= 0)
....@@ -2059,7 +2132,7 @@
20592132 continue;
20602133 }
20612134
2062
- dc->hwss.enable_display_power_gating(
2135
+ hws->funcs.enable_display_power_gating(
20632136 dc, i, dc->ctx->dc_bios,
20642137 PIPE_GATING_CONTROL_DISABLE);
20652138 }
....@@ -2077,13 +2150,15 @@
20772150 if (pipe_ctx->stream == NULL)
20782151 continue;
20792152
2080
- if (pipe_ctx->stream == pipe_ctx_old->stream)
2153
+ if (pipe_ctx->stream == pipe_ctx_old->stream &&
2154
+ pipe_ctx->stream->link->link_state_valid) {
20812155 continue;
2156
+ }
20822157
20832158 if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx))
20842159 continue;
20852160
2086
- if (pipe_ctx->top_pipe)
2161
+ if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe)
20872162 continue;
20882163
20892164 status = apply_single_controller_ctx_to_hw(
....@@ -2095,10 +2170,10 @@
20952170 return status;
20962171 }
20972172
2098
- dcb->funcs->set_scratch_critical_state(dcb, false);
2099
-
21002173 if (dc->fbc_compressor)
2101
- enable_fbc(dc, context);
2174
+ enable_fbc(dc, dc->current_state);
2175
+
2176
+ dcb->funcs->set_scratch_critical_state(dcb, false);
21022177
21032178 return DC_OK;
21042179 }
....@@ -2331,7 +2406,7 @@
23312406 int i;
23322407
23332408 gsl_params.gsl_group = 0;
2334
- gsl_params.gsl_master = grouped_pipes[0]->stream->triggered_crtc_reset.event_source->status.primary_otg_inst;
2409
+ gsl_params.gsl_master = 0;
23352410
23362411 for (i = 0; i < group_size; i++)
23372412 grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock(
....@@ -2354,25 +2429,33 @@
23542429
23552430 }
23562431
2432
+static void init_pipes(struct dc *dc, struct dc_state *context)
2433
+{
2434
+ // Do nothing
2435
+}
2436
+
23572437 static void init_hw(struct dc *dc)
23582438 {
23592439 int i;
23602440 struct dc_bios *bp;
23612441 struct transform *xfm;
23622442 struct abm *abm;
2443
+ struct dmcu *dmcu;
2444
+ struct dce_hwseq *hws = dc->hwseq;
2445
+ uint32_t backlight = MAX_BACKLIGHT_LEVEL;
23632446
23642447 bp = dc->ctx->dc_bios;
23652448 for (i = 0; i < dc->res_pool->pipe_count; i++) {
23662449 xfm = dc->res_pool->transforms[i];
23672450 xfm->funcs->transform_reset(xfm);
23682451
2369
- dc->hwss.enable_display_power_gating(
2452
+ hws->funcs.enable_display_power_gating(
23702453 dc, i, bp,
23712454 PIPE_GATING_CONTROL_INIT);
2372
- dc->hwss.enable_display_power_gating(
2455
+ hws->funcs.enable_display_power_gating(
23732456 dc, i, bp,
23742457 PIPE_GATING_CONTROL_DISABLE);
2375
- dc->hwss.enable_display_pipe_clock_gating(
2458
+ hws->funcs.enable_display_pipe_clock_gating(
23762459 dc->ctx,
23772460 true);
23782461 }
....@@ -2386,9 +2469,6 @@
23862469 * required signal (which may be different from the
23872470 * default signal on connector). */
23882471 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);
23922472
23932473 link->link_enc->funcs->hw_init(link->link_enc);
23942474 }
....@@ -2409,213 +2489,67 @@
24092489 audio->funcs->hw_init(audio);
24102490 }
24112491
2412
- abm = dc->res_pool->abm;
2413
- if (abm != NULL) {
2414
- abm->funcs->init_backlight(abm);
2415
- abm->funcs->abm_init(abm);
2492
+ for (i = 0; i < dc->link_count; i++) {
2493
+ struct dc_link *link = dc->links[i];
2494
+
2495
+ if (link->panel_cntl)
2496
+ backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);
24162497 }
2498
+
2499
+ abm = dc->res_pool->abm;
2500
+ if (abm != NULL)
2501
+ abm->funcs->abm_init(abm, backlight);
2502
+
2503
+ dmcu = dc->res_pool->dmcu;
2504
+ if (dmcu != NULL && abm != NULL)
2505
+ abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu);
24172506
24182507 if (dc->fbc_compressor)
24192508 dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);
24202509
24212510 }
24222511
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;
24292512
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(
2513
+void dce110_prepare_bandwidth(
25832514 struct dc *dc,
2584
- struct dc_state *context,
2585
- bool decrease_allowed)
2515
+ struct dc_state *context)
25862516 {
2587
- struct dc_clocks req_clks;
2517
+ struct clk_mgr *dccg = dc->clk_mgr;
25882518
2589
- req_clks.dispclk_khz = context->bw.dce.dispclk_khz;
2590
- req_clks.phyclk_khz = get_max_pixel_clock_for_all_paths(dc, context);
2519
+ dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
25912520
2592
- if (decrease_allowed)
2593
- dce110_set_displaymarks(dc, context);
2594
- else
2595
- dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool);
2521
+ dccg->funcs->update_clocks(
2522
+ dccg,
2523
+ context,
2524
+ false);
2525
+}
25962526
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);
2527
+void dce110_optimize_bandwidth(
2528
+ struct dc *dc,
2529
+ struct dc_state *context)
2530
+{
2531
+ struct clk_mgr *dccg = dc->clk_mgr;
2532
+
2533
+ dce110_set_displaymarks(dc, context);
2534
+
2535
+ dccg->funcs->update_clocks(
2536
+ dccg,
2537
+ context,
2538
+ true);
26022539 }
26032540
26042541 static void dce110_program_front_end_for_pipe(
26052542 struct dc *dc, struct pipe_ctx *pipe_ctx)
26062543 {
26072544 struct mem_input *mi = pipe_ctx->plane_res.mi;
2608
- struct pipe_ctx *old_pipe = NULL;
26092545 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
26102546 struct xfm_grph_csc_adjustment adjust;
26112547 struct out_csc_color_matrix tbl_entry;
2612
- unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
26132548 unsigned int i;
2549
+ struct dce_hwseq *hws = dc->hwseq;
2550
+
26142551 DC_LOGGER_INIT();
26152552 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];
26192553
26202554 memset(&adjust, 0, sizeof(adjust));
26212555 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
....@@ -2650,15 +2584,6 @@
26502584
26512585 program_scaler(dc, pipe_ctx);
26522586
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
-
26622587 mi->funcs->mem_input_program_surface_config(
26632588 mi,
26642589 plane_state->format,
....@@ -2681,10 +2606,10 @@
26812606 if (pipe_ctx->plane_state->update_flags.bits.full_update ||
26822607 pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
26832608 pipe_ctx->plane_state->update_flags.bits.gamma_change)
2684
- dc->hwss.set_input_transfer_func(pipe_ctx, pipe_ctx->plane_state);
2609
+ hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
26852610
26862611 if (pipe_ctx->plane_state->update_flags.bits.full_update)
2687
- dc->hwss.set_output_transfer_func(pipe_ctx, pipe_ctx->stream);
2612
+ hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
26882613
26892614 DC_LOG_SURFACE(
26902615 "Pipe:%d %p: addr hi:0x%x, "
....@@ -2735,16 +2660,8 @@
27352660 if (num_planes == 0)
27362661 return;
27372662
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
- }
2663
+ if (dc->fbc_compressor)
2664
+ dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
27482665
27492666 for (i = 0; i < dc->res_pool->pipe_count; i++) {
27502667 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
....@@ -2757,7 +2674,7 @@
27572674 pipe_ctx->plane_res.mi,
27582675 pipe_ctx->stream->timing.h_total,
27592676 pipe_ctx->stream->timing.v_total,
2760
- pipe_ctx->stream->timing.pix_clk_khz,
2677
+ pipe_ctx->stream->timing.pix_clk_100hz / 10,
27612678 context->stream_count);
27622679
27632680 dce110_program_front_end_for_pipe(dc, pipe_ctx);
....@@ -2768,19 +2685,19 @@
27682685
27692686 }
27702687
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];
2688
+ if (dc->fbc_compressor)
2689
+ enable_fbc(dc, context);
2690
+}
27742691
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
- }
2692
+static void dce110_post_unlock_program_front_end(
2693
+ struct dc *dc,
2694
+ struct dc_state *context)
2695
+{
27802696 }
27812697
27822698 static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
27832699 {
2700
+ struct dce_hwseq *hws = dc->hwseq;
27842701 int fe_idx = pipe_ctx->plane_res.mi ?
27852702 pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx;
27862703
....@@ -2788,7 +2705,7 @@
27882705 if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream)
27892706 return;
27902707
2791
- dc->hwss.enable_display_power_gating(
2708
+ hws->funcs.enable_display_power_gating(
27922709 dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE);
27932710
27942711 dc->res_pool->transforms[fe_idx]->funcs->transform_reset(
....@@ -2803,42 +2720,59 @@
28032720 /* do nothing*/
28042721 }
28052722
2806
-static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
2723
+static void program_output_csc(struct dc *dc,
2724
+ struct pipe_ctx *pipe_ctx,
28072725 enum dc_color_space colorspace,
2808
- uint16_t *matrix)
2726
+ uint16_t *matrix,
2727
+ int opp_id)
28092728 {
28102729 int i;
28112730 struct out_csc_color_matrix tbl_entry;
28122731
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;
2732
+ if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
2733
+ enum dc_color_space color_space = pipe_ctx->stream->output_color_space;
28172734
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];
2735
+ for (i = 0; i < 12; i++)
2736
+ tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i];
28212737
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);
2738
+ tbl_entry.color_space = color_space;
2739
+
2740
+ pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(
2741
+ pipe_ctx->plane_res.xfm, &tbl_entry);
28252742 }
28262743 }
28272744
2828
-void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
2745
+static void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
28292746 {
28302747 struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
28312748 struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
28322749 struct mem_input *mi = pipe_ctx->plane_res.mi;
28332750 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,
2751
+ .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10,
2752
+ .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.xtalin_clock_inKhz,
28362753 .viewport = pipe_ctx->plane_res.scl_data.viewport,
28372754 .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz,
28382755 .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert,
28392756 .rotation = pipe_ctx->plane_state->rotation,
28402757 .mirror = pipe_ctx->plane_state->horizontal_mirror
28412758 };
2759
+
2760
+ /**
2761
+ * If the cursor's source viewport is clipped then we need to
2762
+ * translate the cursor to appear in the correct position on
2763
+ * the screen.
2764
+ *
2765
+ * This translation isn't affected by scaling so it needs to be
2766
+ * done *after* we adjust the position for the scale factor.
2767
+ *
2768
+ * This is only done by opt-in for now since there are still
2769
+ * some usecases like tiled display that might enable the
2770
+ * cursor on both streams while expecting dc to clip it.
2771
+ */
2772
+ if (pos_cpy.translate_by_source) {
2773
+ pos_cpy.x += pipe_ctx->plane_state->src_rect.x;
2774
+ pos_cpy.y += pipe_ctx->plane_state->src_rect.y;
2775
+ }
28422776
28432777 if (pipe_ctx->plane_state->address.type
28442778 == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
....@@ -2853,7 +2787,7 @@
28532787 mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
28542788 }
28552789
2856
-void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
2790
+static void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
28572791 {
28582792 struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
28592793
....@@ -2873,21 +2807,72 @@
28732807 pipe_ctx->plane_res.xfm, attributes);
28742808 }
28752809
2876
-static void ready_shared_resources(struct dc *dc, struct dc_state *context) {}
2810
+bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
2811
+ uint32_t backlight_pwm_u16_16,
2812
+ uint32_t frame_ramp)
2813
+{
2814
+ struct dc_link *link = pipe_ctx->stream->link;
2815
+ struct dc *dc = link->ctx->dc;
2816
+ struct abm *abm = pipe_ctx->stream_res.abm;
2817
+ struct panel_cntl *panel_cntl = link->panel_cntl;
2818
+ struct dmcu *dmcu = dc->res_pool->dmcu;
2819
+ bool fw_set_brightness = true;
2820
+ /* DMCU -1 for all controller id values,
2821
+ * therefore +1 here
2822
+ */
2823
+ uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1;
28772824
2878
-static void optimize_shared_resources(struct dc *dc) {}
2825
+ if (abm == NULL || panel_cntl == NULL || (abm->funcs->set_backlight_level_pwm == NULL))
2826
+ return false;
2827
+
2828
+ if (dmcu)
2829
+ fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
2830
+
2831
+ if (!fw_set_brightness && panel_cntl->funcs->driver_set_backlight)
2832
+ panel_cntl->funcs->driver_set_backlight(panel_cntl, backlight_pwm_u16_16);
2833
+ else
2834
+ abm->funcs->set_backlight_level_pwm(
2835
+ abm,
2836
+ backlight_pwm_u16_16,
2837
+ frame_ramp,
2838
+ controller_id,
2839
+ link->panel_cntl->inst);
2840
+
2841
+ return true;
2842
+}
2843
+
2844
+void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
2845
+{
2846
+ struct abm *abm = pipe_ctx->stream_res.abm;
2847
+ struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
2848
+
2849
+ if (abm)
2850
+ abm->funcs->set_abm_immediate_disable(abm,
2851
+ pipe_ctx->stream->link->panel_cntl->inst);
2852
+
2853
+ if (panel_cntl)
2854
+ panel_cntl->funcs->store_backlight_level(panel_cntl);
2855
+}
2856
+
2857
+void dce110_set_pipe(struct pipe_ctx *pipe_ctx)
2858
+{
2859
+ struct abm *abm = pipe_ctx->stream_res.abm;
2860
+ struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
2861
+ uint32_t otg_inst = pipe_ctx->stream_res.tg->inst + 1;
2862
+
2863
+ if (abm && panel_cntl)
2864
+ abm->funcs->set_pipe(abm, otg_inst, panel_cntl->inst);
2865
+}
28792866
28802867 static const struct hw_sequencer_funcs dce110_funcs = {
28812868 .program_gamut_remap = program_gamut_remap,
2882
- .program_csc_matrix = program_csc_matrix,
2869
+ .program_output_csc = program_output_csc,
28832870 .init_hw = init_hw,
28842871 .apply_ctx_to_hw = dce110_apply_ctx_to_hw,
28852872 .apply_ctx_for_surface = dce110_apply_ctx_for_surface,
2873
+ .post_unlock_program_front_end = dce110_post_unlock_program_front_end,
28862874 .update_plane_addr = update_plane_addr,
28872875 .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,
28912876 .enable_accelerated_mode = dce110_enable_accelerated_mode,
28922877 .enable_timing_synchronization = dce110_enable_timing_synchronization,
28932878 .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset,
....@@ -2898,31 +2883,46 @@
28982883 .blank_stream = dce110_blank_stream,
28992884 .enable_audio_stream = dce110_enable_audio_stream,
29002885 .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,
29032886 .disable_plane = dce110_power_down_fe,
29042887 .pipe_control_lock = dce_pipe_control_lock,
2905
- .set_bandwidth = dce110_set_bandwidth,
2888
+ .interdependent_update_lock = NULL,
2889
+ .cursor_lock = dce_pipe_control_lock,
2890
+ .prepare_bandwidth = dce110_prepare_bandwidth,
2891
+ .optimize_bandwidth = dce110_optimize_bandwidth,
29062892 .set_drr = set_drr,
29072893 .get_position = get_position,
29082894 .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,
29112895 .setup_stereo = NULL,
29122896 .set_avmute = dce110_set_avmute,
29132897 .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,
2898
+ .edp_backlight_control = dce110_edp_backlight_control,
2899
+ .edp_power_control = dce110_edp_power_control,
2900
+ .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
29202901 .set_cursor_position = dce110_set_cursor_position,
2921
- .set_cursor_attribute = dce110_set_cursor_attribute
2902
+ .set_cursor_attribute = dce110_set_cursor_attribute,
2903
+ .set_backlight_level = dce110_set_backlight_level,
2904
+ .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
2905
+ .set_pipe = dce110_set_pipe,
2906
+};
2907
+
2908
+static const struct hwseq_private_funcs dce110_private_funcs = {
2909
+ .init_pipes = init_pipes,
2910
+ .update_plane_addr = update_plane_addr,
2911
+ .set_input_transfer_func = dce110_set_input_transfer_func,
2912
+ .set_output_transfer_func = dce110_set_output_transfer_func,
2913
+ .power_down = dce110_power_down,
2914
+ .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating,
2915
+ .enable_display_power_gating = dce110_enable_display_power_gating,
2916
+ .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap,
2917
+ .enable_stream_timing = dce110_enable_stream_timing,
2918
+ .disable_stream_gating = NULL,
2919
+ .enable_stream_gating = NULL,
2920
+ .edp_backlight_control = dce110_edp_backlight_control,
29222921 };
29232922
29242923 void dce110_hw_sequencer_construct(struct dc *dc)
29252924 {
29262925 dc->hwss = dce110_funcs;
2926
+ dc->hwseq->funcs = dce110_private_funcs;
29272927 }
29282928