diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc')
57 files changed, 473 insertions, 256 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c index a737782b2840..b737cbc468f5 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c @@ -522,6 +522,11 @@ static void dcn315_clk_mgr_helper_populate_bw_params( bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[0]; bw_params->clk_table.entries[i].wck_ratio = 1; i++; + } else if (clock_table->NumDcfClkLevelsEnabled != clock_table->NumSocClkLevelsEnabled) { + bw_params->clk_table.entries[i-1].voltage = clock_table->SocVoltage[clock_table->NumSocClkLevelsEnabled - 1]; + bw_params->clk_table.entries[i-1].socclk_mhz = clock_table->SocClocks[clock_table->NumSocClkLevelsEnabled - 1]; + bw_params->clk_table.entries[i-1].dispclk_mhz = clock_table->DispClocks[clock_table->NumDispClkLevelsEnabled - 1]; + bw_params->clk_table.entries[i-1].dppclk_mhz = clock_table->DppClocks[clock_table->NumDispClkLevelsEnabled - 1]; } bw_params->clk_table.num_entries = i; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index ae5f1b7b4fef..52564b93f7eb 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -888,6 +888,10 @@ static bool dc_construct_ctx(struct dc *dc, dc->ctx = dc_ctx; + dc->link_srv = link_create_link_service(); + if (!dc->link_srv) + return false; + return true; } @@ -985,8 +989,6 @@ static bool dc_construct(struct dc *dc, goto fail; } - dc->link_srv = link_create_link_service(); - dc->res_pool = dc_create_resource_pool(dc, init_params, dc_ctx->dce_version); if (!dc->res_pool) goto fail; @@ -3492,22 +3494,6 @@ static void commit_planes_for_stream(struct dc *dc, dc_dmub_update_dirty_rect(dc, surface_count, stream, srf_updates, context); - if (update_type != UPDATE_TYPE_FAST) { - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; - - if ((new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) || - subvp_prev_use) { - // If old context or new context has phantom pipes, apply - // the phantom timings now. We can't change the phantom - // pipe configuration safely without driver acquiring - // the DMCUB lock first. - dc->hwss.apply_ctx_to_hw(dc, context); - break; - } - } - } - // Stream updates if (stream_update) commit_planes_do_stream_update(dc, stream, stream_update, update_type, context); @@ -3723,6 +3709,9 @@ static void commit_planes_for_stream(struct dc *dc, } } + if (update_type != UPDATE_TYPE_FAST) + dc->hwss.post_unlock_program_front_end(dc, context); + if (subvp_prev_use && !subvp_curr_use) { /* If disabling subvp, disable phantom streams after front end * programming has completed (we turn on phantom OTG in order @@ -3732,15 +3721,8 @@ static void commit_planes_for_stream(struct dc *dc, } if (update_type != UPDATE_TYPE_FAST) - dc->hwss.post_unlock_program_front_end(dc, context); - if (update_type != UPDATE_TYPE_FAST) - if (dc->hwss.commit_subvp_config) - dc->hwss.commit_subvp_config(dc, context); - - if (update_type != UPDATE_TYPE_FAST) if (dc->hwss.commit_subvp_config) dc->hwss.commit_subvp_config(dc, context); - /* Since phantom pipe programming is moved to post_unlock_program_front_end, * move the SubVP lock to after the phantom pipes have been setup */ diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c index 58fa911b1417..18e098568cb4 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c @@ -285,8 +285,7 @@ int dc_link_aux_transfer_raw(struct ddc_service *ddc, ddc, payload, operation_result); } -uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data( - struct dc *dc, uint8_t bw) +uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(const struct dc *dc, uint8_t bw) { return dc->link_srv->bw_kbps_from_raw_frl_link_rate_data(bw); } @@ -474,3 +473,8 @@ void dc_link_enable_hpd_filter(struct dc_link *link, bool enable) { link->dc->link_srv->enable_hpd_filter(link, enable); } + +bool dc_link_validate(struct dc *dc, const struct dc_stream_state *streams, const unsigned int count) +{ + return dc->link_srv->validate_dpia_bandwidth(streams, count); +} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c index 6c06587dd88c..5f6392ae31a6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c @@ -35,19 +35,15 @@ */ /** - ***************************************************************************** - * Function: dc_stat_get_dmub_notification + * dc_stat_get_dmub_notification * - * @brief - * Calls dmub layer to retrieve dmub notification + * Calls dmub layer to retrieve dmub notification * - * @param - * [in] dc: dc structure - * [in] notify: dmub notification structure + * @dc: dc structure + * @notify: dmub notification structure * - * @return + * Returns * None - ***************************************************************************** */ void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification *notify) { @@ -73,19 +69,15 @@ void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification } /** - ***************************************************************************** - * Function: dc_stat_get_dmub_dataout + * dc_stat_get_dmub_dataout * - * @brief - * Calls dmub layer to retrieve dmub gpint dataout + * Calls dmub layer to retrieve dmub gpint dataout * - * @param - * [in] dc: dc structure - * [in] dataout: dmub gpint dataout + * @dc: dc structure + * @dataout: dmub gpint dataout * - * @return + * Returns * None - ***************************************************************************** */ void dc_stat_get_dmub_dataout(const struct dc *dc, uint32_t *dataout) { diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 2818483964dd..e363a3c88250 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -45,7 +45,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.227" +#define DC_VER "3.2.229" #define MAX_SURFACES 3 #define MAX_PLANES 6 @@ -873,6 +873,8 @@ struct dc_debug_options { bool dig_fifo_off_in_blank; bool temp_mst_deallocation_sequence; bool override_dispclk_programming; + bool disable_fpo_optimizations; + bool support_eDP1_5; }; struct gpu_info_soc_bounding_box_v1_0; @@ -1768,8 +1770,7 @@ void dc_restore_link_res_map(const struct dc *dc, uint32_t *map); bool dc_link_update_dsc_config(struct pipe_ctx *pipe_ctx); /* translate a raw link rate data to bandwidth in kbps */ -uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data( - struct dc *dc, uint8_t bw); +uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(const struct dc *dc, uint8_t bw); /* determine the optimal bandwidth given link and required bw. * @link - current detected link @@ -2029,6 +2030,19 @@ void dc_link_handle_usb4_bw_alloc_response(struct dc_link *link, int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link( struct dc_link *link, int peak_bw); +/* + * Validate the BW of all the valid DPIA links to make sure it doesn't exceed + * available BW for each host router + * + * @dc: pointer to dc struct + * @stream: pointer to all possible streams + * @num_streams: number of valid DPIA streams + * + * return: TRUE if bw used by DPIAs doesn't exceed available BW else return FALSE + */ +bool dc_link_validate(struct dc *dc, const struct dc_stream_state *streams, + const unsigned int count); + /* Sink Interfaces - A sink corresponds to a display output device */ struct dc_container_id { diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index b5c6501c28fc..dd6f643254fe 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -302,27 +302,29 @@ static uint8_t dc_dmub_srv_get_pipes_for_stream(struct dc *dc, struct dc_stream_ return pipes; } -static int dc_dmub_srv_get_timing_generator_offset(struct dc *dc, struct dc_stream_state *stream) +static void dc_dmub_srv_populate_fams_pipe_info(struct dc *dc, struct dc_state *context, + struct pipe_ctx *head_pipe, + struct dmub_cmd_fw_assisted_mclk_switch_pipe_data *fams_pipe_data) { - int tg_inst = 0; - int i = 0; + int j; + int pipe_idx = 0; - for (i = 0; i < MAX_PIPES; i++) { - struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + fams_pipe_data->pipe_index[pipe_idx++] = head_pipe->plane_res.hubp->inst; + for (j = 0; j < dc->res_pool->pipe_count; j++) { + struct pipe_ctx *split_pipe = &context->res_ctx.pipe_ctx[j]; - if (pipe->stream == stream && pipe->stream_res.tg) { - tg_inst = pipe->stream_res.tg->inst; - break; + if (split_pipe->stream == head_pipe->stream && (split_pipe->top_pipe || split_pipe->prev_odm_pipe)) { + fams_pipe_data->pipe_index[pipe_idx++] = split_pipe->plane_res.hubp->inst; } } - return tg_inst; + fams_pipe_data->pipe_count = pipe_idx; } bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, struct dc_state *context) { union dmub_rb_cmd cmd = { 0 }; struct dmub_cmd_fw_assisted_mclk_switch_config *config_data = &cmd.fw_assisted_mclk_switch.config_data; - int i = 0; + int i = 0, k = 0; int ramp_up_num_steps = 1; // TODO: Ramp is currently disabled. Reenable it. uint8_t visual_confirm_enabled; @@ -337,17 +339,21 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru cmd.fw_assisted_mclk_switch.config_data.fams_enabled = should_manage_pstate; cmd.fw_assisted_mclk_switch.config_data.visual_confirm_enabled = visual_confirm_enabled; - for (i = 0; context && i < context->stream_count; i++) { - struct dc_stream_state *stream = context->streams[i]; - uint8_t min_refresh_in_hz = (stream->timing.min_refresh_in_uhz + 999999) / 1000000; - int tg_inst = dc_dmub_srv_get_timing_generator_offset(dc, stream); + for (i = 0, k = 0; context && i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - config_data->pipe_data[tg_inst].pix_clk_100hz = stream->timing.pix_clk_100hz; - config_data->pipe_data[tg_inst].min_refresh_in_hz = min_refresh_in_hz; - config_data->pipe_data[tg_inst].max_ramp_step = ramp_up_num_steps; - config_data->pipe_data[tg_inst].pipes = dc_dmub_srv_get_pipes_for_stream(dc, stream); + if (!pipe->top_pipe && !pipe->prev_odm_pipe && pipe->stream && pipe->stream->fpo_in_use) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + uint8_t min_refresh_in_hz = (pipe->stream->timing.min_refresh_in_uhz + 999999) / 1000000; + + config_data->pipe_data[k].pix_clk_100hz = pipe->stream->timing.pix_clk_100hz; + config_data->pipe_data[k].min_refresh_in_hz = min_refresh_in_hz; + config_data->pipe_data[k].max_ramp_step = ramp_up_num_steps; + config_data->pipe_data[k].pipes = dc_dmub_srv_get_pipes_for_stream(dc, pipe->stream); + dc_dmub_srv_populate_fams_pipe_info(dc, context, pipe, &config_data->pipe_data[k]); + k++; + } } - cmd.fw_assisted_mclk_switch.header.payload_bytes = sizeof(cmd.fw_assisted_mclk_switch) - sizeof(cmd.fw_assisted_mclk_switch.header); diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index af53278662ec..49aab1924665 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -47,14 +47,15 @@ enum dc_lane_count { */ enum dc_link_rate { LINK_RATE_UNKNOWN = 0, - LINK_RATE_LOW = 0x06, // Rate_1 (RBR) - 1.62 Gbps/Lane - LINK_RATE_RATE_2 = 0x08, // Rate_2 - 2.16 Gbps/Lane - LINK_RATE_RATE_3 = 0x09, // Rate_3 - 2.43 Gbps/Lane - LINK_RATE_HIGH = 0x0A, // Rate_4 (HBR) - 2.70 Gbps/Lane - LINK_RATE_RBR2 = 0x0C, // Rate_5 (RBR2)- 3.24 Gbps/Lane - LINK_RATE_RATE_6 = 0x10, // Rate_6 - 4.32 Gbps/Lane - LINK_RATE_HIGH2 = 0x14, // Rate_7 (HBR2)- 5.40 Gbps/Lane - LINK_RATE_HIGH3 = 0x1E, // Rate_8 (HBR3)- 8.10 Gbps/Lane + LINK_RATE_LOW = 0x06, // Rate_1 (RBR) - 1.62 Gbps/Lane + LINK_RATE_RATE_2 = 0x08, // Rate_2 - 2.16 Gbps/Lane + LINK_RATE_RATE_3 = 0x09, // Rate_3 - 2.43 Gbps/Lane + LINK_RATE_HIGH = 0x0A, // Rate_4 (HBR) - 2.70 Gbps/Lane + LINK_RATE_RBR2 = 0x0C, // Rate_5 (RBR2) - 3.24 Gbps/Lane + LINK_RATE_RATE_6 = 0x10, // Rate_6 - 4.32 Gbps/Lane + LINK_RATE_HIGH2 = 0x14, // Rate_7 (HBR2) - 5.40 Gbps/Lane + LINK_RATE_RATE_8 = 0x19, // Rate_8 - 6.75 Gbps/Lane + LINK_RATE_HIGH3 = 0x1E, // Rate_9 (HBR3) - 8.10 Gbps/Lane /* Starting from DP2.0 link rate enum directly represents actual * link rate value in unit of 10 mbps */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h index c364744b4c83..b015e80672ec 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h @@ -50,7 +50,6 @@ struct dp_hdmi_dongle_signature_data { /* DP-HDMI dongle slave address for retrieving dongle signature*/ #define DP_HDMI_DONGLE_ADDRESS 0x40 -static const uint8_t dp_hdmi_dongle_signature_str[] = "DP-HDMI ADAPTOR"; #define DP_HDMI_DONGLE_SIGNATURE_EOT 0x04 diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 567452599659..181a3408cc61 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -293,6 +293,7 @@ struct dc_stream_state { bool has_non_synchronizable_pclk; bool vblank_synchronized; + bool fpo_in_use; struct mall_stream_config mall_stream_config; }; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c index 67e3df7e1b05..462c7a3ec3cc 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -1157,6 +1157,7 @@ const struct pixel_rate_range_table_entry video_optimized_pixel_rates[] = { {25170, 25180, 25200, 1000, 1001}, //25.2MHz -> 25.17 {59340, 59350, 59400, 1000, 1001}, //59.4Mhz -> 59.340 {74170, 74180, 74250, 1000, 1001}, //74.25Mhz -> 74.1758 + {89910, 90000, 90000, 1000, 1001}, //90Mhz -> 89.91 {125870, 125880, 126000, 1000, 1001}, //126Mhz -> 125.87 {148350, 148360, 148500, 1000, 1001}, //148.5Mhz -> 148.3516 {167830, 167840, 168000, 1000, 1001}, //168Mhz -> 167.83 diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 19440bdf6344..9705d8f88382 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -33,6 +33,9 @@ #define MAX_PIPES 6 +static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3}; +static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5}; + /* * Convert dmcub psr state to dmcu psr state. */ @@ -250,7 +253,7 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_ dc_dmub_srv_wait_idle(dc->dmub_srv); } -/** +/* * Set PSR vtotal requirement for FreeSync PSR. */ static void dmub_psr_set_sink_vtotal_in_psr_active(struct dmub_psr *dmub, diff --git a/drivers/gpu/drm/amd/display/dc/dce60/Makefile b/drivers/gpu/drm/amd/display/dc/dce60/Makefile index dda596fa1cd7..fee331accc0e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce60/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dce60/Makefile @@ -23,7 +23,7 @@ # Makefile for the 'controller' sub-component of DAL. # It provides the control and status of HW CRTC block. -CFLAGS_AMDDALPATH)/dc/dce60/dce60_resource.o = $(call cc-disable-warning, override-init) +CFLAGS_$(AMDDALPATH)/dc/dce60/dce60_resource.o = $(call cc-disable-warning, override-init) DCE60 = dce60_timing_generator.o dce60_hw_sequencer.o \ dce60_resource.o 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 7f9cceb49f4e..1c3b6f25a782 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 @@ -726,11 +726,15 @@ void dcn10_hubp_pg_control( } } -static void power_on_plane( +static void power_on_plane_resources( struct dce_hwseq *hws, int plane_id) { DC_LOGGER_INIT(hws->ctx->logger); + + if (hws->funcs.dpp_root_clock_control) + hws->funcs.dpp_root_clock_control(hws, plane_id, true); + if (REG(DC_IP_REQUEST_CNTL)) { REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); @@ -1237,11 +1241,15 @@ void dcn10_plane_atomic_power_down(struct dc *dc, hws->funcs.hubp_pg_control(hws, hubp->inst, false); dpp->funcs->dpp_reset(dpp); + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); DC_LOG_DEBUG( "Power gated front end %d\n", hubp->inst); } + + if (hws->funcs.dpp_root_clock_control) + hws->funcs.dpp_root_clock_control(hws, dpp->inst, false); } /* disable HW used by plane. @@ -2462,7 +2470,7 @@ static void dcn10_enable_plane( undo_DEGVIDCN10_253_wa(dc); - power_on_plane(dc->hwseq, + power_on_plane_resources(dc->hwseq, pipe_ctx->plane_res.hubp->inst); /* enable DCFCLK current DCHUB */ @@ -3385,7 +3393,9 @@ static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) for (test_pipe = pipe_ctx->top_pipe; test_pipe; test_pipe = test_pipe->top_pipe) { // Skip invisible layer and pipe-split plane on same layer - if (!test_pipe->plane_state->visible || test_pipe->plane_state->layer_index == cur_layer) + if (!test_pipe->plane_state || + !test_pipe->plane_state->visible || + test_pipe->plane_state->layer_index == cur_layer) continue; r2 = test_pipe->plane_res.scl_data.recout; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h index 0b37bb0e184b..db766689af58 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h @@ -161,10 +161,20 @@ struct dcn_optc_registers { uint32_t OTG_CRC_CNTL2; uint32_t OTG_CRC0_DATA_RG; uint32_t OTG_CRC0_DATA_B; + uint32_t OTG_CRC1_DATA_B; + uint32_t OTG_CRC2_DATA_B; + uint32_t OTG_CRC3_DATA_B; + uint32_t OTG_CRC1_DATA_RG; + uint32_t OTG_CRC2_DATA_RG; + uint32_t OTG_CRC3_DATA_RG; uint32_t OTG_CRC0_WINDOWA_X_CONTROL; uint32_t OTG_CRC0_WINDOWA_Y_CONTROL; uint32_t OTG_CRC0_WINDOWB_X_CONTROL; uint32_t OTG_CRC0_WINDOWB_Y_CONTROL; + uint32_t OTG_CRC1_WINDOWA_X_CONTROL; + uint32_t OTG_CRC1_WINDOWA_Y_CONTROL; + uint32_t OTG_CRC1_WINDOWB_X_CONTROL; + uint32_t OTG_CRC1_WINDOWB_Y_CONT |
