mirror of
https://github.com/torvalds/linux.git
synced 2026-04-28 11:32:28 -04:00
Merge tag 'drm-next-5.5-2019-11-01' of git://people.freedesktop.org/~agd5f/linux into drm-next
drm-next-5.5-2019-11-01: amdgpu: - Add EEPROM support for Arcturus - Enable VCN encode support for Arcturus - Misc PSP fixes - Misc DC fixes - swSMU cleanup amdkfd: - Misc cleanups - Fix typo in cu bitmap parsing Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191101190607.3763-1-alexander.deucher@amd.com
This commit is contained in:
@@ -1202,15 +1202,9 @@ static void dcn20_update_dchubp_dpp(
|
||||
struct dpp *dpp = pipe_ctx->plane_res.dpp;
|
||||
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
|
||||
|
||||
if (pipe_ctx->update_flags.bits.dppclk) {
|
||||
if (pipe_ctx->update_flags.bits.dppclk)
|
||||
dpp->funcs->dpp_dppclk_control(dpp, false, true);
|
||||
|
||||
dc->res_pool->dccg->funcs->update_dpp_dto(
|
||||
dc->res_pool->dccg,
|
||||
dpp->inst,
|
||||
pipe_ctx->plane_res.bw.dppclk_khz);
|
||||
}
|
||||
|
||||
/* TODO: Need input parameter to tell current DCHUB pipe tie to which OTG
|
||||
* VTG is within DCHUBBUB which is commond block share by each pipe HUBP.
|
||||
* VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
|
||||
@@ -1996,6 +1990,28 @@ static void dcn20_reset_hw_ctx_wrap(
|
||||
}
|
||||
}
|
||||
|
||||
void dcn20_get_mpctree_visual_confirm_color(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct tg_color *color)
|
||||
{
|
||||
const struct tg_color pipe_colors[6] = {
|
||||
{MAX_TG_COLOR_VALUE, 0, 0}, // red
|
||||
{MAX_TG_COLOR_VALUE, 0, MAX_TG_COLOR_VALUE}, // yellow
|
||||
{0, MAX_TG_COLOR_VALUE, 0}, // blue
|
||||
{MAX_TG_COLOR_VALUE / 2, 0, MAX_TG_COLOR_VALUE / 2}, // purple
|
||||
{0, 0, MAX_TG_COLOR_VALUE}, // green
|
||||
{MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE * 2 / 3, 0}, // orange
|
||||
};
|
||||
|
||||
struct pipe_ctx *top_pipe = pipe_ctx;
|
||||
|
||||
while (top_pipe->top_pipe) {
|
||||
top_pipe = top_pipe->top_pipe;
|
||||
}
|
||||
|
||||
*color = pipe_colors[top_pipe->pipe_idx];
|
||||
}
|
||||
|
||||
static void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct hubp *hubp = pipe_ctx->plane_res.hubp;
|
||||
@@ -2013,6 +2029,9 @@ static void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {
|
||||
dcn10_get_surface_visual_confirm_color(
|
||||
pipe_ctx, &blnd_cfg.black_color);
|
||||
} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_MPCTREE) {
|
||||
dcn20_get_mpctree_visual_confirm_color(
|
||||
pipe_ctx, &blnd_cfg.black_color);
|
||||
}
|
||||
|
||||
if (per_pixel_alpha)
|
||||
|
||||
@@ -109,5 +109,7 @@ bool dcn20_set_blend_lut(
|
||||
struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
|
||||
bool dcn20_set_shaper_3dlut(
|
||||
struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state);
|
||||
|
||||
void dcn20_get_mpctree_visual_confirm_color(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
struct tg_color *color);
|
||||
#endif /* __DC_HWSS_DCN20_H__ */
|
||||
|
||||
@@ -742,6 +742,33 @@ static const struct dce110_aux_registers_mask aux_mask = {
|
||||
DCN_AUX_MASK_SH_LIST(_MASK)
|
||||
};
|
||||
|
||||
static int map_transmitter_id_to_phy_instance(
|
||||
enum transmitter transmitter)
|
||||
{
|
||||
switch (transmitter) {
|
||||
case TRANSMITTER_UNIPHY_A:
|
||||
return 0;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_B:
|
||||
return 1;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_C:
|
||||
return 2;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_D:
|
||||
return 3;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_E:
|
||||
return 4;
|
||||
break;
|
||||
case TRANSMITTER_UNIPHY_F:
|
||||
return 5;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||
#define dsc_regsDCN20(id)\
|
||||
@@ -825,7 +852,7 @@ static const struct resource_caps res_cap_nv14 = {
|
||||
.num_audio = 6,
|
||||
.num_stream_encoder = 5,
|
||||
.num_pll = 5,
|
||||
.num_dwb = 0,
|
||||
.num_dwb = 1,
|
||||
.num_ddc = 5,
|
||||
};
|
||||
|
||||
@@ -836,7 +863,7 @@ static const struct dc_debug_options debug_defaults_drv = {
|
||||
.clock_trace = true,
|
||||
.disable_pplib_clock_request = true,
|
||||
.pipe_split_policy = MPC_SPLIT_DYNAMIC,
|
||||
.force_single_disp_pipe_split = true,
|
||||
.force_single_disp_pipe_split = false,
|
||||
.disable_dcc = DCC_ENABLE,
|
||||
.vsr_support = true,
|
||||
.performance_trace = false,
|
||||
@@ -1056,14 +1083,18 @@ struct link_encoder *dcn20_link_encoder_create(
|
||||
{
|
||||
struct dcn20_link_encoder *enc20 =
|
||||
kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
|
||||
int link_regs_id;
|
||||
|
||||
if (!enc20)
|
||||
return NULL;
|
||||
|
||||
link_regs_id =
|
||||
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
|
||||
|
||||
dcn20_link_encoder_construct(enc20,
|
||||
enc_init_data,
|
||||
&link_enc_feature,
|
||||
&link_enc_regs[enc_init_data->transmitter],
|
||||
&link_enc_regs[link_regs_id],
|
||||
&link_enc_aux_regs[enc_init_data->channel - 1],
|
||||
&link_enc_hpd_regs[enc_init_data->hpd_source],
|
||||
&le_shift,
|
||||
@@ -1612,7 +1643,7 @@ static void swizzle_to_dml_params(
|
||||
}
|
||||
}
|
||||
|
||||
static bool dcn20_split_stream_for_odm(
|
||||
bool dcn20_split_stream_for_odm(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct pipe_ctx *prev_odm_pipe,
|
||||
@@ -1633,7 +1664,6 @@ static bool dcn20_split_stream_for_odm(
|
||||
next_odm_pipe->stream_res.dsc = NULL;
|
||||
#endif
|
||||
if (prev_odm_pipe->next_odm_pipe && prev_odm_pipe->next_odm_pipe != next_odm_pipe) {
|
||||
ASSERT(!next_odm_pipe->next_odm_pipe);
|
||||
next_odm_pipe->next_odm_pipe = prev_odm_pipe->next_odm_pipe;
|
||||
next_odm_pipe->next_odm_pipe->prev_odm_pipe = next_odm_pipe;
|
||||
}
|
||||
@@ -1690,7 +1720,7 @@ static bool dcn20_split_stream_for_odm(
|
||||
return true;
|
||||
}
|
||||
|
||||
static void dcn20_split_stream_for_mpc(
|
||||
void dcn20_split_stream_for_mpc(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct pipe_ctx *primary_pipe,
|
||||
@@ -2148,7 +2178,7 @@ void dcn20_set_mcif_arb_params(
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||
static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
|
||||
bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -2183,7 +2213,7 @@ static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
|
||||
struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
const struct pipe_ctx *primary_pipe)
|
||||
@@ -2260,25 +2290,11 @@ static struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
|
||||
return secondary_pipe;
|
||||
}
|
||||
|
||||
bool dcn20_fast_validate_bw(
|
||||
void dcn20_merge_pipes_for_validate(
|
||||
struct dc *dc,
|
||||
struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
int *pipe_cnt_out,
|
||||
int *pipe_split_from,
|
||||
int *vlevel_out)
|
||||
struct dc_state *context)
|
||||
{
|
||||
bool out = false;
|
||||
|
||||
int pipe_cnt, i, pipe_idx, vlevel, vlevel_unsplit;
|
||||
bool force_split = false;
|
||||
int split_threshold = dc->res_pool->pipe_count / 2;
|
||||
bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC;
|
||||
|
||||
|
||||
ASSERT(pipes);
|
||||
if (!pipes)
|
||||
return false;
|
||||
int i;
|
||||
|
||||
/* merge previously split odm pipes since mode support needs to make the decision */
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
@@ -2333,35 +2349,19 @@ bool dcn20_fast_validate_bw(
|
||||
if (pipe->plane_state)
|
||||
resource_build_scaling_params(pipe);
|
||||
}
|
||||
}
|
||||
|
||||
if (dc->res_pool->funcs->populate_dml_pipes)
|
||||
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
|
||||
&context->res_ctx, pipes);
|
||||
else
|
||||
pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
|
||||
&context->res_ctx, pipes);
|
||||
int dcn20_validate_apply_pipe_split_flags(
|
||||
struct dc *dc,
|
||||
struct dc_state *context,
|
||||
int vlevel,
|
||||
bool *split)
|
||||
{
|
||||
int i, pipe_idx, vlevel_split;
|
||||
bool force_split = false;
|
||||
bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC;
|
||||
|
||||
*pipe_cnt_out = pipe_cnt;
|
||||
|
||||
if (!pipe_cnt) {
|
||||
out = true;
|
||||
goto validate_out;
|
||||
}
|
||||
|
||||
vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
|
||||
|
||||
if (vlevel > context->bw_ctx.dml.soc.num_states)
|
||||
goto validate_fail;
|
||||
|
||||
if ((context->stream_count > split_threshold && dc->current_state->stream_count <= split_threshold)
|
||||
|| (context->stream_count <= split_threshold && dc->current_state->stream_count > split_threshold))
|
||||
context->commit_hints.full_update_needed = true;
|
||||
|
||||
/*initialize pipe_just_split_from to invalid idx*/
|
||||
for (i = 0; i < MAX_PIPES; i++)
|
||||
pipe_split_from[i] = -1;
|
||||
|
||||
/* Single display only conditionals get set here */
|
||||
/* Single display loop, exits if there is more than one display */
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
bool exit_loop = false;
|
||||
@@ -2388,38 +2388,107 @@ bool dcn20_fast_validate_bw(
|
||||
if (exit_loop)
|
||||
break;
|
||||
}
|
||||
|
||||
if (context->stream_count > split_threshold)
|
||||
/* TODO: fix dc bugs and remove this split threshold thing */
|
||||
if (context->stream_count > dc->res_pool->pipe_count / 2)
|
||||
avoid_split = true;
|
||||
|
||||
vlevel_unsplit = vlevel;
|
||||
/* Avoid split loop looks for lowest voltage level that allows most unsplit pipes possible */
|
||||
if (avoid_split) {
|
||||
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||
continue;
|
||||
|
||||
for (vlevel_split = vlevel; vlevel <= context->bw_ctx.dml.soc.num_states; vlevel++)
|
||||
if (context->bw_ctx.dml.vba.NoOfDPP[vlevel][0][pipe_idx] == 1)
|
||||
break;
|
||||
/* Impossible to not split this pipe */
|
||||
if (vlevel > context->bw_ctx.dml.soc.num_states)
|
||||
vlevel = vlevel_split;
|
||||
pipe_idx++;
|
||||
}
|
||||
context->bw_ctx.dml.vba.maxMpcComb = 0;
|
||||
}
|
||||
|
||||
/* Split loop sets which pipe should be split based on dml outputs and dc flags */
|
||||
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||
continue;
|
||||
for (; vlevel_unsplit <= context->bw_ctx.dml.soc.num_states; vlevel_unsplit++)
|
||||
if (context->bw_ctx.dml.vba.NoOfDPP[vlevel_unsplit][0][pipe_idx] == 1)
|
||||
break;
|
||||
|
||||
if (force_split || context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] > 1)
|
||||
split[i] = true;
|
||||
if ((pipe->stream->view_format ==
|
||||
VIEW_3D_FORMAT_SIDE_BY_SIDE ||
|
||||
pipe->stream->view_format ==
|
||||
VIEW_3D_FORMAT_TOP_AND_BOTTOM) &&
|
||||
(pipe->stream->timing.timing_3d_format ==
|
||||
TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
|
||||
pipe->stream->timing.timing_3d_format ==
|
||||
TIMING_3D_FORMAT_SIDE_BY_SIDE))
|
||||
split[i] = true;
|
||||
if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) {
|
||||
split[i] = true;
|
||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx] = true;
|
||||
}
|
||||
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx] =
|
||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
|
||||
/* Adjust dppclk when split is forced, do not bother with dispclk */
|
||||
if (split[i] && context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1)
|
||||
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] /= 2;
|
||||
pipe_idx++;
|
||||
}
|
||||
|
||||
return vlevel;
|
||||
}
|
||||
|
||||
bool dcn20_fast_validate_bw(
|
||||
struct dc *dc,
|
||||
struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
int *pipe_cnt_out,
|
||||
int *pipe_split_from,
|
||||
int *vlevel_out)
|
||||
{
|
||||
bool out = false;
|
||||
bool split[MAX_PIPES] = { false };
|
||||
int pipe_cnt, i, pipe_idx, vlevel;
|
||||
|
||||
ASSERT(pipes);
|
||||
if (!pipes)
|
||||
return false;
|
||||
|
||||
dcn20_merge_pipes_for_validate(dc, context);
|
||||
|
||||
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, &context->res_ctx, pipes);
|
||||
|
||||
*pipe_cnt_out = pipe_cnt;
|
||||
|
||||
if (!pipe_cnt) {
|
||||
out = true;
|
||||
goto validate_out;
|
||||
}
|
||||
|
||||
vlevel = dml_get_voltage_level(&context->bw_ctx.dml, pipes, pipe_cnt);
|
||||
|
||||
if (vlevel > context->bw_ctx.dml.soc.num_states)
|
||||
goto validate_fail;
|
||||
|
||||
vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split);
|
||||
|
||||
/*initialize pipe_just_split_from to invalid idx*/
|
||||
for (i = 0; i < MAX_PIPES; i++)
|
||||
pipe_split_from[i] = -1;
|
||||
|
||||
for (i = 0, pipe_idx = -1; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe;
|
||||
bool need_split = true;
|
||||
bool need_split3d;
|
||||
|
||||
if (!pipe->stream || pipe_split_from[i] >= 0)
|
||||
continue;
|
||||
|
||||
pipe_idx++;
|
||||
|
||||
if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) {
|
||||
force_split = true;
|
||||
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx] = true;
|
||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx] = true;
|
||||
}
|
||||
if (force_split && context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1)
|
||||
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] /= 2;
|
||||
if (!pipe->top_pipe && !pipe->plane_state && context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
|
||||
hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
|
||||
ASSERT(hsplit_pipe);
|
||||
@@ -2437,35 +2506,20 @@ bool dcn20_fast_validate_bw(
|
||||
if (pipe->top_pipe && pipe->plane_state == pipe->top_pipe->plane_state)
|
||||
continue;
|
||||
|
||||
need_split3d = ((pipe->stream->view_format ==
|
||||
VIEW_3D_FORMAT_SIDE_BY_SIDE ||
|
||||
pipe->stream->view_format ==
|
||||
VIEW_3D_FORMAT_TOP_AND_BOTTOM) &&
|
||||
(pipe->stream->timing.timing_3d_format ==
|
||||
TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
|
||||
pipe->stream->timing.timing_3d_format ==
|
||||
TIMING_3D_FORMAT_SIDE_BY_SIDE));
|
||||
|
||||
if (avoid_split && vlevel_unsplit <= context->bw_ctx.dml.soc.num_states && !force_split && !need_split3d) {
|
||||
need_split = false;
|
||||
vlevel = vlevel_unsplit;
|
||||
context->bw_ctx.dml.vba.maxMpcComb = 0;
|
||||
} else
|
||||
need_split = context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 2;
|
||||
|
||||
/* We do not support mpo + odm at the moment */
|
||||
if (hsplit_pipe && hsplit_pipe->plane_state != pipe->plane_state
|
||||
&& context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx])
|
||||
goto validate_fail;
|
||||
|
||||
if (need_split3d || need_split || force_split) {
|
||||
if (split[i]) {
|
||||
if (!hsplit_pipe || hsplit_pipe->plane_state != pipe->plane_state) {
|
||||
/* pipe not split previously needs split */
|
||||
hsplit_pipe = dcn20_find_secondary_pipe(dc, &context->res_ctx, dc->res_pool, pipe);
|
||||
ASSERT(hsplit_pipe || force_split);
|
||||
if (!hsplit_pipe)
|
||||
ASSERT(hsplit_pipe);
|
||||
if (!hsplit_pipe) {
|
||||
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] *= 2;
|
||||
continue;
|
||||
|
||||
}
|
||||
if (context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
|
||||
if (!dcn20_split_stream_for_odm(
|
||||
&context->res_ctx, dc->res_pool,
|
||||
@@ -2504,7 +2558,7 @@ validate_out:
|
||||
return out;
|
||||
}
|
||||
|
||||
void dcn20_calculate_wm(
|
||||
static void dcn20_calculate_wm(
|
||||
struct dc *dc, struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
int *out_pipe_cnt,
|
||||
@@ -2525,7 +2579,7 @@ void dcn20_calculate_wm(
|
||||
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
|
||||
if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine =
|
||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
|
||||
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx];
|
||||
else
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine = 0;
|
||||
pipe_idx++;
|
||||
@@ -2534,7 +2588,7 @@ void dcn20_calculate_wm(
|
||||
context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
|
||||
if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine =
|
||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_split_from[i]];
|
||||
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_split_from[i]];
|
||||
else
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine = 0;
|
||||
}
|
||||
@@ -2580,6 +2634,7 @@ void dcn20_calculate_wm(
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN2_1)
|
||||
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
|
||||
#endif
|
||||
|
||||
if (vlevel < 2) {
|
||||
@@ -2905,6 +2960,7 @@ static struct resource_funcs dcn20_res_pool_funcs = {
|
||||
.populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context,
|
||||
.get_default_swizzle_mode = dcn20_get_default_swizzle_mode,
|
||||
.set_mcif_arb_params = dcn20_set_mcif_arb_params,
|
||||
.populate_dml_pipes = dcn20_populate_dml_pipes_from_context,
|
||||
.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link
|
||||
};
|
||||
|
||||
@@ -2913,8 +2969,6 @@ bool dcn20_dwbc_create(struct dc_context *ctx, struct resource_pool *pool)
|
||||
int i;
|
||||
uint32_t pipe_count = pool->res_cap->num_dwb;
|
||||
|
||||
ASSERT(pipe_count > 0);
|
||||
|
||||
for (i = 0; i < pipe_count; i++) {
|
||||
struct dcn20_dwbc *dwbc20 = kzalloc(sizeof(struct dcn20_dwbc),
|
||||
GFP_KERNEL);
|
||||
@@ -2983,7 +3037,7 @@ static void dcn20_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
|
||||
}
|
||||
}
|
||||
|
||||
static void cap_soc_clocks(
|
||||
void dcn20_cap_soc_clocks(
|
||||
struct _vcs_dpi_soc_bounding_box_st *bb,
|
||||
struct pp_smu_nv_clock_table max_clocks)
|
||||
{
|
||||
@@ -3050,7 +3104,7 @@ static void cap_soc_clocks(
|
||||
}
|
||||
}
|
||||
|
||||
static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
|
||||
void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
|
||||
struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states)
|
||||
{
|
||||
struct _vcs_dpi_voltage_scaling_st calculated_states[MAX_CLOCK_LIMIT_STATES];
|
||||
@@ -3065,10 +3119,14 @@ static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_
|
||||
|
||||
if (dc->bb_overrides.min_dcfclk_mhz > 0)
|
||||
min_dcfclk = dc->bb_overrides.min_dcfclk_mhz;
|
||||
else
|
||||
// Accounting for SOC/DCF relationship, we can go as high as
|
||||
// 506Mhz in Vmin. We need to code 507 since SMU will round down to 506.
|
||||
min_dcfclk = 507;
|
||||
else {
|
||||
if (ASICREV_IS_NAVI12_P(dc->ctx->asic_id.hw_internal_rev))
|
||||
min_dcfclk = 310;
|
||||
else
|
||||
// Accounting for SOC/DCF relationship, we can go as high as
|
||||
// 506Mhz in Vmin.
|
||||
min_dcfclk = 506;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_states; i++) {
|
||||
int min_fclk_required_by_uclk;
|
||||
@@ -3108,7 +3166,7 @@ static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_
|
||||
bb->clock_limits[num_calculated_states].state = bb->num_states;
|
||||
}
|
||||
|
||||
static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
|
||||
void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb)
|
||||
{
|
||||
kernel_fpu_begin();
|
||||
if ((int)(bb->sr_exit_time_us * 1000) != dc->bb_overrides.sr_exit_time_ns
|
||||
@@ -3307,14 +3365,14 @@ static bool init_soc_bounding_box(struct dc *dc,
|
||||
}
|
||||
|
||||
if (clock_limits_available && uclk_states_available && num_states)
|
||||
update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states);
|
||||
dcn20_update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states);
|
||||
else if (clock_limits_available)
|
||||
cap_soc_clocks(loaded_bb, max_clocks);
|
||||
dcn20_cap_soc_clocks(loaded_bb, max_clocks);
|
||||
}
|
||||
|
||||
loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
|
||||
loaded_ip->max_num_dpp = pool->base.pipe_count;
|
||||
patch_bounding_box(dc, loaded_bb);
|
||||
dcn20_patch_bounding_box(dc, loaded_bb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -95,6 +95,12 @@ struct display_stream_compressor *dcn20_dsc_create(
|
||||
struct dc_context *ctx, uint32_t inst);
|
||||
void dcn20_dsc_destroy(struct display_stream_compressor **dsc);
|
||||
|
||||
void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb);
|
||||
void dcn20_cap_soc_clocks(
|
||||
struct _vcs_dpi_soc_bounding_box_st *bb,
|
||||
struct pp_smu_nv_clock_table max_clocks);
|
||||
void dcn20_update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb,
|
||||
struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states);
|
||||
struct hubp *dcn20_hubp_create(
|
||||
struct dc_context *ctx,
|
||||
uint32_t inst);
|
||||
@@ -113,6 +119,31 @@ void dcn20_set_mcif_arb_params(
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
int pipe_cnt);
|
||||
bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate);
|
||||
void dcn20_merge_pipes_for_validate(
|
||||
struct dc *dc,
|
||||
struct dc_state *context);
|
||||
int dcn20_validate_apply_pipe_split_flags(
|
||||
struct dc *dc,
|
||||
struct dc_state *context,
|
||||
int vlevel,
|
||||
bool *split);
|
||||
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||
bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx);
|
||||
#endif
|
||||
void dcn20_split_stream_for_mpc(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct pipe_ctx *primary_pipe,
|
||||
struct pipe_ctx *secondary_pipe);
|
||||
bool dcn20_split_stream_for_odm(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct pipe_ctx *prev_odm_pipe,
|
||||
struct pipe_ctx *next_odm_pipe);
|
||||
struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
const struct pipe_ctx *primary_pipe);
|
||||
bool dcn20_fast_validate_bw(
|
||||
struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
||||
Reference in New Issue
Block a user