| .. | .. |
|---|
| 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 | |
|---|