.. | .. |
---|
22 | 22 | * Authors: AMD |
---|
23 | 23 | * |
---|
24 | 24 | */ |
---|
| 25 | + |
---|
| 26 | +#include <linux/delay.h> |
---|
| 27 | + |
---|
25 | 28 | #include "dm_services.h" |
---|
26 | 29 | #include "dc.h" |
---|
27 | 30 | #include "dc_bios_types.h" |
---|
.. | .. |
---|
46 | 49 | #include "link_encoder.h" |
---|
47 | 50 | #include "link_hwss.h" |
---|
48 | 51 | #include "clock_source.h" |
---|
| 52 | +#include "clk_mgr.h" |
---|
49 | 53 | #include "abm.h" |
---|
50 | 54 | #include "audio.h" |
---|
51 | 55 | #include "reg_helper.h" |
---|
| 56 | +#include "panel_cntl.h" |
---|
52 | 57 | |
---|
53 | 58 | /* include DCE11 register header files */ |
---|
54 | 59 | #include "dce/dce_11_0_d.h" |
---|
.. | .. |
---|
56 | 61 | #include "custom_float.h" |
---|
57 | 62 | |
---|
58 | 63 | #include "atomfirmware.h" |
---|
| 64 | + |
---|
| 65 | +#define GAMMA_HW_POINTS_NUM 256 |
---|
59 | 66 | |
---|
60 | 67 | /* |
---|
61 | 68 | * All values are in milliseconds; |
---|
.. | .. |
---|
65 | 72 | #define PANEL_POWER_UP_TIMEOUT 300 |
---|
66 | 73 | #define PANEL_POWER_DOWN_TIMEOUT 500 |
---|
67 | 74 | #define HPD_CHECK_INTERVAL 10 |
---|
| 75 | +#define OLED_POST_T7_DELAY 100 |
---|
| 76 | +#define OLED_PRE_T11_DELAY 150 |
---|
68 | 77 | |
---|
69 | 78 | #define CTX \ |
---|
70 | 79 | hws->ctx |
---|
.. | .. |
---|
264 | 273 | } |
---|
265 | 274 | |
---|
266 | 275 | 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, |
---|
268 | 277 | const struct dc_plane_state *plane_state) |
---|
269 | 278 | { |
---|
270 | 279 | struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; |
---|
.. | .. |
---|
551 | 560 | |
---|
552 | 561 | regamma_params->hw_points_num = hw_points; |
---|
553 | 562 | |
---|
554 | | - i = 1; |
---|
555 | | - for (k = 0; k < 16 && i < 16; k++) { |
---|
| 563 | + k = 0; |
---|
| 564 | + for (i = 1; i < 16; i++) { |
---|
556 | 565 | if (seg_distr[k] != -1) { |
---|
557 | 566 | regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; |
---|
558 | 567 | regamma_params->arr_curve_points[i].offset = |
---|
559 | 568 | regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]); |
---|
560 | 569 | } |
---|
561 | | - i++; |
---|
| 570 | + k++; |
---|
562 | 571 | } |
---|
563 | 572 | |
---|
564 | 573 | if (seg_distr[k] != -1) |
---|
.. | .. |
---|
592 | 601 | } |
---|
593 | 602 | |
---|
594 | 603 | 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, |
---|
596 | 605 | const struct dc_stream_state *stream) |
---|
597 | 606 | { |
---|
598 | 607 | struct transform *xfm = pipe_ctx->plane_res.xfm; |
---|
.. | .. |
---|
617 | 626 | return true; |
---|
618 | 627 | } |
---|
619 | 628 | |
---|
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 | | - |
---|
669 | 629 | void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) |
---|
670 | 630 | { |
---|
671 | | - bool is_hdmi; |
---|
| 631 | + bool is_hdmi_tmds; |
---|
672 | 632 | bool is_dp; |
---|
673 | 633 | |
---|
674 | 634 | ASSERT(pipe_ctx->stream); |
---|
.. | .. |
---|
676 | 636 | if (pipe_ctx->stream_res.stream_enc == NULL) |
---|
677 | 637 | return; /* this is not root pipe */ |
---|
678 | 638 | |
---|
679 | | - is_hdmi = dc_is_hdmi_signal(pipe_ctx->stream->signal); |
---|
| 639 | + is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal); |
---|
680 | 640 | is_dp = dc_is_dp_signal(pipe_ctx->stream->signal); |
---|
681 | 641 | |
---|
682 | | - if (!is_hdmi && !is_dp) |
---|
| 642 | + if (!is_hdmi_tmds && !is_dp) |
---|
683 | 643 | return; |
---|
684 | 644 | |
---|
685 | | - if (is_hdmi) |
---|
| 645 | + if (is_hdmi_tmds) |
---|
686 | 646 | pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets( |
---|
687 | 647 | pipe_ctx->stream_res.stream_enc, |
---|
688 | 648 | &pipe_ctx->stream_res.encoder_info_frame); |
---|
.. | .. |
---|
695 | 655 | void dce110_enable_stream(struct pipe_ctx *pipe_ctx) |
---|
696 | 656 | { |
---|
697 | 657 | 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; |
---|
700 | 659 | 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; |
---|
703 | 662 | |
---|
704 | 663 | uint32_t active_total_with_borders; |
---|
705 | 664 | uint32_t early_control = 0; |
---|
.. | .. |
---|
712 | 671 | link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, |
---|
713 | 672 | pipe_ctx->stream_res.stream_enc->id, true); |
---|
714 | 673 | |
---|
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); |
---|
718 | 675 | |
---|
719 | 676 | /* enable early control to avoid corruption on DP monitor*/ |
---|
720 | 677 | active_total_with_borders = |
---|
.. | .. |
---|
741 | 698 | |
---|
742 | 699 | } |
---|
743 | 700 | |
---|
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 | | - |
---|
766 | 701 | static enum bp_result link_transmitter_control( |
---|
767 | 702 | struct dc_bios *bios, |
---|
768 | 703 | struct bp_transmitter_control *cntl) |
---|
.. | .. |
---|
778 | 713 | * @brief |
---|
779 | 714 | * eDP only. |
---|
780 | 715 | */ |
---|
781 | | -void hwss_edp_wait_for_hpd_ready( |
---|
| 716 | +void dce110_edp_wait_for_hpd_ready( |
---|
782 | 717 | struct dc_link *link, |
---|
783 | 718 | bool power_up) |
---|
784 | 719 | { |
---|
785 | 720 | struct dc_context *ctx = link->ctx; |
---|
786 | 721 | struct graphics_object_id connector = link->link_enc->connector; |
---|
787 | 722 | struct gpio *hpd; |
---|
| 723 | + struct dc_sink *sink = link->local_sink; |
---|
788 | 724 | bool edp_hpd_high = false; |
---|
789 | 725 | uint32_t time_elapsed = 0; |
---|
790 | 726 | uint32_t timeout = power_up ? |
---|
.. | .. |
---|
817 | 753 | return; |
---|
818 | 754 | } |
---|
819 | 755 | |
---|
| 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 | + |
---|
820 | 764 | dal_gpio_open(hpd, GPIO_MODE_INTERRUPT); |
---|
821 | 765 | |
---|
822 | 766 | /* wait until timeout or panel detected */ |
---|
.. | .. |
---|
846 | 790 | } |
---|
847 | 791 | } |
---|
848 | 792 | |
---|
849 | | -void hwss_edp_power_control( |
---|
| 793 | +void dce110_edp_power_control( |
---|
850 | 794 | struct dc_link *link, |
---|
851 | 795 | bool power_up) |
---|
852 | 796 | { |
---|
853 | 797 | struct dc_context *ctx = link->ctx; |
---|
854 | | - struct dce_hwseq *hwseq = ctx->dc->hwseq; |
---|
855 | 798 | struct bp_transmitter_control cntl = { 0 }; |
---|
856 | 799 | enum bp_result bp_result; |
---|
857 | 800 | |
---|
.. | .. |
---|
862 | 805 | return; |
---|
863 | 806 | } |
---|
864 | 807 | |
---|
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 | + |
---|
866 | 835 | /* Send VBIOS command to prompt eDP panel power */ |
---|
867 | 836 | 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; |
---|
875 | 839 | |
---|
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) */ |
---|
879 | 841 | 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; |
---|
886 | 844 | |
---|
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; |
---|
891 | 852 | } |
---|
892 | 853 | |
---|
| 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 | + } |
---|
893 | 869 | } |
---|
894 | 870 | |
---|
895 | 871 | DC_LOG_HW_RESUME_S3( |
---|
896 | | - "%s: Panel Power action: %s\n", |
---|
| 872 | + "%s: BEGIN: Panel Power action: %s\n", |
---|
897 | 873 | __func__, (power_up ? "On":"Off")); |
---|
898 | 874 | |
---|
899 | 875 | cntl.action = power_up ? |
---|
.. | .. |
---|
904 | 880 | cntl.coherent = false; |
---|
905 | 881 | cntl.lanes_number = LANE_COUNT_FOUR; |
---|
906 | 882 | 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 | + |
---|
907 | 894 | 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); |
---|
908 | 900 | |
---|
909 | 901 | if (!power_up) |
---|
910 | 902 | /*save driver power off time stamp*/ |
---|
911 | 903 | link->link_trace.time_stamp.edp_poweroff = dm_get_timestamp(ctx); |
---|
912 | 904 | else |
---|
913 | 905 | 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); |
---|
914 | 912 | |
---|
915 | 913 | if (bp_result != BP_RESULT_OK) |
---|
916 | 914 | DC_LOG_ERROR( |
---|
.. | .. |
---|
928 | 926 | * @brief |
---|
929 | 927 | * eDP only. Control the backlight of the eDP panel |
---|
930 | 928 | */ |
---|
931 | | -void hwss_edp_backlight_control( |
---|
| 929 | +void dce110_edp_backlight_control( |
---|
932 | 930 | struct dc_link *link, |
---|
933 | 931 | bool enable) |
---|
934 | 932 | { |
---|
935 | 933 | struct dc_context *ctx = link->ctx; |
---|
936 | | - struct dce_hwseq *hws = ctx->dc->hwseq; |
---|
937 | 934 | struct bp_transmitter_control cntl = { 0 }; |
---|
938 | 935 | |
---|
939 | 936 | if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) |
---|
.. | .. |
---|
942 | 939 | return; |
---|
943 | 940 | } |
---|
944 | 941 | |
---|
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)) { |
---|
946 | 944 | DC_LOG_HW_RESUME_S3( |
---|
947 | 945 | "%s: panel already powered up. Do nothing.\n", |
---|
948 | 946 | __func__); |
---|
.. | .. |
---|
981 | 979 | /*edp 1.2*/ |
---|
982 | 980 | if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) |
---|
983 | 981 | 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 | + |
---|
984 | 993 | 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 | + |
---|
985 | 1005 | /*edp 1.2*/ |
---|
986 | 1006 | if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) |
---|
987 | 1007 | edp_receiver_ready_T9(link); |
---|
| 1008 | + |
---|
| 1009 | + if (!enable && link->dpcd_sink_ext_caps.bits.oled) |
---|
| 1010 | + msleep(OLED_PRE_T11_DELAY); |
---|
988 | 1011 | } |
---|
989 | 1012 | |
---|
990 | 1013 | void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) |
---|
991 | 1014 | { |
---|
992 | | - struct dc *core_dc = pipe_ctx->stream->ctx->dc; |
---|
993 | 1015 | /* 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; |
---|
995 | 1018 | 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; |
---|
996 | 1028 | |
---|
997 | 1029 | if (pipe_ctx->stream_res.audio) { |
---|
998 | 1030 | for (i = 0; i < MAX_PIPES; i++) { |
---|
999 | 1031 | /*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) |
---|
1001 | 1033 | num_audio++; |
---|
1002 | 1034 | } |
---|
1003 | 1035 | |
---|
1004 | 1036 | pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); |
---|
1005 | 1037 | |
---|
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) |
---|
1007 | 1039 | /*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); |
---|
1009 | 1041 | /* un-mute audio */ |
---|
1010 | 1042 | /* TODO: audio should be per stream rather than per link */ |
---|
1011 | 1043 | 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; |
---|
1013 | 1047 | } |
---|
1014 | 1048 | } |
---|
1015 | 1049 | |
---|
1016 | | -void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option) |
---|
| 1050 | +void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx) |
---|
1017 | 1051 | { |
---|
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; |
---|
1019 | 1063 | |
---|
1020 | 1064 | pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( |
---|
1021 | 1065 | pipe_ctx->stream_res.stream_enc, true); |
---|
1022 | 1066 | 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; |
---|
1030 | 1068 | |
---|
1031 | 1069 | if (dc_is_dp_signal(pipe_ctx->stream->signal)) |
---|
1032 | 1070 | pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable( |
---|
.. | .. |
---|
1034 | 1072 | else |
---|
1035 | 1073 | pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable( |
---|
1036 | 1074 | 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) |
---|
1045 | 1077 | /*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); |
---|
1047 | 1079 | |
---|
1048 | 1080 | /* TODO: notify audio driver for if audio modes list changed |
---|
1049 | 1081 | * add audio mode list change flag */ |
---|
.. | .. |
---|
1053 | 1085 | } |
---|
1054 | 1086 | } |
---|
1055 | 1087 | |
---|
1056 | | -void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option) |
---|
| 1088 | +void dce110_disable_stream(struct pipe_ctx *pipe_ctx) |
---|
1057 | 1089 | { |
---|
1058 | 1090 | struct dc_stream_state *stream = pipe_ctx->stream; |
---|
1059 | | - struct dc_link *link = stream->sink->link; |
---|
| 1091 | + struct dc_link *link = stream->link; |
---|
1060 | 1092 | struct dc *dc = pipe_ctx->stream->ctx->dc; |
---|
1061 | 1093 | |
---|
1062 | | - if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) |
---|
| 1094 | + if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) { |
---|
1063 | 1095 | pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( |
---|
1064 | 1096 | 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 | + } |
---|
1065 | 1100 | |
---|
1066 | 1101 | if (dc_is_dp_signal(pipe_ctx->stream->signal)) |
---|
1067 | 1102 | pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( |
---|
1068 | 1103 | pipe_ctx->stream_res.stream_enc); |
---|
1069 | 1104 | |
---|
1070 | | - dc->hwss.disable_audio_stream(pipe_ctx, option); |
---|
| 1105 | + dc->hwss.disable_audio_stream(pipe_ctx); |
---|
1071 | 1106 | |
---|
1072 | 1107 | link->link_enc->funcs->connect_dig_be_to_fe( |
---|
1073 | 1108 | link->link_enc, |
---|
.. | .. |
---|
1081 | 1116 | { |
---|
1082 | 1117 | struct encoder_unblank_param params = { { 0 } }; |
---|
1083 | 1118 | 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; |
---|
1085 | 1121 | |
---|
1086 | 1122 | /* 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; |
---|
1089 | 1124 | params.link_settings.link_rate = link_settings->link_rate; |
---|
1090 | 1125 | |
---|
1091 | 1126 | if (dc_is_dp_signal(pipe_ctx->stream->signal)) |
---|
1092 | 1127 | pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); |
---|
1093 | 1128 | |
---|
1094 | 1129 | 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); |
---|
1097 | 1131 | } |
---|
1098 | 1132 | } |
---|
| 1133 | + |
---|
1099 | 1134 | void dce110_blank_stream(struct pipe_ctx *pipe_ctx) |
---|
1100 | 1135 | { |
---|
1101 | 1136 | 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; |
---|
1103 | 1139 | |
---|
1104 | 1140 | 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); |
---|
1107 | 1143 | } |
---|
1108 | 1144 | |
---|
1109 | | - if (dc_is_dp_signal(pipe_ctx->stream->signal)) |
---|
| 1145 | + if (dc_is_dp_signal(pipe_ctx->stream->signal)) { |
---|
1110 | 1146 | 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 | + |
---|
1111 | 1156 | } |
---|
1112 | 1157 | |
---|
1113 | 1158 | |
---|
.. | .. |
---|
1172 | 1217 | stream->timing.flags.INTERLACE; |
---|
1173 | 1218 | |
---|
1174 | 1219 | audio_output->crtc_info.refresh_rate = |
---|
1175 | | - (stream->timing.pix_clk_khz*1000)/ |
---|
| 1220 | + (stream->timing.pix_clk_100hz*100)/ |
---|
1176 | 1221 | (stream->timing.h_total*stream->timing.v_total); |
---|
1177 | 1222 | |
---|
1178 | 1223 | audio_output->crtc_info.color_depth = |
---|
1179 | 1224 | stream->timing.display_color_depth; |
---|
1180 | 1225 | |
---|
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; |
---|
1183 | 1228 | |
---|
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; |
---|
1186 | 1231 | |
---|
1187 | 1232 | /*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)) { |
---|
1191 | 1236 | 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; |
---|
1196 | 1241 | |
---|
1197 | 1242 | } |
---|
1198 | 1243 | } |
---|
1199 | 1244 | |
---|
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)) { |
---|
1202 | 1248 | 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); |
---|
1205 | 1251 | } |
---|
1206 | 1252 | |
---|
1207 | 1253 | audio_output->pll_info.feed_back_divider = |
---|
.. | .. |
---|
1258 | 1304 | { |
---|
1259 | 1305 | struct tg_color color = {0}; |
---|
1260 | 1306 | |
---|
1261 | | -#if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
---|
| 1307 | +#if defined(CONFIG_DRM_AMD_DC_DCN) |
---|
1262 | 1308 | /* TOFPGA */ |
---|
1263 | 1309 | if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL) |
---|
1264 | 1310 | return; |
---|
.. | .. |
---|
1330 | 1376 | pipe_ctx->stream_res.tg->funcs->program_timing( |
---|
1331 | 1377 | pipe_ctx->stream_res.tg, |
---|
1332 | 1378 | &stream->timing, |
---|
| 1379 | + 0, |
---|
| 1380 | + 0, |
---|
| 1381 | + 0, |
---|
| 1382 | + 0, |
---|
| 1383 | + pipe_ctx->stream->signal, |
---|
1333 | 1384 | true); |
---|
1334 | | - |
---|
1335 | | - pipe_ctx->stream_res.tg->funcs->set_static_screen_control( |
---|
1336 | | - pipe_ctx->stream_res.tg, |
---|
1337 | | - 0x182); |
---|
1338 | 1385 | } |
---|
1339 | 1386 | |
---|
1340 | 1387 | if (!pipe_ctx_old->stream) { |
---|
.. | .. |
---|
1345 | 1392 | } |
---|
1346 | 1393 | } |
---|
1347 | 1394 | |
---|
1348 | | - |
---|
1349 | | - |
---|
1350 | 1395 | return DC_OK; |
---|
1351 | 1396 | } |
---|
1352 | 1397 | |
---|
.. | .. |
---|
1356 | 1401 | struct dc *dc) |
---|
1357 | 1402 | { |
---|
1358 | 1403 | 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 | + } |
---|
1361 | 1412 | |
---|
1362 | 1413 | if (pipe_ctx->stream_res.audio != NULL) { |
---|
1363 | 1414 | struct audio_output audio_output; |
---|
.. | .. |
---|
1384 | 1435 | } |
---|
1385 | 1436 | |
---|
1386 | 1437 | /* */ |
---|
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); |
---|
1388 | 1441 | |
---|
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); |
---|
1396 | 1444 | |
---|
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, ¶ms); |
---|
| 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 | + |
---|
1409 | 1467 | pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( |
---|
1410 | 1468 | pipe_ctx->stream_res.opp, |
---|
1411 | 1469 | COLOR_SPACE_YCBCR601, |
---|
1412 | 1470 | 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); |
---|
1426 | 1472 | |
---|
1427 | 1473 | pipe_ctx->stream_res.opp->funcs->opp_program_fmt( |
---|
1428 | 1474 | pipe_ctx->stream_res.opp, |
---|
1429 | 1475 | &stream->bit_depth_params, |
---|
1430 | 1476 | &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); |
---|
1431 | 1483 | |
---|
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 | + } |
---|
1437 | 1490 | |
---|
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) |
---|
1455 | 1492 | core_link_enable_stream(context, pipe_ctx); |
---|
1456 | 1493 | |
---|
1457 | 1494 | pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; |
---|
1458 | 1495 | |
---|
1459 | | - pipe_ctx->stream->sink->link->psr_enabled = false; |
---|
| 1496 | + pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false; |
---|
1460 | 1497 | |
---|
1461 | 1498 | return DC_OK; |
---|
1462 | 1499 | } |
---|
.. | .. |
---|
1466 | 1503 | static void power_down_encoders(struct dc *dc) |
---|
1467 | 1504 | { |
---|
1468 | 1505 | int i; |
---|
1469 | | - enum connector_id connector_id; |
---|
1470 | | - enum signal_type signal = SIGNAL_TYPE_NONE; |
---|
1471 | 1506 | |
---|
1472 | 1507 | /* do not know BIOS back-front mapping, simply blank all. It will not |
---|
1473 | 1508 | * hurt for non-DP |
---|
.. | .. |
---|
1478 | 1513 | } |
---|
1479 | 1514 | |
---|
1480 | 1515 | 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; |
---|
1484 | 1517 | |
---|
| 1518 | + if ((signal == SIGNAL_TYPE_EDP) || |
---|
| 1519 | + (signal == SIGNAL_TYPE_DISPLAY_PORT)) |
---|
1485 | 1520 | if (!dc->links[i]->wa_flags.dp_keep_receiver_powered) |
---|
1486 | 1521 | 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; |
---|
1490 | 1525 | |
---|
1491 | 1526 | dc->links[i]->link_enc->funcs->disable_output( |
---|
1492 | 1527 | dc->links[i]->link_enc, signal); |
---|
| 1528 | + |
---|
| 1529 | + dc->links[i]->link_status.link_active = false; |
---|
1493 | 1530 | } |
---|
1494 | 1531 | } |
---|
1495 | 1532 | |
---|
.. | .. |
---|
1555 | 1592 | } |
---|
1556 | 1593 | } |
---|
1557 | 1594 | |
---|
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) |
---|
1559 | 1597 | { |
---|
1560 | 1598 | int i; |
---|
1561 | 1599 | |
---|
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]; |
---|
1565 | 1603 | } |
---|
1566 | 1604 | return NULL; |
---|
1567 | 1605 | } |
---|
1568 | 1606 | |
---|
1569 | | -static struct dc_link *get_link_for_edp_not_in_use( |
---|
| 1607 | +static struct dc_link *get_edp_link_with_sink( |
---|
1570 | 1608 | struct dc *dc, |
---|
1571 | 1609 | struct dc_state *context) |
---|
1572 | 1610 | { |
---|
1573 | 1611 | int i; |
---|
1574 | 1612 | 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 | | - } |
---|
1581 | 1613 | |
---|
1582 | 1614 | /* check if there is an eDP panel not in use */ |
---|
1583 | 1615 | for (i = 0; i < dc->link_count; i++) { |
---|
.. | .. |
---|
1600 | 1632 | */ |
---|
1601 | 1633 | void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) |
---|
1602 | 1634 | { |
---|
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; |
---|
1606 | 1643 | |
---|
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; |
---|
1616 | 1666 | } |
---|
1617 | 1667 | |
---|
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 | + } |
---|
1626 | 1674 | } |
---|
1627 | 1675 | |
---|
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) { |
---|
1630 | 1681 | /*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); |
---|
1632 | 1683 | } |
---|
1633 | 1684 | /*resume from S3, no vbios posting, no need to power down again*/ |
---|
| 1685 | + clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); |
---|
| 1686 | + |
---|
1634 | 1687 | power_down_all_hw_blocks(dc); |
---|
1635 | 1688 | 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); |
---|
1638 | 1692 | } |
---|
1639 | 1693 | bios_set_scratch_acc_mode_change(dc->ctx->dc_bios); |
---|
1640 | 1694 | } |
---|
.. | .. |
---|
1649 | 1703 | pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24; |
---|
1650 | 1704 | |
---|
1651 | 1705 | 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 + |
---|
1654 | 1708 | pstate_blackout_duration_ns; |
---|
1655 | 1709 | |
---|
1656 | 1710 | return total_dest_line_time_ns; |
---|
.. | .. |
---|
1674 | 1728 | dc->bw_vbios->blackout_duration, pipe_ctx->stream); |
---|
1675 | 1729 | pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks( |
---|
1676 | 1730 | 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], |
---|
1681 | 1735 | total_dest_line_time_ns); |
---|
1682 | 1736 | if (i == underlay_idx) { |
---|
1683 | 1737 | num_pipes++; |
---|
1684 | 1738 | pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks( |
---|
1685 | 1739 | 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], |
---|
1689 | 1743 | total_dest_line_time_ns); |
---|
1690 | 1744 | } |
---|
1691 | 1745 | num_pipes++; |
---|
.. | .. |
---|
1732 | 1786 | ******************************************************************************/ |
---|
1733 | 1787 | |
---|
1734 | 1788 | 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) |
---|
1736 | 1791 | { |
---|
1737 | 1792 | int i = 0; |
---|
1738 | 1793 | 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; |
---|
1739 | 1798 | |
---|
1740 | 1799 | params.vertical_total_max = vmax; |
---|
1741 | 1800 | params.vertical_total_min = vmin; |
---|
1742 | 1801 | |
---|
1743 | 1802 | /* 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. |
---|
1745 | 1805 | */ |
---|
1746 | | - |
---|
1747 | 1806 | for (i = 0; i < num_pipes; i++) { |
---|
1748 | | - pipe_ctx[i]->stream_res.tg->funcs->set_drr(pipe_ctx[i]->stream_res.tg, ¶ms); |
---|
| 1807 | + pipe_ctx[i]->stream_res.tg->funcs->set_drr( |
---|
| 1808 | + pipe_ctx[i]->stream_res.tg, ¶ms); |
---|
| 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); |
---|
1749 | 1814 | } |
---|
1750 | 1815 | } |
---|
1751 | 1816 | |
---|
.. | .. |
---|
1762 | 1827 | } |
---|
1763 | 1828 | |
---|
1764 | 1829 | 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) |
---|
1766 | 1831 | { |
---|
1767 | 1832 | unsigned int i; |
---|
1768 | | - unsigned int value = 0; |
---|
| 1833 | + unsigned int triggers = 0; |
---|
1769 | 1834 | |
---|
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; |
---|
1778 | 1843 | |
---|
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 | + } |
---|
1780 | 1850 | |
---|
1781 | 1851 | for (i = 0; i < num_pipes; i++) |
---|
1782 | 1852 | 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); |
---|
1812 | 1855 | } |
---|
1813 | 1856 | |
---|
1814 | 1857 | /* |
---|
1815 | 1858 | * Check if FBC can be enabled |
---|
1816 | 1859 | */ |
---|
1817 | 1860 | 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) |
---|
1820 | 1863 | { |
---|
1821 | 1864 | uint32_t i; |
---|
1822 | 1865 | struct pipe_ctx *pipe_ctx = NULL; |
---|
1823 | 1866 | struct resource_context *res_ctx = &context->res_ctx; |
---|
| 1867 | + unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; |
---|
1824 | 1868 | |
---|
1825 | 1869 | |
---|
1826 | 1870 | ASSERT(dc->fbc_compressor); |
---|
.. | .. |
---|
1835 | 1879 | |
---|
1836 | 1880 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
---|
1837 | 1881 | if (res_ctx->pipe_ctx[i].stream) { |
---|
| 1882 | + |
---|
1838 | 1883 | 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 | + } |
---|
1841 | 1893 | } |
---|
1842 | 1894 | } |
---|
1843 | 1895 | |
---|
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; |
---|
1846 | 1901 | |
---|
1847 | 1902 | /* 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) |
---|
1849 | 1904 | return false; |
---|
1850 | 1905 | |
---|
1851 | 1906 | /* 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) |
---|
1853 | 1908 | return false; |
---|
1854 | 1909 | |
---|
1855 | 1910 | /* Nothing to compress */ |
---|
.. | .. |
---|
1866 | 1921 | /* |
---|
1867 | 1922 | * Enable FBC |
---|
1868 | 1923 | */ |
---|
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) |
---|
1871 | 1927 | { |
---|
1872 | 1928 | uint32_t pipe_idx = 0; |
---|
1873 | 1929 | |
---|
.. | .. |
---|
1877 | 1933 | struct compressor *compr = dc->fbc_compressor; |
---|
1878 | 1934 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; |
---|
1879 | 1935 | |
---|
1880 | | - |
---|
1881 | 1936 | params.source_view_width = pipe_ctx->stream->timing.h_addressable; |
---|
1882 | 1937 | params.source_view_height = pipe_ctx->stream->timing.v_addressable; |
---|
1883 | | - |
---|
| 1938 | + params.inst = pipe_ctx->stream_res.tg->inst; |
---|
1884 | 1939 | compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr; |
---|
1885 | 1940 | |
---|
1886 | 1941 | compr->funcs->surface_address_and_pitch(compr, ¶ms); |
---|
.. | .. |
---|
1919 | 1974 | /* Disable if new stream is null. O/w, if stream is |
---|
1920 | 1975 | * disabled already, no need to disable again. |
---|
1921 | 1976 | */ |
---|
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 | + } |
---|
1924 | 1996 | |
---|
1925 | 1997 | pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); |
---|
1926 | 1998 | if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { |
---|
.. | .. |
---|
1976 | 2048 | |
---|
1977 | 2049 | if (pipe_ctx->top_pipe) |
---|
1978 | 2050 | continue; |
---|
1979 | | - |
---|
1980 | 2051 | if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A) |
---|
1981 | 2052 | 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) { |
---|
1984 | 2055 | struct audio_output audio_output; |
---|
1985 | 2056 | |
---|
1986 | 2057 | build_audio_output(context, pipe_ctx, &audio_output); |
---|
.. | .. |
---|
2008 | 2079 | if (!dc_is_dp_signal(pipe_ctx->stream->signal)) |
---|
2009 | 2080 | continue; |
---|
2010 | 2081 | |
---|
2011 | | - if (pipe_ctx->stream_res.audio != NULL) { |
---|
| 2082 | + if (pipe_ctx->stream_res.audio != NULL && |
---|
| 2083 | + pipe_ctx->stream_res.audio->enabled == false) { |
---|
2012 | 2084 | struct audio_output audio_output; |
---|
2013 | 2085 | |
---|
2014 | 2086 | build_audio_output(context, pipe_ctx, &audio_output); |
---|
.. | .. |
---|
2028 | 2100 | struct dc *dc, |
---|
2029 | 2101 | struct dc_state *context) |
---|
2030 | 2102 | { |
---|
| 2103 | + struct dce_hwseq *hws = dc->hwseq; |
---|
2031 | 2104 | struct dc_bios *dcb = dc->ctx->dc_bios; |
---|
2032 | 2105 | enum dc_status status; |
---|
2033 | 2106 | int i; |
---|
2034 | 2107 | |
---|
2035 | 2108 | /* Reset old context */ |
---|
2036 | 2109 | /* 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); |
---|
2038 | 2111 | |
---|
2039 | 2112 | /* Skip applying if no targets */ |
---|
2040 | 2113 | if (context->stream_count <= 0) |
---|
.. | .. |
---|
2059 | 2132 | continue; |
---|
2060 | 2133 | } |
---|
2061 | 2134 | |
---|
2062 | | - dc->hwss.enable_display_power_gating( |
---|
| 2135 | + hws->funcs.enable_display_power_gating( |
---|
2063 | 2136 | dc, i, dc->ctx->dc_bios, |
---|
2064 | 2137 | PIPE_GATING_CONTROL_DISABLE); |
---|
2065 | 2138 | } |
---|
.. | .. |
---|
2077 | 2150 | if (pipe_ctx->stream == NULL) |
---|
2078 | 2151 | continue; |
---|
2079 | 2152 | |
---|
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) { |
---|
2081 | 2155 | continue; |
---|
| 2156 | + } |
---|
2082 | 2157 | |
---|
2083 | 2158 | if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) |
---|
2084 | 2159 | continue; |
---|
2085 | 2160 | |
---|
2086 | | - if (pipe_ctx->top_pipe) |
---|
| 2161 | + if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe) |
---|
2087 | 2162 | continue; |
---|
2088 | 2163 | |
---|
2089 | 2164 | status = apply_single_controller_ctx_to_hw( |
---|
.. | .. |
---|
2095 | 2170 | return status; |
---|
2096 | 2171 | } |
---|
2097 | 2172 | |
---|
2098 | | - dcb->funcs->set_scratch_critical_state(dcb, false); |
---|
2099 | | - |
---|
2100 | 2173 | 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); |
---|
2102 | 2177 | |
---|
2103 | 2178 | return DC_OK; |
---|
2104 | 2179 | } |
---|
.. | .. |
---|
2331 | 2406 | int i; |
---|
2332 | 2407 | |
---|
2333 | 2408 | 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; |
---|
2335 | 2410 | |
---|
2336 | 2411 | for (i = 0; i < group_size; i++) |
---|
2337 | 2412 | grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( |
---|
.. | .. |
---|
2354 | 2429 | |
---|
2355 | 2430 | } |
---|
2356 | 2431 | |
---|
| 2432 | +static void init_pipes(struct dc *dc, struct dc_state *context) |
---|
| 2433 | +{ |
---|
| 2434 | + // Do nothing |
---|
| 2435 | +} |
---|
| 2436 | + |
---|
2357 | 2437 | static void init_hw(struct dc *dc) |
---|
2358 | 2438 | { |
---|
2359 | 2439 | int i; |
---|
2360 | 2440 | struct dc_bios *bp; |
---|
2361 | 2441 | struct transform *xfm; |
---|
2362 | 2442 | struct abm *abm; |
---|
| 2443 | + struct dmcu *dmcu; |
---|
| 2444 | + struct dce_hwseq *hws = dc->hwseq; |
---|
| 2445 | + uint32_t backlight = MAX_BACKLIGHT_LEVEL; |
---|
2363 | 2446 | |
---|
2364 | 2447 | bp = dc->ctx->dc_bios; |
---|
2365 | 2448 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
---|
2366 | 2449 | xfm = dc->res_pool->transforms[i]; |
---|
2367 | 2450 | xfm->funcs->transform_reset(xfm); |
---|
2368 | 2451 | |
---|
2369 | | - dc->hwss.enable_display_power_gating( |
---|
| 2452 | + hws->funcs.enable_display_power_gating( |
---|
2370 | 2453 | dc, i, bp, |
---|
2371 | 2454 | PIPE_GATING_CONTROL_INIT); |
---|
2372 | | - dc->hwss.enable_display_power_gating( |
---|
| 2455 | + hws->funcs.enable_display_power_gating( |
---|
2373 | 2456 | dc, i, bp, |
---|
2374 | 2457 | PIPE_GATING_CONTROL_DISABLE); |
---|
2375 | | - dc->hwss.enable_display_pipe_clock_gating( |
---|
| 2458 | + hws->funcs.enable_display_pipe_clock_gating( |
---|
2376 | 2459 | dc->ctx, |
---|
2377 | 2460 | true); |
---|
2378 | 2461 | } |
---|
.. | .. |
---|
2386 | 2469 | * required signal (which may be different from the |
---|
2387 | 2470 | * default signal on connector). */ |
---|
2388 | 2471 | 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); |
---|
2392 | 2472 | |
---|
2393 | 2473 | link->link_enc->funcs->hw_init(link->link_enc); |
---|
2394 | 2474 | } |
---|
.. | .. |
---|
2409 | 2489 | audio->funcs->hw_init(audio); |
---|
2410 | 2490 | } |
---|
2411 | 2491 | |
---|
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); |
---|
2416 | 2497 | } |
---|
| 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); |
---|
2417 | 2506 | |
---|
2418 | 2507 | if (dc->fbc_compressor) |
---|
2419 | 2508 | dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); |
---|
2420 | 2509 | |
---|
2421 | 2510 | } |
---|
2422 | 2511 | |
---|
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; |
---|
2429 | 2512 | |
---|
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( |
---|
2583 | 2514 | struct dc *dc, |
---|
2584 | | - struct dc_state *context, |
---|
2585 | | - bool decrease_allowed) |
---|
| 2515 | + struct dc_state *context) |
---|
2586 | 2516 | { |
---|
2587 | | - struct dc_clocks req_clks; |
---|
| 2517 | + struct clk_mgr *dccg = dc->clk_mgr; |
---|
2588 | 2518 | |
---|
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); |
---|
2591 | 2520 | |
---|
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 | +} |
---|
2596 | 2526 | |
---|
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); |
---|
2602 | 2539 | } |
---|
2603 | 2540 | |
---|
2604 | 2541 | static void dce110_program_front_end_for_pipe( |
---|
2605 | 2542 | struct dc *dc, struct pipe_ctx *pipe_ctx) |
---|
2606 | 2543 | { |
---|
2607 | 2544 | struct mem_input *mi = pipe_ctx->plane_res.mi; |
---|
2608 | | - struct pipe_ctx *old_pipe = NULL; |
---|
2609 | 2545 | struct dc_plane_state *plane_state = pipe_ctx->plane_state; |
---|
2610 | 2546 | struct xfm_grph_csc_adjustment adjust; |
---|
2611 | 2547 | struct out_csc_color_matrix tbl_entry; |
---|
2612 | | - unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; |
---|
2613 | 2548 | unsigned int i; |
---|
| 2549 | + struct dce_hwseq *hws = dc->hwseq; |
---|
| 2550 | + |
---|
2614 | 2551 | DC_LOGGER_INIT(); |
---|
2615 | 2552 | 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]; |
---|
2619 | 2553 | |
---|
2620 | 2554 | memset(&adjust, 0, sizeof(adjust)); |
---|
2621 | 2555 | adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; |
---|
.. | .. |
---|
2650 | 2584 | |
---|
2651 | 2585 | program_scaler(dc, pipe_ctx); |
---|
2652 | 2586 | |
---|
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 | | - |
---|
2662 | 2587 | mi->funcs->mem_input_program_surface_config( |
---|
2663 | 2588 | mi, |
---|
2664 | 2589 | plane_state->format, |
---|
.. | .. |
---|
2681 | 2606 | if (pipe_ctx->plane_state->update_flags.bits.full_update || |
---|
2682 | 2607 | pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || |
---|
2683 | 2608 | 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); |
---|
2685 | 2610 | |
---|
2686 | 2611 | 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); |
---|
2688 | 2613 | |
---|
2689 | 2614 | DC_LOG_SURFACE( |
---|
2690 | 2615 | "Pipe:%d %p: addr hi:0x%x, " |
---|
.. | .. |
---|
2735 | 2660 | if (num_planes == 0) |
---|
2736 | 2661 | return; |
---|
2737 | 2662 | |
---|
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); |
---|
2748 | 2665 | |
---|
2749 | 2666 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
---|
2750 | 2667 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; |
---|
.. | .. |
---|
2757 | 2674 | pipe_ctx->plane_res.mi, |
---|
2758 | 2675 | pipe_ctx->stream->timing.h_total, |
---|
2759 | 2676 | pipe_ctx->stream->timing.v_total, |
---|
2760 | | - pipe_ctx->stream->timing.pix_clk_khz, |
---|
| 2677 | + pipe_ctx->stream->timing.pix_clk_100hz / 10, |
---|
2761 | 2678 | context->stream_count); |
---|
2762 | 2679 | |
---|
2763 | 2680 | dce110_program_front_end_for_pipe(dc, pipe_ctx); |
---|
.. | .. |
---|
2768 | 2685 | |
---|
2769 | 2686 | } |
---|
2770 | 2687 | |
---|
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 | +} |
---|
2774 | 2691 | |
---|
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 | +{ |
---|
2780 | 2696 | } |
---|
2781 | 2697 | |
---|
2782 | 2698 | static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx) |
---|
2783 | 2699 | { |
---|
| 2700 | + struct dce_hwseq *hws = dc->hwseq; |
---|
2784 | 2701 | int fe_idx = pipe_ctx->plane_res.mi ? |
---|
2785 | 2702 | pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx; |
---|
2786 | 2703 | |
---|
.. | .. |
---|
2788 | 2705 | if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream) |
---|
2789 | 2706 | return; |
---|
2790 | 2707 | |
---|
2791 | | - dc->hwss.enable_display_power_gating( |
---|
| 2708 | + hws->funcs.enable_display_power_gating( |
---|
2792 | 2709 | dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); |
---|
2793 | 2710 | |
---|
2794 | 2711 | dc->res_pool->transforms[fe_idx]->funcs->transform_reset( |
---|
.. | .. |
---|
2803 | 2720 | /* do nothing*/ |
---|
2804 | 2721 | } |
---|
2805 | 2722 | |
---|
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, |
---|
2807 | 2725 | enum dc_color_space colorspace, |
---|
2808 | | - uint16_t *matrix) |
---|
| 2726 | + uint16_t *matrix, |
---|
| 2727 | + int opp_id) |
---|
2809 | 2728 | { |
---|
2810 | 2729 | int i; |
---|
2811 | 2730 | struct out_csc_color_matrix tbl_entry; |
---|
2812 | 2731 | |
---|
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; |
---|
2817 | 2734 | |
---|
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]; |
---|
2821 | 2737 | |
---|
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); |
---|
2825 | 2742 | } |
---|
2826 | 2743 | } |
---|
2827 | 2744 | |
---|
2828 | | -void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) |
---|
| 2745 | +static void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) |
---|
2829 | 2746 | { |
---|
2830 | 2747 | struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; |
---|
2831 | 2748 | struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; |
---|
2832 | 2749 | struct mem_input *mi = pipe_ctx->plane_res.mi; |
---|
2833 | 2750 | 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, |
---|
2836 | 2753 | .viewport = pipe_ctx->plane_res.scl_data.viewport, |
---|
2837 | 2754 | .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz, |
---|
2838 | 2755 | .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert, |
---|
2839 | 2756 | .rotation = pipe_ctx->plane_state->rotation, |
---|
2840 | 2757 | .mirror = pipe_ctx->plane_state->horizontal_mirror |
---|
2841 | 2758 | }; |
---|
| 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 | + } |
---|
2842 | 2776 | |
---|
2843 | 2777 | if (pipe_ctx->plane_state->address.type |
---|
2844 | 2778 | == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) |
---|
.. | .. |
---|
2853 | 2787 | mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); |
---|
2854 | 2788 | } |
---|
2855 | 2789 | |
---|
2856 | | -void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) |
---|
| 2790 | +static void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) |
---|
2857 | 2791 | { |
---|
2858 | 2792 | struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; |
---|
2859 | 2793 | |
---|
.. | .. |
---|
2873 | 2807 | pipe_ctx->plane_res.xfm, attributes); |
---|
2874 | 2808 | } |
---|
2875 | 2809 | |
---|
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; |
---|
2877 | 2824 | |
---|
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 | +} |
---|
2879 | 2866 | |
---|
2880 | 2867 | static const struct hw_sequencer_funcs dce110_funcs = { |
---|
2881 | 2868 | .program_gamut_remap = program_gamut_remap, |
---|
2882 | | - .program_csc_matrix = program_csc_matrix, |
---|
| 2869 | + .program_output_csc = program_output_csc, |
---|
2883 | 2870 | .init_hw = init_hw, |
---|
2884 | 2871 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
---|
2885 | 2872 | .apply_ctx_for_surface = dce110_apply_ctx_for_surface, |
---|
| 2873 | + .post_unlock_program_front_end = dce110_post_unlock_program_front_end, |
---|
2886 | 2874 | .update_plane_addr = update_plane_addr, |
---|
2887 | 2875 | .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, |
---|
2891 | 2876 | .enable_accelerated_mode = dce110_enable_accelerated_mode, |
---|
2892 | 2877 | .enable_timing_synchronization = dce110_enable_timing_synchronization, |
---|
2893 | 2878 | .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset, |
---|
.. | .. |
---|
2898 | 2883 | .blank_stream = dce110_blank_stream, |
---|
2899 | 2884 | .enable_audio_stream = dce110_enable_audio_stream, |
---|
2900 | 2885 | .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, |
---|
2903 | 2886 | .disable_plane = dce110_power_down_fe, |
---|
2904 | 2887 | .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, |
---|
2906 | 2892 | .set_drr = set_drr, |
---|
2907 | 2893 | .get_position = get_position, |
---|
2908 | 2894 | .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, |
---|
2911 | 2895 | .setup_stereo = NULL, |
---|
2912 | 2896 | .set_avmute = dce110_set_avmute, |
---|
2913 | 2897 | .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, |
---|
2920 | 2901 | .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, |
---|
2922 | 2921 | }; |
---|
2923 | 2922 | |
---|
2924 | 2923 | void dce110_hw_sequencer_construct(struct dc *dc) |
---|
2925 | 2924 | { |
---|
2926 | 2925 | dc->hwss = dce110_funcs; |
---|
| 2926 | + dc->hwseq->funcs = dce110_private_funcs; |
---|
2927 | 2927 | } |
---|
2928 | 2928 | |
---|