drm/amdgpu/display: add MALL support (v2)
Enable Memory Access at Last Level (MALL) feature for display. v2: squash in 64 bit division fixes Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
4005809bb1
commit
52f2e83e2f
7 changed files with 110 additions and 1 deletions
|
@ -53,6 +53,7 @@
|
||||||
#define DALSMC_MSG_GetDcModeMaxDpmFreq 0xC
|
#define DALSMC_MSG_GetDcModeMaxDpmFreq 0xC
|
||||||
#define DALSMC_MSG_SetMinDeepSleepDcefclk 0xD
|
#define DALSMC_MSG_SetMinDeepSleepDcefclk 0xD
|
||||||
#define DALSMC_MSG_NumOfDisplays 0xE
|
#define DALSMC_MSG_NumOfDisplays 0xE
|
||||||
|
#define DALSMC_MSG_SetDisplayRefreshFromMall 0xF
|
||||||
#define DALSMC_MSG_SetExternalClientDfCstateAllow 0x10
|
#define DALSMC_MSG_SetExternalClientDfCstateAllow 0x10
|
||||||
#define DALSMC_MSG_BacoAudioD3PME 0x11
|
#define DALSMC_MSG_BacoAudioD3PME 0x11
|
||||||
#define DALSMC_Message_Count 0x12
|
#define DALSMC_Message_Count 0x12
|
||||||
|
|
|
@ -145,6 +145,16 @@ static void dcn3_build_wm_range_table(struct clk_mgr_internal *clk_mgr)
|
||||||
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz;
|
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz;
|
||||||
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF;
|
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF;
|
||||||
|
|
||||||
|
/* Set D - MALL - SR enter and exit times adjusted for MALL */
|
||||||
|
// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].valid = true;
|
||||||
|
// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us = pstate_latency_us;
|
||||||
|
// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us = 2;
|
||||||
|
// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us = 4;
|
||||||
|
// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.wm_type = WATERMARKS_MALL;
|
||||||
|
// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_dcfclk = 0;
|
||||||
|
// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_dcfclk = 0xFFFF;
|
||||||
|
// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.min_uclk = min_uclk_mhz;
|
||||||
|
// clk_mgr->base.bw_params->wm_table.nv_entries[WM_D].pmfw_breakdown.max_uclk = 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcn3_init_clocks(struct clk_mgr *clk_mgr_base)
|
void dcn3_init_clocks(struct clk_mgr *clk_mgr_base)
|
||||||
|
|
|
@ -297,6 +297,15 @@ void dcn30_smu_set_num_of_displays(struct clk_mgr_internal *clk_mgr, uint32_t nu
|
||||||
DALSMC_MSG_NumOfDisplays, num_displays, NULL);
|
DALSMC_MSG_NumOfDisplays, num_displays, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dcn30_smu_set_display_refresh_from_mall(struct clk_mgr_internal *clk_mgr, bool enable, uint8_t cache_timer_delay, uint8_t cache_timer_scale)
|
||||||
|
{
|
||||||
|
/* bits 8:7 for cache timer scale, bits 6:1 for cache timer delay, bit 0 = 1 for enable, = 0 for disable */
|
||||||
|
uint32_t param = (cache_timer_scale << 7) | (cache_timer_delay << 1) | (enable ? 1 : 0);
|
||||||
|
|
||||||
|
dcn30_smu_send_msg_with_param(clk_mgr,
|
||||||
|
DALSMC_MSG_SetDisplayRefreshFromMall, param, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void dcn30_smu_set_external_client_df_cstate_allow(struct clk_mgr_internal *clk_mgr, bool enable)
|
void dcn30_smu_set_external_client_df_cstate_allow(struct clk_mgr_internal *clk_mgr, bool enable)
|
||||||
{
|
{
|
||||||
smu_print("SMU Set external client df cstate allow: enable = %d\n", enable);
|
smu_print("SMU Set external client df cstate allow: enable = %d\n", enable);
|
||||||
|
|
|
@ -70,6 +70,7 @@ typedef enum {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
WATERMARKS_CLOCK_RANGE = 0,
|
WATERMARKS_CLOCK_RANGE = 0,
|
||||||
WATERMARKS_DUMMY_PSTATE,
|
WATERMARKS_DUMMY_PSTATE,
|
||||||
|
WATERMARKS_MALL,
|
||||||
WATERMARKS_COUNT,
|
WATERMARKS_COUNT,
|
||||||
} WATERMARKS_FLAGS_e;
|
} WATERMARKS_FLAGS_e;
|
||||||
|
|
||||||
|
@ -102,6 +103,7 @@ unsigned int dcn30_smu_get_dpm_freq_by_index(struct clk_mgr_internal *clk_mgr, P
|
||||||
unsigned int dcn30_smu_get_dc_mode_max_dpm_freq(struct clk_mgr_internal *clk_mgr, PPCLK_e clk);
|
unsigned int dcn30_smu_get_dc_mode_max_dpm_freq(struct clk_mgr_internal *clk_mgr, PPCLK_e clk);
|
||||||
void dcn30_smu_set_min_deep_sleep_dcef_clk(struct clk_mgr_internal *clk_mgr, uint32_t freq_mhz);
|
void dcn30_smu_set_min_deep_sleep_dcef_clk(struct clk_mgr_internal *clk_mgr, uint32_t freq_mhz);
|
||||||
void dcn30_smu_set_num_of_displays(struct clk_mgr_internal *clk_mgr, uint32_t num_displays);
|
void dcn30_smu_set_num_of_displays(struct clk_mgr_internal *clk_mgr, uint32_t num_displays);
|
||||||
|
void dcn30_smu_set_display_refresh_from_mall(struct clk_mgr_internal *clk_mgr, bool enable, uint8_t cache_timer_delay, uint8_t cache_timer_scale);
|
||||||
void dcn30_smu_set_external_client_df_cstate_allow(struct clk_mgr_internal *clk_mgr, bool enable);
|
void dcn30_smu_set_external_client_df_cstate_allow(struct clk_mgr_internal *clk_mgr, bool enable);
|
||||||
void dcn30_smu_set_pme_workaround(struct clk_mgr_internal *clk_mgr);
|
void dcn30_smu_set_pme_workaround(struct clk_mgr_internal *clk_mgr);
|
||||||
|
|
||||||
|
|
|
@ -696,6 +696,10 @@ void dcn30_program_dmdata_engine(struct pipe_ctx *pipe_ctx)
|
||||||
|
|
||||||
bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
|
bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
|
||||||
{
|
{
|
||||||
|
union dmub_rb_cmd cmd;
|
||||||
|
unsigned int surface_size, refresh_hz, denom;
|
||||||
|
uint32_t tmr_delay = 0, tmr_scale = 0;
|
||||||
|
|
||||||
if (!dc->ctx->dmub_srv)
|
if (!dc->ctx->dmub_srv)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -710,12 +714,75 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable)
|
||||||
/* Fail eligibility on a visible stream */
|
/* Fail eligibility on a visible stream */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove hard code size
|
||||||
|
if (surface_size < 128 * 1024 * 1024) {
|
||||||
|
refresh_hz = div_u64((unsigned long long) dc->current_state->streams[0]->timing.pix_clk_100hz *
|
||||||
|
100LL,
|
||||||
|
(dc->current_state->streams[0]->timing.v_total *
|
||||||
|
dc->current_state->streams[0]->timing.h_total));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delay_Us = 65.28 * (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale
|
||||||
|
* Delay_Us / 65.28 = (64 + MallFrameCacheTmrDly) * 2^MallFrameCacheTmrScale
|
||||||
|
* (Delay_Us / 65.28) / 2^MallFrameCacheTmrScale = 64 + MallFrameCacheTmrDly
|
||||||
|
* MallFrameCacheTmrDly = ((Delay_Us / 65.28) / 2^MallFrameCacheTmrScale) - 64
|
||||||
|
* = (1000000 / refresh) / 65.28 / 2^MallFrameCacheTmrScale - 64
|
||||||
|
* = 1000000 / (refresh * 65.28 * 2^MallFrameCacheTmrScale) - 64
|
||||||
|
* = (1000000 * 100) / (refresh * 6528 * 2^MallFrameCacheTmrScale) - 64
|
||||||
|
*
|
||||||
|
* need to round up the result of the division before the subtraction
|
||||||
|
*/
|
||||||
|
denom = refresh_hz * 6528;
|
||||||
|
tmr_delay = div_u64((100000000LL + denom - 1), denom) - 64LL;
|
||||||
|
|
||||||
|
/* scale should be increased until it fits into 6 bits */
|
||||||
|
while (tmr_delay & ~0x3F) {
|
||||||
|
tmr_scale++;
|
||||||
|
|
||||||
|
if (tmr_scale > 3) {
|
||||||
|
/* The delay exceeds the range of the hystersis timer */
|
||||||
|
ASSERT(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
denom *= 2;
|
||||||
|
tmr_delay = div_u64((100000000LL + denom - 1), denom) - 64LL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable MALL */
|
||||||
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
|
cmd.mall.header.type = DMUB_CMD__MALL;
|
||||||
|
cmd.mall.header.sub_type =
|
||||||
|
DMUB_CMD__MALL_ACTION_ALLOW;
|
||||||
|
cmd.mall.header.payload_bytes =
|
||||||
|
sizeof(cmd.mall) -
|
||||||
|
sizeof(cmd.mall.header);
|
||||||
|
cmd.mall.tmr_delay = tmr_delay;
|
||||||
|
cmd.mall.tmr_scale = tmr_scale;
|
||||||
|
|
||||||
|
dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
|
||||||
|
dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No applicable optimizations */
|
/* No applicable optimizations */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Disable MALL */
|
||||||
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
|
cmd.mall.header.type = DMUB_CMD__MALL;
|
||||||
|
cmd.mall.header.sub_type = DMUB_CMD__MALL_ACTION_DISALLOW;
|
||||||
|
cmd.mall.header.payload_bytes =
|
||||||
|
sizeof(cmd.mall) - sizeof(cmd.mall.header);
|
||||||
|
|
||||||
|
dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
|
||||||
|
dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
|
||||||
|
dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2247,7 +2247,7 @@ void dcn30_calculate_wm_and_dlg(
|
||||||
/* Set D:
|
/* Set D:
|
||||||
* DCFCLK: Min Required
|
* DCFCLK: Min Required
|
||||||
* FCLK(proportional to UCLK): 1GHz or Max
|
* FCLK(proportional to UCLK): 1GHz or Max
|
||||||
* sr_enter_exit = 4, sr_exit = 2us
|
* MALL stutter, sr_enter_exit = 4, sr_exit = 2us
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) {
|
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) {
|
||||||
|
|
|
@ -298,6 +298,7 @@ enum dmub_cmd_type {
|
||||||
DMUB_CMD__REG_REG_WAIT = 4,
|
DMUB_CMD__REG_REG_WAIT = 4,
|
||||||
DMUB_CMD__PLAT_54186_WA = 5,
|
DMUB_CMD__PLAT_54186_WA = 5,
|
||||||
DMUB_CMD__PSR = 64,
|
DMUB_CMD__PSR = 64,
|
||||||
|
DMUB_CMD__MALL = 65,
|
||||||
DMUB_CMD__ABM = 66,
|
DMUB_CMD__ABM = 66,
|
||||||
DMUB_CMD__HW_LOCK = 69,
|
DMUB_CMD__HW_LOCK = 69,
|
||||||
DMUB_CMD__DP_AUX_ACCESS = 70,
|
DMUB_CMD__DP_AUX_ACCESS = 70,
|
||||||
|
@ -425,6 +426,18 @@ struct dmub_rb_cmd_PLAT_54186_wa {
|
||||||
struct dmub_cmd_PLAT_54186_wa flip;
|
struct dmub_cmd_PLAT_54186_wa flip;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dmub_rb_cmd_mall {
|
||||||
|
struct dmub_cmd_header header;
|
||||||
|
union dmub_addr cursor_copy_src;
|
||||||
|
union dmub_addr cursor_copy_dst;
|
||||||
|
uint32_t tmr_delay;
|
||||||
|
uint32_t tmr_scale;
|
||||||
|
uint16_t cursor_width;
|
||||||
|
uint16_t cursor_pitch;
|
||||||
|
uint16_t cursor_height;
|
||||||
|
uint8_t cursor_bpp;
|
||||||
|
};
|
||||||
|
|
||||||
struct dmub_cmd_digx_encoder_control_data {
|
struct dmub_cmd_digx_encoder_control_data {
|
||||||
union dig_encoder_control_parameters_v1_5 dig;
|
union dig_encoder_control_parameters_v1_5 dig;
|
||||||
};
|
};
|
||||||
|
@ -556,6 +569,12 @@ enum psr_version {
|
||||||
PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF,
|
PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum dmub_cmd_mall_type {
|
||||||
|
DMUB_CMD__MALL_ACTION_ALLOW = 0,
|
||||||
|
DMUB_CMD__MALL_ACTION_DISALLOW = 1,
|
||||||
|
DMUB_CMD__MALL_ACTION_COPY_CURSOR = 2,
|
||||||
|
};
|
||||||
|
|
||||||
struct dmub_cmd_psr_copy_settings_data {
|
struct dmub_cmd_psr_copy_settings_data {
|
||||||
union dmub_psr_debug_flags debug;
|
union dmub_psr_debug_flags debug;
|
||||||
uint16_t psr_level;
|
uint16_t psr_level;
|
||||||
|
@ -761,6 +780,7 @@ union dmub_rb_cmd {
|
||||||
struct dmub_rb_cmd_psr_enable psr_enable;
|
struct dmub_rb_cmd_psr_enable psr_enable;
|
||||||
struct dmub_rb_cmd_psr_set_level psr_set_level;
|
struct dmub_rb_cmd_psr_set_level psr_set_level;
|
||||||
struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa;
|
struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa;
|
||||||
|
struct dmub_rb_cmd_mall mall;
|
||||||
struct dmub_rb_cmd_abm_set_pipe abm_set_pipe;
|
struct dmub_rb_cmd_abm_set_pipe abm_set_pipe;
|
||||||
struct dmub_rb_cmd_abm_set_backlight abm_set_backlight;
|
struct dmub_rb_cmd_abm_set_backlight abm_set_backlight;
|
||||||
struct dmub_rb_cmd_abm_set_level abm_set_level;
|
struct dmub_rb_cmd_abm_set_level abm_set_level;
|
||||||
|
|
Loading…
Add table
Reference in a new issue