summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c62
1 files changed, 44 insertions, 18 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
index 5ae3419682c8..1c88d2edd381 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
@@ -58,6 +58,7 @@
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
#include "dcn20/dcn20_dccg.h"
+#include "dcn21/dcn21_dccg.h"
#include "dcn21_hubbub.h"
#include "dcn10/dcn10_resource.h"
#include "dce110/dce110_resource.h"
@@ -301,9 +302,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
.xfc_bus_transport_time_us = 4,
.xfc_xbuf_latency_tolerance_us = 4,
.use_urgent_burst_bw = 1,
- .num_states = 8,
- .allow_dram_self_refresh_or_dram_clock_change_in_vblank
- = dm_allow_self_refresh_and_mclk_switch
+ .num_states = 8
};
#ifndef MAX
@@ -706,7 +705,10 @@ static const struct dcn10_stream_encoder_mask se_mask = {
static void dcn21_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
static int dcn21_populate_dml_pipes_from_context(
- struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes);
+ struct dc *dc,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate);
static struct input_pixel_processor *dcn21_ipp_create(
struct dc_context *ctx, uint32_t inst)
@@ -1093,7 +1095,8 @@ void dcn21_calculate_wm(
display_e2e_pipe_params_st *pipes,
int *out_pipe_cnt,
int *pipe_split_from,
- int vlevel_req)
+ int vlevel_req,
+ bool fast_validate)
{
int pipe_cnt, i, pipe_idx;
int vlevel, vlevel_max;
@@ -1135,10 +1138,10 @@ void dcn21_calculate_wm(
if (pipe_cnt != pipe_idx) {
if (dc->res_pool->funcs->populate_dml_pipes)
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
- context, pipes);
+ context, pipes, fast_validate);
else
pipe_cnt = dcn21_populate_dml_pipes_from_context(dc,
- context, pipes);
+ context, pipes, fast_validate);
}
*out_pipe_cnt = pipe_cnt;
@@ -1179,7 +1182,8 @@ static bool dcn21_fast_validate_bw(
display_e2e_pipe_params_st *pipes,
int *pipe_cnt_out,
int *pipe_split_from,
- int *vlevel_out)
+ int *vlevel_out,
+ bool fast_validate)
{
bool out = false;
int split[MAX_PIPES] = { 0 };
@@ -1191,7 +1195,7 @@ static bool dcn21_fast_validate_bw(
dcn20_merge_pipes_for_validate(dc, context);
- pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes);
+ pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
*pipe_cnt_out = pipe_cnt;
@@ -1199,11 +1203,29 @@ static bool dcn21_fast_validate_bw(
out = true;
goto validate_out;
}
-
+ /*
+ * DML favors voltage over p-state, but we're more interested in
+ * supporting p-state over voltage. We can't support p-state in
+ * prefetch mode > 0 so try capping the prefetch mode to start.
+ */
+ context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank =
+ dm_allow_self_refresh_and_mclk_switch;
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 (vlevel > context->bw_ctx.dml.soc.num_states) {
+ /*
+ * If mode is unsupported or there's still no p-state support then
+ * fall back to favoring voltage.
+ *
+ * We don't actually support prefetch mode 2, so require that we
+ * at least support prefetch mode 1.
+ */
+ context->bw_ctx.dml.soc.allow_dram_self_refresh_or_dram_clock_change_in_vblank =
+ dm_allow_self_refresh;
+ 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, NULL);
@@ -1323,7 +1345,7 @@ bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context,
/*Unsafe due to current pipe merge and split logic*/
ASSERT(context != dc->current_state);
- out = dcn21_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel);
+ out = dcn21_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);
if (pipe_cnt == 0)
goto validate_out;
@@ -1338,7 +1360,7 @@ bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context,
goto validate_out;
}
- dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel);
+ dcn21_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);
dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
BW_VAL_TRACE_END_WATERMARKS();
@@ -1854,14 +1876,17 @@ static uint32_t read_pipe_fuses(struct dc_context *ctx)
}
static int dcn21_populate_dml_pipes_from_context(
- struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes)
+ struct dc *dc,
+ struct dc_state *context,
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate)
{
- uint32_t pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, context, pipes);
+ uint32_t pipe_cnt = dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
int i;
for (i = 0; i < pipe_cnt; i++) {
- pipes[i].pipe.src.hostvm = 1;
+ pipes[i].pipe.src.hostvm = dc->res_pool->hubbub->riommu_active;
pipes[i].pipe.src.gpuvm = 1;
}
@@ -1954,6 +1979,7 @@ static bool dcn21_resource_construct(
dc->caps.color.dpp.dgam_rom_caps.hlg = 0;
dc->caps.color.dpp.post_csc = 0;
dc->caps.color.dpp.gamma_corr = 0;
+ dc->caps.color.dpp.dgam_rom_for_yuv = 1;
dc->caps.color.dpp.hw_3d_lut = 1;
dc->caps.color.dpp.ogam_ram = 1;
@@ -2021,7 +2047,7 @@ static bool dcn21_resource_construct(
}
}
- pool->base.dccg = dccg2_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
+ pool->base.dccg = dccg21_create(ctx, &dccg_regs, &dccg_shift, &dccg_mask);
if (pool->base.dccg == NULL) {
dm_error("DC: failed to create dccg!\n");
BREAK_TO_DEBUGGER();