diff options
author | Anthony Koo <Anthony.Koo@amd.com> | 2019-01-20 01:23:07 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-02-06 13:31:22 -0500 |
commit | fb55546ea4b50f04ef41c196b8ac1824e26bc48c (patch) | |
tree | ff85e381a2d761983efc63759830ca99d50779bc | |
parent | 9c0fb8d45bfcf2e8f080489913db443c1fd241ed (diff) |
drm/amd/display: refactor init_hw to isolate pipe related init
[Why]
Pipe related init is possible to optimized if we know what we
intend to program, and if we can determine it matches what is
already programmed for the pipe.
[How]
First step is to isolate the pipe related init code
Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
3 files changed, 85 insertions, 82 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index a4386348a981..4df8a43b5018 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | |||
@@ -2275,6 +2275,11 @@ static void dce110_enable_per_frame_crtc_position_reset( | |||
2275 | 2275 | ||
2276 | } | 2276 | } |
2277 | 2277 | ||
2278 | static void init_pipes(struct dc *dc, struct dc_state *context) | ||
2279 | { | ||
2280 | // Do nothing | ||
2281 | } | ||
2282 | |||
2278 | static void init_hw(struct dc *dc) | 2283 | static void init_hw(struct dc *dc) |
2279 | { | 2284 | { |
2280 | int i; | 2285 | int i; |
@@ -2642,6 +2647,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { | |||
2642 | .program_gamut_remap = program_gamut_remap, | 2647 | .program_gamut_remap = program_gamut_remap, |
2643 | .program_output_csc = program_output_csc, | 2648 | .program_output_csc = program_output_csc, |
2644 | .init_hw = init_hw, | 2649 | .init_hw = init_hw, |
2650 | .init_pipes = init_pipes, | ||
2645 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, | 2651 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
2646 | .apply_ctx_for_surface = dce110_apply_ctx_for_surface, | 2652 | .apply_ctx_for_surface = dce110_apply_ctx_for_surface, |
2647 | .update_plane_addr = update_plane_addr, | 2653 | .update_plane_addr = update_plane_addr, |
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index a03bbbf94d5d..117d9d8227f7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | |||
@@ -956,97 +956,34 @@ static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) | |||
956 | pipe_ctx->pipe_idx); | 956 | pipe_ctx->pipe_idx); |
957 | } | 957 | } |
958 | 958 | ||
959 | static void dcn10_init_hw(struct dc *dc) | 959 | static void dcn10_init_pipes(struct dc *dc, struct dc_state *context) |
960 | { | 960 | { |
961 | int i; | 961 | int i; |
962 | struct abm *abm = dc->res_pool->abm; | ||
963 | struct dmcu *dmcu = dc->res_pool->dmcu; | ||
964 | struct dce_hwseq *hws = dc->hwseq; | ||
965 | struct dc_bios *dcb = dc->ctx->dc_bios; | ||
966 | struct dc_state *context = dc->current_state; | ||
967 | |||
968 | if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { | ||
969 | REG_WRITE(REFCLK_CNTL, 0); | ||
970 | REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1); | ||
971 | REG_WRITE(DIO_MEM_PWR_CTRL, 0); | ||
972 | |||
973 | if (!dc->debug.disable_clock_gate) { | ||
974 | /* enable all DCN clock gating */ | ||
975 | REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); | ||
976 | |||
977 | REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); | ||
978 | |||
979 | REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); | ||
980 | } | ||
981 | |||
982 | enable_power_gating_plane(dc->hwseq, true); | ||
983 | } else { | ||
984 | |||
985 | if (!dcb->funcs->is_accelerated_mode(dcb)) { | ||
986 | bool allow_self_fresh_force_enable = | ||
987 | hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub); | ||
988 | |||
989 | bios_golden_init(dc); | ||
990 | |||
991 | /* WA for making DF sleep when idle after resume from S0i3. | ||
992 | * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by | ||
993 | * command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0 | ||
994 | * before calling command table and it changed to 1 after, | ||
995 | * it should be set back to 0. | ||
996 | */ | ||
997 | if (allow_self_fresh_force_enable == false && | ||
998 | hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub)) | ||
999 | hubbub1_allow_self_refresh_control(dc->res_pool->hubbub, true); | ||
1000 | |||
1001 | disable_vga(dc->hwseq); | ||
1002 | } | ||
1003 | |||
1004 | for (i = 0; i < dc->link_count; i++) { | ||
1005 | /* Power up AND update implementation according to the | ||
1006 | * required signal (which may be different from the | ||
1007 | * default signal on connector). | ||
1008 | */ | ||
1009 | struct dc_link *link = dc->links[i]; | ||
1010 | |||
1011 | if (link->link_enc->connector.id == CONNECTOR_ID_EDP) | ||
1012 | dc->hwss.edp_power_control(link, true); | ||
1013 | |||
1014 | link->link_enc->funcs->hw_init(link->link_enc); | ||
1015 | |||
1016 | /* Check for enabled DIG to identify enabled display */ | ||
1017 | if (link->link_enc->funcs->is_dig_enabled && | ||
1018 | link->link_enc->funcs->is_dig_enabled(link->link_enc)) | ||
1019 | link->link_status.link_active = true; | ||
1020 | } | ||
1021 | } | ||
1022 | 962 | ||
1023 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | 963 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
1024 | struct timing_generator *tg = dc->res_pool->timing_generators[i]; | 964 | struct timing_generator *tg = dc->res_pool->timing_generators[i]; |
1025 | 965 | ||
1026 | if (tg->funcs->is_tg_enabled(tg)) | 966 | if (tg->funcs->is_tg_enabled(tg)) |
1027 | tg->funcs->lock(tg); | 967 | tg->funcs->lock(tg); |
1028 | } | ||
1029 | |||
1030 | /* Blank controller using driver code instead of | ||
1031 | * command table. | ||
1032 | */ | ||
1033 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
1034 | struct timing_generator *tg = dc->res_pool->timing_generators[i]; | ||
1035 | 968 | ||
969 | /* Blank controller using driver code instead of | ||
970 | * command table. | ||
971 | */ | ||
1036 | if (tg->funcs->is_tg_enabled(tg)) { | 972 | if (tg->funcs->is_tg_enabled(tg)) { |
1037 | tg->funcs->set_blank(tg, true); | 973 | tg->funcs->set_blank(tg, true); |
1038 | hwss_wait_for_blank_complete(tg); | 974 | hwss_wait_for_blank_complete(tg); |
1039 | } | 975 | } |
1040 | } | 976 | } |
1041 | 977 | ||
1042 | /* Reset all MPCC muxes */ | ||
1043 | dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc); | 978 | dc->res_pool->mpc->funcs->mpc_init(dc->res_pool->mpc); |
1044 | 979 | ||
1045 | for (i = 0; i < dc->res_pool->timing_generator_count; i++) { | 980 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
1046 | struct timing_generator *tg = dc->res_pool->timing_generators[i]; | 981 | struct timing_generator *tg = dc->res_pool->timing_generators[i]; |
1047 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | ||
1048 | struct hubp *hubp = dc->res_pool->hubps[i]; | 982 | struct hubp *hubp = dc->res_pool->hubps[i]; |
1049 | struct dpp *dpp = dc->res_pool->dpps[i]; | 983 | struct dpp *dpp = dc->res_pool->dpps[i]; |
984 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | ||
985 | |||
986 | dpp->funcs->dpp_reset(dpp); | ||
1050 | 987 | ||
1051 | pipe_ctx->stream_res.tg = tg; | 988 | pipe_ctx->stream_res.tg = tg; |
1052 | pipe_ctx->pipe_idx = i; | 989 | pipe_ctx->pipe_idx = i; |
@@ -1064,18 +1001,9 @@ static void dcn10_init_hw(struct dc *dc) | |||
1064 | pipe_ctx->stream_res.opp = dc->res_pool->opps[i]; | 1001 | pipe_ctx->stream_res.opp = dc->res_pool->opps[i]; |
1065 | 1002 | ||
1066 | hwss1_plane_atomic_disconnect(dc, pipe_ctx); | 1003 | hwss1_plane_atomic_disconnect(dc, pipe_ctx); |
1067 | } | ||
1068 | |||
1069 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
1070 | struct timing_generator *tg = dc->res_pool->timing_generators[i]; | ||
1071 | 1004 | ||
1072 | if (tg->funcs->is_tg_enabled(tg)) | 1005 | if (tg->funcs->is_tg_enabled(tg)) |
1073 | tg->funcs->unlock(tg); | 1006 | tg->funcs->unlock(tg); |
1074 | } | ||
1075 | |||
1076 | for (i = 0; i < dc->res_pool->pipe_count; i++) { | ||
1077 | struct timing_generator *tg = dc->res_pool->timing_generators[i]; | ||
1078 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; | ||
1079 | 1007 | ||
1080 | dcn10_disable_plane(dc, pipe_ctx); | 1008 | dcn10_disable_plane(dc, pipe_ctx); |
1081 | 1009 | ||
@@ -1084,10 +1012,73 @@ static void dcn10_init_hw(struct dc *dc) | |||
1084 | 1012 | ||
1085 | tg->funcs->tg_init(tg); | 1013 | tg->funcs->tg_init(tg); |
1086 | } | 1014 | } |
1015 | } | ||
1016 | |||
1017 | static void dcn10_init_hw(struct dc *dc) | ||
1018 | { | ||
1019 | int i; | ||
1020 | struct abm *abm = dc->res_pool->abm; | ||
1021 | struct dmcu *dmcu = dc->res_pool->dmcu; | ||
1022 | struct dce_hwseq *hws = dc->hwseq; | ||
1023 | struct dc_bios *dcb = dc->ctx->dc_bios; | ||
1024 | |||
1025 | if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { | ||
1026 | REG_WRITE(REFCLK_CNTL, 0); | ||
1027 | REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1); | ||
1028 | REG_WRITE(DIO_MEM_PWR_CTRL, 0); | ||
1087 | 1029 | ||
1088 | /* end of FPGA. Below if real ASIC */ | 1030 | if (!dc->debug.disable_clock_gate) { |
1089 | if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) | 1031 | /* enable all DCN clock gating */ |
1032 | REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); | ||
1033 | |||
1034 | REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); | ||
1035 | |||
1036 | REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); | ||
1037 | } | ||
1038 | |||
1039 | enable_power_gating_plane(dc->hwseq, true); | ||
1040 | |||
1041 | /* end of FPGA. Below if real ASIC */ | ||
1090 | return; | 1042 | return; |
1043 | } | ||
1044 | |||
1045 | if (!dcb->funcs->is_accelerated_mode(dcb)) { | ||
1046 | bool allow_self_fresh_force_enable = | ||
1047 | hububu1_is_allow_self_refresh_enabled( | ||
1048 | dc->res_pool->hubbub); | ||
1049 | |||
1050 | bios_golden_init(dc); | ||
1051 | |||
1052 | /* WA for making DF sleep when idle after resume from S0i3. | ||
1053 | * DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by | ||
1054 | * command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0 | ||
1055 | * before calling command table and it changed to 1 after, | ||
1056 | * it should be set back to 0. | ||
1057 | */ | ||
1058 | if (allow_self_fresh_force_enable == false && | ||
1059 | hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub)) | ||
1060 | hubbub1_allow_self_refresh_control(dc->res_pool->hubbub, true); | ||
1061 | |||
1062 | disable_vga(dc->hwseq); | ||
1063 | } | ||
1064 | |||
1065 | for (i = 0; i < dc->link_count; i++) { | ||
1066 | /* Power up AND update implementation according to the | ||
1067 | * required signal (which may be different from the | ||
1068 | * default signal on connector). | ||
1069 | */ | ||
1070 | struct dc_link *link = dc->links[i]; | ||
1071 | |||
1072 | if (link->link_enc->connector.id == CONNECTOR_ID_EDP) | ||
1073 | dc->hwss.edp_power_control(link, true); | ||
1074 | |||
1075 | link->link_enc->funcs->hw_init(link->link_enc); | ||
1076 | |||
1077 | /* Check for enabled DIG to identify enabled display */ | ||
1078 | if (link->link_enc->funcs->is_dig_enabled && | ||
1079 | link->link_enc->funcs->is_dig_enabled(link->link_enc)) | ||
1080 | link->link_status.link_active = true; | ||
1081 | } | ||
1091 | 1082 | ||
1092 | for (i = 0; i < dc->res_pool->audio_count; i++) { | 1083 | for (i = 0; i < dc->res_pool->audio_count; i++) { |
1093 | struct audio *audio = dc->res_pool->audios[i]; | 1084 | struct audio *audio = dc->res_pool->audios[i]; |
@@ -1118,6 +1109,9 @@ static void dcn10_init_hw(struct dc *dc) | |||
1118 | enable_power_gating_plane(dc->hwseq, true); | 1109 | enable_power_gating_plane(dc->hwseq, true); |
1119 | 1110 | ||
1120 | memset(&dc->res_pool->clk_mgr->clks, 0, sizeof(dc->res_pool->clk_mgr->clks)); | 1111 | memset(&dc->res_pool->clk_mgr->clks, 0, sizeof(dc->res_pool->clk_mgr->clks)); |
1112 | |||
1113 | if (dc->hwss.init_pipes) | ||
1114 | dc->hwss.init_pipes(dc, dc->current_state); | ||
1121 | } | 1115 | } |
1122 | 1116 | ||
1123 | static void reset_hw_ctx_wrap( | 1117 | static void reset_hw_ctx_wrap( |
@@ -2718,6 +2712,7 @@ static void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx) | |||
2718 | static const struct hw_sequencer_funcs dcn10_funcs = { | 2712 | static const struct hw_sequencer_funcs dcn10_funcs = { |
2719 | .program_gamut_remap = program_gamut_remap, | 2713 | .program_gamut_remap = program_gamut_remap, |
2720 | .init_hw = dcn10_init_hw, | 2714 | .init_hw = dcn10_init_hw, |
2715 | .init_pipes = dcn10_init_pipes, | ||
2721 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, | 2716 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
2722 | .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, | 2717 | .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, |
2723 | .update_plane_addr = dcn10_update_plane_addr, | 2718 | .update_plane_addr = dcn10_update_plane_addr, |
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index d6a85f48b6d1..341b4810288c 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | |||
@@ -70,6 +70,8 @@ struct hw_sequencer_funcs { | |||
70 | 70 | ||
71 | void (*init_hw)(struct dc *dc); | 71 | void (*init_hw)(struct dc *dc); |
72 | 72 | ||
73 | void (*init_pipes)(struct dc *dc, struct dc_state *context); | ||
74 | |||
73 | enum dc_status (*apply_ctx_to_hw)( | 75 | enum dc_status (*apply_ctx_to_hw)( |
74 | struct dc *dc, struct dc_state *context); | 76 | struct dc *dc, struct dc_state *context); |
75 | 77 | ||