mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 10:33:41 +02:00
drm/amd/display: Firmware assisted MCLK switch and FS
[WHY] Memory clock switching has great potential for power savings. [HOW] The driver code was modified to notify the DMCUB firmware that it should stretch the vertical blank of frames when a memory clock switch is about to start so that no blackouts happen on the screen due to unavailability of the frame buffer. The driver logic to determine when such firmware assisted strategy can be initiated is also implemented and consists on checking prerequisites of the feature. Acked-by: Alan Liu <HaoPing.Liu@amd.com> Signed-off-by: Felipe Clark <felipe.clark@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
a34136a3b3
commit
c2fbe663ec
|
|
@ -397,7 +397,6 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
|||
struct dc_crtc_timing_adjust *adjust)
|
||||
{
|
||||
int i;
|
||||
bool ret = false;
|
||||
|
||||
stream->adjust.v_total_max = adjust->v_total_max;
|
||||
stream->adjust.v_total_mid = adjust->v_total_mid;
|
||||
|
|
@ -412,10 +411,10 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
|||
1,
|
||||
*adjust);
|
||||
|
||||
ret = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2650,6 +2649,9 @@ static void copy_stream_update_to_stream(struct dc *dc,
|
|||
if (update->vrr_infopacket)
|
||||
stream->vrr_infopacket = *update->vrr_infopacket;
|
||||
|
||||
if (update->allow_freesync)
|
||||
stream->allow_freesync = *update->allow_freesync;
|
||||
|
||||
if (update->crtc_timing_adjust)
|
||||
stream->adjust = *update->crtc_timing_adjust;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include "dc_dmub_srv.h"
|
||||
#include "../dmub/dmub_srv.h"
|
||||
#include "dm_helpers.h"
|
||||
#include "dc_hw_types.h"
|
||||
#include "core_types.h"
|
||||
|
||||
#define CTX dc_dmub_srv->ctx
|
||||
#define DC_LOGGER CTX->logger
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@
|
|||
|
||||
struct dmub_srv;
|
||||
struct dc;
|
||||
struct pipe_ctx;
|
||||
struct dc_crtc_timing_adjust;
|
||||
struct dc_crtc_timing;
|
||||
struct dc_state;
|
||||
|
||||
struct dc_reg_helper_state {
|
||||
bool gather_in_progress;
|
||||
|
|
@ -69,7 +73,6 @@ bool dc_dmub_srv_get_dmub_outbox0_msg(const struct dc *dc, struct dmcub_trace_bu
|
|||
void dc_dmub_trace_event_control(struct dc *dc, bool enable);
|
||||
|
||||
void dc_dmub_srv_query_caps_cmd(struct dmub_srv *dmub);
|
||||
|
||||
void dc_dmub_srv_clear_inbox0_ack(struct dc_dmub_srv *dmub_srv);
|
||||
void dc_dmub_srv_wait_for_inbox0_ack(struct dc_dmub_srv *dmub_srv);
|
||||
void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv *dmub_srv, union dmub_inbox0_data_register data);
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ struct dc_stream_state {
|
|||
bool use_vsc_sdp_for_colorimetry;
|
||||
bool ignore_msa_timing_param;
|
||||
|
||||
bool allow_freesync;
|
||||
bool freesync_on_desktop;
|
||||
|
||||
bool converter_disable_audio;
|
||||
|
|
@ -295,9 +296,9 @@ struct dc_stream_update {
|
|||
struct dc_info_packet *vrr_infopacket;
|
||||
struct dc_info_packet *vsc_infopacket;
|
||||
struct dc_info_packet *vsp_infopacket;
|
||||
|
||||
bool *dpms_off;
|
||||
bool integer_scaling_update;
|
||||
bool *allow_freesync;
|
||||
|
||||
struct colorspace_transform *gamut_remap;
|
||||
enum dc_color_space *output_color_space;
|
||||
|
|
|
|||
|
|
@ -2613,7 +2613,6 @@ void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
|||
dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id);
|
||||
|
||||
ASSERT(new_mpcc != NULL);
|
||||
|
||||
hubp->opp_id = pipe_ctx->stream_res.opp->inst;
|
||||
hubp->mpcc_id = mpcc_id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2446,7 +2446,6 @@ void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
|||
NULL,
|
||||
hubp->inst,
|
||||
mpcc_id);
|
||||
|
||||
dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id);
|
||||
|
||||
ASSERT(new_mpcc != NULL);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@
|
|||
#include "dc_dmub_srv.h"
|
||||
#include "link_hwss.h"
|
||||
#include "dpcd_defs.h"
|
||||
#include "../dcn20/dcn20_hwseq.h"
|
||||
#include "dcn30_resource.h"
|
||||
#include "inc/dc_link_dp.h"
|
||||
#include "inc/link_dpcd.h"
|
||||
|
||||
|
|
@ -344,17 +346,6 @@ void dcn30_enable_writeback(
|
|||
dwb->funcs->enable(dwb, &wb_info->dwb_params);
|
||||
}
|
||||
|
||||
void dcn30_prepare_bandwidth(struct dc *dc,
|
||||
struct dc_state *context)
|
||||
{
|
||||
if (dc->clk_mgr->dc_mode_softmax_enabled)
|
||||
if (dc->clk_mgr->clks.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 &&
|
||||
context->bw_ctx.bw.dcn.clk.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
|
||||
dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz);
|
||||
|
||||
dcn20_prepare_bandwidth(dc, context);
|
||||
}
|
||||
|
||||
void dcn30_disable_writeback(
|
||||
struct dc *dc,
|
||||
unsigned int dwb_pipe_inst)
|
||||
|
|
@ -647,6 +638,9 @@ void dcn30_init_hw(struct dc *dc)
|
|||
if (dc->res_pool->hubbub->funcs->init_crb)
|
||||
dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
|
||||
|
||||
// Get DMCUB capabilities
|
||||
dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv->dmub);
|
||||
dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
|
||||
}
|
||||
|
||||
void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
|
||||
|
|
@ -962,3 +956,15 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc,
|
|||
pipe_ctx->stream_res.opp->funcs->opp_set_disp_pattern_generator(pipe_ctx->stream_res.opp, test_pattern,
|
||||
color_space, color_depth, solid_color, width, height, offset);
|
||||
}
|
||||
|
||||
void dcn30_prepare_bandwidth(struct dc *dc,
|
||||
struct dc_state *context)
|
||||
{
|
||||
if (dc->clk_mgr->dc_mode_softmax_enabled)
|
||||
if (dc->clk_mgr->clks.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 &&
|
||||
context->bw_ctx.bw.dcn.clk.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
|
||||
dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz);
|
||||
|
||||
dcn20_prepare_bandwidth(dc, context);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,9 +47,6 @@ void dcn30_disable_writeback(
|
|||
struct dc *dc,
|
||||
unsigned int dwb_pipe_inst);
|
||||
|
||||
void dcn30_prepare_bandwidth(struct dc *dc,
|
||||
struct dc_state *context);
|
||||
|
||||
bool dcn30_mmhubbub_warmup(
|
||||
struct dc *dc,
|
||||
unsigned int num_dwb,
|
||||
|
|
@ -83,4 +80,12 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc,
|
|||
const struct tg_color *solid_color,
|
||||
int width, int height, int offset);
|
||||
|
||||
void dcn30_set_hubp_blank(const struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
bool blank_enable);
|
||||
|
||||
void dcn30_prepare_bandwidth(struct dc *dc,
|
||||
struct dc_state *context);
|
||||
|
||||
|
||||
#endif /* __DC_HWSS_DCN30_H__ */
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = {
|
|||
.pipe_control_lock = dcn20_pipe_control_lock,
|
||||
.interdependent_update_lock = dcn10_lock_all_pipes,
|
||||
.cursor_lock = dcn10_cursor_lock,
|
||||
.prepare_bandwidth = dcn20_prepare_bandwidth,
|
||||
.prepare_bandwidth = dcn30_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn20_optimize_bandwidth,
|
||||
.update_bandwidth = dcn20_update_bandwidth,
|
||||
.set_drr = dcn10_set_drr,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "dcn30_optc.h"
|
||||
#include "dc.h"
|
||||
#include "dcn_calc_math.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
|
||||
#include "dml/dcn30/dcn30_fpu.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@
|
|||
#include "vm_helper.h"
|
||||
#include "dcn20/dcn20_vmid.h"
|
||||
#include "amdgpu_socbb.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ struct dce_hwseq;
|
|||
struct timing_generator;
|
||||
struct tg_color;
|
||||
struct output_pixel_processor;
|
||||
struct mpcc_blnd_cfg;
|
||||
|
||||
struct hwseq_private_funcs {
|
||||
|
||||
|
|
|
|||
|
|
@ -1374,6 +1374,11 @@ unsigned long long mod_freesync_calc_field_rate_from_timing(
|
|||
return field_rate_in_uhz;
|
||||
}
|
||||
|
||||
bool mod_freesync_get_freesync_enabled(struct mod_vrr_params *pVrr, struct dc_stream_state *const pStream)
|
||||
{
|
||||
return (pVrr->state != VRR_STATE_UNSUPPORTED) && (pVrr->state != VRR_STATE_DISABLED);
|
||||
}
|
||||
|
||||
bool mod_freesync_is_valid_range(uint32_t min_refresh_cap_in_uhz,
|
||||
uint32_t max_refresh_cap_in_uhz,
|
||||
uint32_t nominal_field_rate_in_uhz)
|
||||
|
|
|
|||
|
|
@ -194,4 +194,8 @@ unsigned int mod_freesync_calc_v_total_from_refresh(
|
|||
const struct dc_stream_state *stream,
|
||||
unsigned int refresh_in_uhz);
|
||||
|
||||
// Returns true when FreeSync is supported and enabled (even if it is inactive)
|
||||
bool mod_freesync_get_freesync_enabled(struct mod_vrr_params *pVrr,
|
||||
struct dc_stream_state *const pStream);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user