summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc')
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/conversion.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/vector.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/bios_parser.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c70
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c172
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c8
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h10
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c33
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link.c74
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c36
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h13
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_bios_types.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_link.h12
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_stream.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_types.h21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c24
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h7
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c12
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h16
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_panel_cntl.c36
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c82
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c126
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c15
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c24
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c69
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c82
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c44
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c23
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_dccg.c129
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_dccg.h36
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c62
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h83
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c49
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c12
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c59
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c62
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h38
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c204
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dm_helpers.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/core_types.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h84
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c4
67 files changed, 1335 insertions, 629 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/basics/conversion.c b/drivers/gpu/drm/amd/display/dc/basics/conversion.c
index 50b47f11875c..24ed03d8cda7 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/conversion.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/conversion.c
@@ -24,6 +24,7 @@
*/
#include "dm_services.h"
+#include "conversion.h"
#define DIVIDER 10000
diff --git a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
index 1e9a2d352068..1726bdf89bae 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
@@ -26,6 +26,10 @@
#include "dm_services.h"
#include "include/fixed31_32.h"
+static const struct fixed31_32 dc_fixpt_two_pi = { 26986075409LL };
+static const struct fixed31_32 dc_fixpt_ln2 = { 2977044471LL };
+static const struct fixed31_32 dc_fixpt_ln2_div_2 = { 1488522236LL };
+
static inline unsigned long long abs_i64(
long long arg)
{
diff --git a/drivers/gpu/drm/amd/display/dc/basics/vector.c b/drivers/gpu/drm/amd/display/dc/basics/vector.c
index 8f93d25f91ee..706c803c4d3b 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/vector.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/vector.c
@@ -52,7 +52,7 @@ bool dal_vector_construct(
return true;
}
-bool dal_vector_presized_costruct(
+static bool dal_vector_presized_costruct(
struct vector *vector,
struct dc_context *ctx,
uint32_t count,
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
index ad394aefa5d9..23a373ca94b5 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
@@ -1198,6 +1198,7 @@ static enum bp_result bios_parser_get_embedded_panel_info(
default:
break;
}
+ break;
default:
break;
}
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
index 43922fa358a9..670c26583817 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -903,6 +903,7 @@ static enum bp_result bios_parser_get_soc_bb_info(
break;
case 4:
result = get_soc_bb_info_v4_4(bp, soc_bb_info);
+ break;
default:
break;
}
@@ -1019,6 +1020,7 @@ static enum bp_result bios_parser_get_embedded_panel_info(
default:
break;
}
+ break;
default:
break;
}
@@ -1453,6 +1455,72 @@ static struct atom_encoder_caps_record *get_encoder_cap_record(
return NULL;
}
+static struct atom_disp_connector_caps_record *get_disp_connector_caps_record(
+ struct bios_parser *bp,
+ struct atom_display_object_path_v2 *object)
+{
+ struct atom_common_record_header *header;
+ uint32_t offset;
+
+ if (!object) {
+ BREAK_TO_DEBUGGER(); /* Invalid object */
+ return NULL;
+ }
+
+ offset = object->disp_recordoffset + bp->object_info_tbl_offset;
+
+ for (;;) {
+ header = GET_IMAGE(struct atom_common_record_header, offset);
+
+ if (!header)
+ return NULL;
+
+ offset += header->record_size;
+
+ if (header->record_type == LAST_RECORD_TYPE ||
+ !header->record_size)
+ break;
+
+ if (header->record_type != ATOM_DISP_CONNECTOR_CAPS_RECORD_TYPE)
+ continue;
+
+ if (sizeof(struct atom_disp_connector_caps_record) <=
+ header->record_size)
+ return (struct atom_disp_connector_caps_record *)header;
+ }
+
+ return NULL;
+}
+
+static enum bp_result bios_parser_get_disp_connector_caps_info(
+ struct dc_bios *dcb,
+ struct graphics_object_id object_id,
+ struct bp_disp_connector_caps_info *info)
+{
+ struct bios_parser *bp = BP_FROM_DCB(dcb);
+ struct atom_display_object_path_v2 *object;
+ struct atom_disp_connector_caps_record *record = NULL;
+
+ if (!info)
+ return BP_RESULT_BADINPUT;
+
+ object = get_bios_object(bp, object_id);
+
+ if (!object)
+ return BP_RESULT_BADINPUT;
+
+ record = get_disp_connector_caps_record(bp, object);
+ if (!record)
+ return BP_RESULT_NORECORD;
+
+ info->INTERNAL_DISPLAY = (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY)
+ ? 1 : 0;
+ info->INTERNAL_DISPLAY_BL = (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL)
+ ? 1 : 0;
+
+ return BP_RESULT_OK;
+}
+
static enum bp_result get_vram_info_v23(
struct bios_parser *bp,
struct dc_vram_info *info)
@@ -2461,6 +2529,8 @@ static const struct dc_vbios_funcs vbios_funcs = {
.enable_lvtma_control = bios_parser_enable_lvtma_control,
.get_soc_bb_info = bios_parser_get_soc_bb_info,
+
+ .get_disp_connector_caps_info = bios_parser_get_disp_connector_caps_info,
};
static bool bios_parser2_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
index 73c91027572b..995ffbbf64e7 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
@@ -94,7 +94,7 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m
if (edp_link) {
clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active;
- dc_link_set_psr_allow_active(edp_link, false, false);
+ dc_link_set_psr_allow_active(edp_link, false, false, false);
}
}
@@ -104,7 +104,8 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
struct dc_link *edp_link = get_edp_link(dc);
if (edp_link)
- dc_link_set_psr_allow_active(edp_link, clk_mgr->psr_allow_active_cache, false);
+ dc_link_set_psr_allow_active(edp_link,
+ clk_mgr->psr_allow_active_cache, false, false);
if (dc->hwss.optimize_pwr_state)
dc->hwss.optimize_pwr_state(dc, dc->current_state);
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
index c42d2f4e81e8..6f4fe8fce6b7 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
@@ -103,6 +103,31 @@ void rn_set_low_power_state(struct clk_mgr *clk_mgr_base)
clk_mgr_base->clks.pwr_state = DCN_PWR_STATE_LOW_POWER;
}
+static void rn_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
+ struct dc_state *context, int ref_dpp_clk, bool safe_to_lower)
+{
+ int i;
+
+ clk_mgr->dccg->ref_dppclk = ref_dpp_clk;
+
+ for (i = 0; i < clk_mgr->base.ctx->dc->res_pool->pipe_count; i++) {
+ int dpp_inst, dppclk_khz, prev_dppclk_khz;
+
+ /* Loop index will match dpp->inst if resource exists,
+ * and we want to avoid dependency on dpp object
+ */
+ dpp_inst = i;
+ dppclk_khz = context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz;
+
+ prev_dppclk_khz = clk_mgr->dccg->pipe_dppclk_khz[i];
+
+ if (safe_to_lower || prev_dppclk_khz < dppclk_khz)
+ clk_mgr->dccg->funcs->update_dpp_dto(
+ clk_mgr->dccg, dpp_inst, dppclk_khz);
+ }
+}
+
+
void rn_update_clocks(struct clk_mgr *clk_mgr_base,
struct dc_state *context,
bool safe_to_lower)
@@ -158,13 +183,20 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
// workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow.
// Do not adjust dppclk if dppclk is 0 to avoid unexpected result
- if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
- if (new_clocks->dppclk_khz < 100000 && new_clocks->dppclk_khz > 0)
- new_clocks->dppclk_khz = 100000;
+ if (new_clocks->dppclk_khz < 100000 && new_clocks->dppclk_khz > 0)
+ new_clocks->dppclk_khz = 100000;
+
+ /*
+ * Temporally ignore thew 0 cases for disp and dpp clks.
+ * We may have a new feature that requires 0 clks in the future.
+ */
+ if (new_clocks->dppclk_khz == 0 || new_clocks->dispclk_khz == 0) {
+ new_clocks->dppclk_khz = clk_mgr_base->clks.dppclk_khz;
+ new_clocks->dispclk_khz = clk_mgr_base->clks.dispclk_khz;
}
- if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) {
- if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz)
+ if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr_base->clks.dppclk_khz)) {
+ if (clk_mgr_base->clks.dppclk_khz > new_clocks->dppclk_khz)
dpp_clock_lowered = true;
clk_mgr_base->clks.dppclk_khz = new_clocks->dppclk_khz;
update_dppclk = true;
@@ -172,22 +204,42 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
- rn_vbios_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
+ clk_mgr_base->clks.actual_dispclk_khz = rn_vbios_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
update_dispclk = true;
}
if (dpp_clock_lowered) {
- // increase per DPP DTO before lowering global dppclk
- dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
- rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+ // increase per DPP DTO before lowering global dppclk with requested dppclk
+ rn_update_clocks_update_dpp_dto(
+ clk_mgr,
+ context,
+ clk_mgr_base->clks.dppclk_khz,
+ safe_to_lower);
+
+ clk_mgr_base->clks.actual_dppclk_khz =
+ rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+
+ //update dpp dto with actual dpp clk.
+ rn_update_clocks_update_dpp_dto(
+ clk_mgr,
+ context,
+ clk_mgr_base->clks.actual_dppclk_khz,
+ safe_to_lower);
+
} else {
// increase global DPPCLK before lowering per DPP DTO
if (update_dppclk || update_dispclk)
- rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+ clk_mgr_base->clks.actual_dppclk_khz =
+ rn_vbios_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz);
+
// always update dtos unless clock is lowered and not safe to lower
if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz)
- dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower);
+ rn_update_clocks_update_dpp_dto(
+ clk_mgr,
+ context,
+ clk_mgr_base->clks.actual_dppclk_khz,
+ safe_to_lower);
}
if (update_dispclk &&
@@ -198,7 +250,6 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base,
}
}
-
static int get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr)
{
/* get FbMult value */
@@ -570,14 +621,14 @@ static struct clk_bw_params rn_bw_params = {
};
-static struct wm_table ddr4_wm_table = {
+static struct wm_table ddr4_wm_table_gs = {
.entries = {
{
.wm_inst = WM_A,
.wm_type = WM_TYPE_PSTATE_CHG,
.pstate_latency_us = 11.72,
- .sr_exit_time_us = 6.09,
- .sr_enter_plus_exit_time_us = 7.14,
+ .sr_exit_time_us = 7.09,
+ .sr_enter_plus_exit_time_us = 8.14,
.valid = true,
},
{
@@ -607,7 +658,7 @@ static struct wm_table ddr4_wm_table = {
}
};
-static struct wm_table lpddr4_wm_table = {
+static struct wm_table lpddr4_wm_table_gs = {
.entries = {
{
.wm_inst = WM_A,
@@ -681,6 +732,80 @@ static struct wm_table lpddr4_wm_table_with_disabled_ppt = {
}
};
+static struct wm_table ddr4_wm_table_rn = {
+ .entries = {
+ {
+ .wm_inst = WM_A,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+ .sr_exit_time_us = 9.09,
+ .sr_enter_plus_exit_time_us = 10.14,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_B,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+ .sr_exit_time_us = 10.12,
+ .sr_enter_plus_exit_time_us = 11.48,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_C,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+ .sr_exit_time_us = 10.12,
+ .sr_enter_plus_exit_time_us = 11.48,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_D,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.72,
+ .sr_exit_time_us = 10.12,
+ .sr_enter_plus_exit_time_us = 11.48,
+ .valid = true,
+ },
+ }
+};
+
+static struct wm_table lpddr4_wm_table_rn = {
+ .entries = {
+ {
+ .wm_inst = WM_A,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 7.32,
+ .sr_enter_plus_exit_time_us = 8.38,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_B,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 9.82,
+ .sr_enter_plus_exit_time_us = 11.196,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_C,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 9.89,
+ .sr_enter_plus_exit_time_us = 11.24,
+ .valid = true,
+ },
+ {
+ .wm_inst = WM_D,
+ .wm_type = WM_TYPE_PSTATE_CHG,
+ .pstate_latency_us = 11.65333,
+ .sr_exit_time_us = 9.748,
+ .sr_enter_plus_exit_time_us = 11.102,
+ .valid = true,
+ },
+ }
+};
+
static unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage)
{
int i;
@@ -762,6 +887,11 @@ void rn_clk_mgr_construct(
struct dc_debug_options *debug = &ctx->dc->debug;
struct dpm_clocks clock_table = { 0 };
enum pp_smu_status status = 0;
+ int is_green_sardine = 0;
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+ is_green_sardine = ASICREV_IS_GREEN_SARDINE(ctx->asic_id.hw_internal_rev);
+#endif
clk_mgr->base.ctx = ctx;
clk_mgr->base.funcs = &dcn21_funcs;
@@ -802,10 +932,16 @@ void rn_clk_mgr_construct(
if (clk_mgr->periodic_retraining_disabled) {
rn_bw_params.wm_table = lpddr4_wm_table_with_disabled_ppt;
} else {
- rn_bw_params.wm_table = lpddr4_wm_table;
+ if (is_green_sardine)
+ rn_bw_params.wm_table = lpddr4_wm_table_gs;
+ else
+ rn_bw_params.wm_table = lpddr4_wm_table_rn;
}
} else {
- rn_bw_params.wm_table = ddr4_wm_table;
+ if (is_green_sardine)
+ rn_bw_params.wm_table = ddr4_wm_table_gs;
+ else
+ rn_bw_params.wm_table = ddr4_wm_table_rn;
}
/* Saved clocks configured at boot for debug purposes */
rn_dump_clk_registers(&clk_mgr->base.boot_snapshot, &clk_mgr->base, &log_info);
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c
index 9a374522e963..11a7b583d561 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c
@@ -136,6 +136,10 @@ int rn_vbios_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dis
}
}
+ // pmfw always set clock more than or equal requested clock
+ if (!IS_DIAG_DC(dc->ctx->dce_environment))
+ ASSERT(actual_dispclk_set_mhz >= requested_dispclk_khz / 1000);
+
return actual_dispclk_set_mhz * 1000;
}
@@ -194,12 +198,16 @@ void rn_vbios_smu_set_phyclk(struct clk_mgr_internal *clk_mgr, int requested_phy
int rn_vbios_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz)
{
int actual_dppclk_set_mhz = -1;
+ struct dc *dc = clk_mgr->base.ctx->dc;
actual_dppclk_set_mhz = rn_vbios_smu_send_msg_with_param(
clk_mgr,
VBIOSSMC_MSG_SetDppclkFreq,
requested_dpp_khz / 1000);
+ if (!IS_DIAG_DC(dc->ctx->dce_environment))
+ ASSERT(actual_dppclk_set_mhz >= requested_dpp_khz / 1000);
+
return actual_dppclk_set_mhz * 1000;
}
@@ -239,5 +247,6 @@ int rn_vbios_smu_is_periodic_retraining_disabled(struct clk_mgr_internal *clk_mg
return rn_vbios_smu_send_msg_with_param(
clk_mgr,
VBIOSSMC_MSG_IsPeriodicRetrainingDisabled,
- 0);
+ 1); // if PMFW doesn't support this message, assume retraining is disabled
+ // so we only use most optimal watermark if we know retraining is enabled.
}
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
index 82cb688ba5e0..5b466f440d67 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
@@ -499,7 +499,7 @@ static void dcn3_init_clocks_fpga(struct clk_mgr *clk_mgr)
/* TODO: Implement the functions and remove the ifndef guard */
}
-static struct clk_mgr_funcs dcn3_fpga_funcs = {
+struct clk_mgr_funcs dcn3_fpga_funcs = {
.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
.update_clocks = dcn2_update_clocks_fpga,
.init_clocks = dcn3_init_clocks_fpga,
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
index 98cbb0ac095c..9a8e66bba9c0 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
@@ -32,9 +32,9 @@
// For dcn20_update_clocks_update_dpp_dto
#include "dcn20/dcn20_clk_mgr.h"
-#include "vg_clk_mgr.h"
-#include "dcn301_smu.h"
+
+#include "vg_clk_mgr.h"
#include "reg_helper.h"
#include "core_types.h"
#include "dm_helpers.h"
@@ -631,7 +631,7 @@ static unsigned int find_dcfclk_for_voltage(const struct vg_dpm_clocks *clock_ta
return 0;
}
-static void vg_clk_mgr_helper_populate_bw_params(
+void vg_clk_mgr_helper_populate_bw_params(
struct clk_mgr_internal *clk_mgr,
struct integrated_info *bios_info,
const struct vg_dpm_clocks *clock_table)
@@ -709,7 +709,7 @@ static struct vg_dpm_clocks dummy_clocks = {
static struct watermarks dummy_wms = { 0 };
-static void vg_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr,
+void vg_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr,
struct smu_dpm_clks *smu_dpm_clks)
{
struct vg_dpm_clocks *table = smu_dpm_clks->dpm_clks;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h
index 80497df20ba7..b5115b3123a1 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.h
@@ -39,5 +39,15 @@ void vg_clk_mgr_construct(struct dc_context *ctx,
void vg_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr);
+#include "dcn301_smu.h"
void vg_notify_wm_ranges(struct clk_mgr *clk_mgr_base);
+
+void vg_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr,
+ struct smu_dpm_clks *smu_dpm_clks);
+
+void vg_clk_mgr_helper_populate_bw_params(
+ struct clk_mgr_internal *clk_mgr,
+ struct integrated_info *bios_info,
+ const struct vg_dpm_clocks *clock_table);
+
#endif //__VG_CLK_MGR_H__
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 5951f7d4022f..58eb0d69873a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -149,6 +149,20 @@ static void destroy_links(struct dc *dc)
}
}
+static uint32_t get_num_of_internal_disp(struct dc_link **links, uint32_t num_links)
+{
+ int i;
+ uint32_t count = 0;
+
+ for (i = 0; i < num_links; i++) {
+ if (links[i]->connector_signal == SIGNAL_TYPE_EDP ||
+ links[i]->is_internal_display)
+ count++;
+ }
+
+ return count;
+}
+
static bool create_links(
struct dc *dc,
uint32_t num_virtual_links)
@@ -250,6 +264,8 @@ static bool create_links(
virtual_link_encoder_construct(link->link_enc, &enc_init);
}
+ dc->caps.num_of_internal_disp = get_num_of_internal_disp(dc->links, dc->link_count);
+
return true;
failed_alloc:
@@ -2782,6 +2798,19 @@ struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i)
return NULL;
}
+struct dc_stream_state *dc_stream_find_from_link(const struct dc_link *link)
+{
+ uint8_t i;
+ struct dc_context *ctx = link->ctx;
+
+ for (i = 0; i < ctx->dc->current_state->stream_count; i++) {
+ if (ctx->dc->current_state->streams[i]->link == link)
+ return ctx->dc->current_state->streams[i];
+ }
+
+ return NULL;
+}
+
enum dc_irq_source dc_interrupt_to_irq_source(
struct dc *dc,
uint32_t src_id,
@@ -3058,9 +3087,9 @@ bool dc_set_psr_allow_active(struct dc *dc, bool enable)
if (link->psr_settings.psr_feature_enabled) {
if (enable && !link->psr_settings.psr_allow_active)
- return dc_link_set_psr_allow_active(link, true, false);
+ return dc_link_set_psr_allow_active(link, true, false, false);
else if (!enable && link->psr_settings.psr_allow_active)
- return dc_link_set_psr_allow_active(link, false, true);
+ return dc_link_set_psr_allow_active(link, false, true, false);
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index ea9c459c9130..a901baf2aaef 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1060,6 +1060,7 @@ static bool dc_link_detect_helper(struct dc_link *link,
return false;
}
+ break;
default:
break;
}
@@ -1368,6 +1369,7 @@ static bool dc_link_construct(struct dc_link *link,
struct integrated_info info = {{{ 0 }}};
struct dc_bios *bios = init_params->dc->ctx->dc_bios;
const struct dc_vbios_funcs *bp_funcs = bios->funcs;
+ struct bp_disp_connector_caps_info disp_connect_caps_info = { 0 };
DC_LOGGER_INIT(dc_ctx->logger);
@@ -1388,6 +1390,12 @@ static bool dc_link_construct(struct dc_link *link,
link->link_id =
bios->funcs->get_connector_id(bios, init_params->connector_index);
+
+ if (bios->funcs->get_disp_connector_caps_info) {
+ bios->funcs->get_disp_connector_caps_info(bios, link->link_id, &disp_connect_caps_info);
+ link->is_internal_display = disp_connect_caps_info.INTERNAL_DISPLAY;
+ }
+
if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
dm_output_to_console("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
__func__, init_params->connector_index,
@@ -1730,7 +1738,7 @@ static enum dc_status enable_link_dp_mst(
/* sink signal type after MST branch is MST. Multiple MST sinks
* share one link. Link DP PHY is enable or training only once.
*/
- if (link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN)
+ if (link->link_status.link_active)
return DC_OK;
/* clear payload table */
@@ -2565,17 +2573,23 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
return true;
}
-bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool wait)
+bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active,
+ bool wait, bool force_static)
{
struct dc *dc = link->ctx->dc;
struct dmcu *dmcu = dc->res_pool->dmcu;
struct dmub_psr *psr = dc->res_pool->psr;
+ if (psr == NULL && force_static)
+ return false;
+
link->psr_settings.psr_allow_active = allow_active;
- if (psr != NULL && link->psr_settings.psr_feature_enabled)
+ if (psr != NULL && link->psr_settings.psr_feature_enabled) {
+ if (force_static && psr->funcs->psr_force_static)
+ psr->funcs->psr_force_static(psr);
psr->funcs->psr_enable(psr, allow_active, wait);
- else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled)
+ } else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled)
dmcu->funcs->set_psr_enable(dmcu, allow_active, wait);
else
return false;
@@ -2583,16 +2597,16 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool
return true;
}
-bool dc_link_get_psr_state(const struct dc_link *link, uint32_t *psr_state)
+bool dc_link_get_psr_state(const struct dc_link *link, enum dc_psr_state *state)
{
struct dc *dc = link->ctx->dc;
struct dmcu *dmcu = dc->res_pool->dmcu;
struct dmub_psr *psr = dc->res_pool->psr;
if (psr != NULL && link->psr_settings.psr_feature_enabled)
- psr->funcs->psr_get_state(psr, psr_state);
+ psr->funcs->psr_get_state(psr, state);
else if (dmcu != NULL && link->psr_settings.psr_feature_enabled)
- dmcu->funcs->get_psr_state(dmcu, psr_state);
+ dmcu->funcs->get_psr_state(dmcu, state);
return true;
}
@@ -2751,6 +2765,7 @@ bool dc_link_setup_psr(struct dc_link *link,
* (Always set for DAL2, did not check ASIC)
*/
psr_context->allow_smu_optimizations = psr_config->allow_smu_optimizations;
+ psr_context->allow_multi_disp_optimizations = psr_config->allow_multi_disp_optimizations;
/* Complete PSR entry before aborting to prevent intermittent
* freezes on certain eDPs
@@ -2777,6 +2792,18 @@ bool dc_link_setup_psr(struct dc_link *link,
}
+void dc_link_get_psr_residency(const struct dc_link *link, uint32_t *residency)
+{
+ struct dc *dc = link->ctx->dc;
+ struct dmub_psr *psr = dc->res_pool->psr;
+
+ // PSR residency measurements only supported on DMCUB
+ if (psr != NULL && link->psr_settings.psr_feature_enabled)
+ psr->funcs->psr_get_residency(psr, residency);
+ else
+ *residency = 0;
+}
+
const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
{
return &link->link_status;
@@ -2800,15 +2827,12 @@ static struct fixed31_32 get_pbn_per_slot(struct dc_stream_state *stream)
return dc_fixpt_div_int(mbytes_per_sec, 54);
}
-static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
+static struct fixed31_32 get_pbn_from_bw_in_kbps(uint64_t kbps)
{
- uint64_t kbps;
struct fixed31_32 peak_kbps;
uint32_t numerator;
uint32_t denominator;
- kbps = dc_bandwidth_in_kbps_from_timing(&pipe_ctx->stream->timing);
-
/*
* margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
* The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
@@ -2828,6 +2852,14 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
return peak_kbps;
}
+static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
+{
+ uint64_t kbps;
+
+ kbps = dc_bandwidth_in_kbps_from_timing(&pipe_ctx->stream->timing);
+ return get_pbn_from_bw_in_kbps(kbps);
+}
+
static void update_mst_stream_alloc_table(
struct dc_link *link,
struct stream_encoder *stream_enc,
@@ -2855,6 +2887,7 @@ static void update_mst_stream_alloc_table(
proposed_table->stream_allocations[i].vcp_id) {
work_table[i] = *dc_alloc;
+ work_table[i].slot_count = proposed_table->stream_allocations[i].slot_count;
break; /* exit j loop */
}
}
@@ -3234,7 +3267,8 @@ void core_link_enable_stream(
}
}
- dc->hwss.enable_audio_stream(pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
+#endif
/* turn off otg test pattern if enable */
if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
@@ -3274,6 +3308,9 @@ void core_link_enable_stream(
#if defined(CONFIG_DRM_AMD_DC_HDCP)
update_psp_stream_config(pipe_ctx, false);
#endif
+
+ dc->hwss.enable_audio_stream(pipe_ctx);
+
} else { // if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
dc_is_virtual_signal(pipe_ctx->stream->signal))
@@ -3301,6 +3338,8 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
core_link_set_avmute(pipe_ctx, true);
}
+ dc->hwss.disable_audio_stream(pipe_ctx);
+
#if defined(CONFIG_DRM_AMD_DC_HDCP)
update_psp_stream_config(pipe_ctx, true);
#endif
@@ -3408,10 +3447,13 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
{
uint32_t bits_per_channel = 0;
uint32_t kbps;
+ struct fixed31_32 link_bw_kbps;
if (timing->flags.DSC) {
- kbps = (timing->pix_clk_100hz * timing->dsc_cfg.bits_per_pixel);
- kbps = kbps / 160 + ((kbps % 160) ? 1 : 0);
+ link_bw_kbps = dc_fixpt_from_int(timing->pix_clk_100hz);
+ link_bw_kbps = dc_fixpt_div_int(link_bw_kbps, 160);
+ link_bw_kbps = dc_fixpt_mul_int(link_bw_kbps, timing->dsc_cfg.bits_per_pixel);
+ kbps = dc_fixpt_ceil(link_bw_kbps);
return kbps;
}
@@ -3435,11 +3477,11 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
bits_per_channel = 16;
break;
default:
+ ASSERT(bits_per_channel != 0);
+ bits_per_channel = 8;
break;
}
- ASSERT(bits_per_channel != 0);
-
kbps = timing->pix_clk_100hz / 10;
kbps *= bits_per_channel;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
index 54beda4d4e85..c5936e064360 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
@@ -37,6 +37,10 @@
#include "dc_link_ddc.h"
#include "dce/dce_aux.h"
+/*DP to Dual link DVI converter*/
+static const uint8_t DP_DVI_CONVERTER_ID_4[] = "m2DVIa";
+static const uint8_t DP_DVI_CONVERTER_ID_5[] = "3393N2";
+
#define AUX_POWER_UP_WA_DELAY 500
#define I2C_OVER_AUX_DEFER_WA_DELAY 70
#define I2C_OVER_AUX_DEFER_WA_DELAY_1MS 1
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 8a7c4de49a4b..6b11d4af54af 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -15,6 +15,11 @@
#include "dc_dmub_srv.h"
#include "dce/dmub_hw_lock_mgr.h"
+/*Travis*/
+static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT";
+/*Nutmeg*/
+static const uint8_t DP_VGA_LVDS_CONVERTER_ID_3[] = "dnomlA";
+
#define DC_LOGGER \
link->ctx->logger
#define DC_TRACE_LEVEL_MESSAGE(...) /* do nothing */
@@ -1405,15 +1410,24 @@ static void print_status_message(
case LINK_RATE_LOW:
link_rate = "RBR";
break;
+ case LINK_RATE_RATE_2:
+ link_rate = "R2";
+ break;
+ case LINK_RATE_RATE_3:
+ link_rate = "R3";
+ break;
case LINK_RATE_HIGH:
link_rate = "HBR";
break;
- case LINK_RATE_HIGH2:
- link_rate = "HBR2";
- break;
case LINK_RATE_RBR2:
link_rate = "RBR2";
break;
+ case LINK_RATE_RATE_6:
+ link_rate = "R6";
+ break;
+ case LINK_RATE_HIGH2:
+ link_rate = "HBR2";
+ break;
case LINK_RATE_HIGH3:
link_rate = "HBR3";
break;
@@ -1860,7 +1874,7 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link)
return max_link_cap;
}
-static enum dc_status read_hpd_rx_irq_data(
+enum dc_status read_hpd_rx_irq_data(
struct dc_link *link,
union hpd_irq_data *irq_data)
{
@@ -2565,7 +2579,8 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link)
psr_sink_psr_status.raw = dpcdbuf[2];
if (psr_error_status.bits.LINK_CRC_ERROR ||
- psr_error_status.bits.RFB_STORAGE_ERROR) {
+ psr_error_status.bits.RFB_STORAGE_ERROR ||
+ psr_error_status.bits.VSC_SDP_ERROR) {
/* Acknowledge and clear error bits */
dm_helpers_dp_write_dpcd(
link->ctx,
@@ -2575,8 +2590,8 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link)
sizeof(psr_error_status.raw));
/* PSR error, disable and re-enable PSR */
- dc_link_set_psr_allow_active(link, false, true);
- dc_link_set_psr_allow_active(link, true, true);
+ dc_link_set_psr_allow_active(link, false, true, false);
+ dc_link_set_psr_allow_active(link, true, true, false);
return true;
} else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
@@ -3740,6 +3755,7 @@ void detect_edp_sink_caps(struct dc_link *link)
uint32_t entry;
uint32_t link_rate_in_khz;
enum dc_link_rate link_rate = LINK_RATE_UNKNOWN;
+ uint8_t backlight_adj_cap;
retrieve_link_cap(link);
link->dpcd_caps.edp_supported_link_rates_count = 0;
@@ -3770,6 +3786,12 @@ void detect_edp_sink_caps(struct dc_link *link)
}
link->verified_link_cap = link->reported_link_cap;
+ core_link_read_dpcd(link, DP_EDP_BACKLIGHT_ADJUSTMENT_CAP,
+ &backlight_adj_cap, sizeof(backlight_adj_cap));
+
+ link->dpcd_caps.dynamic_backlight_capable_edp =
+ (backlight_adj_cap & DP_EDP_DYNAMIC_BACKLIGHT_CAP) ? true:false;
+
dc_link_set_default_brightness_aux(link);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 65aabf25cdec..b8f1e2d33423 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -42,7 +42,7 @@
#include "inc/hw/dmcu.h"
#include "dml/display_mode_lib.h"
-#define DC_VER "3.2.110"
+#define DC_VER "3.2.115"
#define MAX_SURFACES 3
#define MAX_PLANES 6
@@ -125,6 +125,7 @@ struct dpp_color_caps {
uint16_t hw_3d_lut : 1;
uint16_t ogam_ram : 1; // blnd gam
uint16_t ocsc : 1;
+ uint16_t dgam_rom_for_yuv : 1;
struct rom_curve_caps dgam_rom_caps;
struct rom_curve_caps ogam_rom_caps;
};
@@ -168,6 +169,7 @@ struct dc_caps {
bool psp_setup_panel_mode;
bool extended_aux_timeout_support;
bool dmcub_support;
+ uint32_t num_of_internal_disp;
enum dp_protocol_version max_dp_protocol_version;
struct dc_plane_cap planes[MAX_PLANES];
struct dc_color_caps color;
@@ -341,7 +343,9 @@ enum dcn_pwr_state {
*/
struct dc_clocks {
int dispclk_khz;
+ int actual_dispclk_khz;
int dppclk_khz;
+ int actual_dppclk_khz;
int disp_dpp_voltage_level_khz;
int dcfclk_khz;
int socclk_khz;
@@ -416,6 +420,10 @@ struct dc_bw_validation_profile {
union mem_low_power_enable_options {
struct {
+ bool i2c: 1;
+ bool dmcu: 1;
+ bool dscl: 1;
+ bool cm: 1;
bool mpc: 1;
bool optc: 1;
} bits;
@@ -479,7 +487,7 @@ struct dc_debug_options {
bool scl_reset_length10;
bool hdmi20_disable;
bool skip_detection_link_training;
- bool edid_read_retry_times;
+ uint32_t edid_read_retry_times;
bool remove_disconnect_edp;
unsigned int force_odm_combine; //bit vector based on otg inst
#if defined(CONFIG_DRM_AMD_DC_DCN)
@@ -1088,6 +1096,7 @@ struct dpcd_caps {
bool panel_mode_edp;
bool dpcd_display_control_capable;
bool ext_receiver_cap_field_present;
+ bool dynamic_backlight_capable_edp;
union dpcd_fec_capability fec_cap;
struct dpcd_dsc_capabilities dsc_caps;
struct dc_lttpr_caps lttpr_caps;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
index e146e3cba8eb..509d23fdd3c9 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
@@ -144,6 +144,11 @@ struct dc_vbios_funcs {
enum bp_result (*get_soc_bb_info)(
struct dc_bios *dcb,
struct bp_soc_bb_info *soc_bb_info);
+
+ enum bp_result (*get_disp_connector_caps_info)(
+ struct dc_bios *dcb,
+ struct graphics_object_id object_id,
+ struct bp_disp_connector_caps_info *info);
};
struct bios_registers {
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index 266b93a705d5..6d9a60c9dcc0 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -101,6 +101,7 @@ struct dc_link {
bool aux_access_disabled;
bool sync_lt_in_progress;
bool lttpr_non_transparent_mode;
+ bool is_internal_display;
/* caps is the same as reported_link_cap. link_traing use
* reported_link_cap. Will clean up. TODO
@@ -219,14 +220,17 @@ int dc_link_get_backlight_level(const struct dc_link *dc_link);
int dc_link_get_target_backlight_pwm(const struct dc_link *link);
-bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable, bool wait);
+bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable,
+ bool wait, bool force_static);
-bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state);
+bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state);
bool dc_link_setup_psr(struct dc_link *dc_link,
const struct dc_stream_state *stream, struct psr_config *psr_config,
struct psr_context *psr_context);
+void dc_link_get_psr_residency(const struct dc_link *link, uint32_t *residency);
+
/* Request DC to detect if there is a Panel connected.
* boot - If this call is during initial boot.
* Return false for any type of detection failure or MST detection
@@ -255,6 +259,10 @@ enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link);
bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link,
union hpd_irq_data *hpd_irq_dpcd_data, bool *out_link_loss);
+enum dc_status read_hpd_rx_irq_data(
+ struct dc_link *link,
+ union hpd_irq_data *irq_data);
+
struct dc_sink_init_data;
struct dc_sink *dc_link_add_remote_sink(
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index bf090afc2f70..b7910976b81a 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -292,6 +292,7 @@ void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream);
uint8_t dc_get_current_stream_count(struct dc *dc);
struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i);
+struct dc_stream_state *dc_stream_find_from_link(const struct dc_link *link);
/*
* Return the current frame counter.
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 53c29d811493..80757a0ea7c6 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -671,6 +671,25 @@ struct dc_plane_flip_time {
unsigned int prev_update_time_in_us;
};
+enum dc_psr_state {
+ PSR_STATE0 = 0x0,
+ PSR_STATE1,
+ PSR_STATE1a,
+ PSR_STATE2,
+ PSR_STATE2a,
+ PSR_STATE3,
+ PSR_STATE3Init,
+ PSR_STATE4,
+ PSR_STATE4a,
+ PSR_STATE4b,
+ PSR_STATE4c,
+ PSR_STATE4d,
+ PSR_STATE5,
+ PSR_STATE5a,
+ PSR_STATE5b,
+ PSR_STATE5c
+};
+
struct psr_config {
unsigned char psr_version;
unsigned int psr_rfb_setup_time;
@@ -678,6 +697,7 @@ struct psr_config {
bool psr_frame_capture_indication_req;
unsigned int psr_sdp_transmit_line_num_deadline;
bool allow_smu_optimizations;
+ bool allow_multi_disp_optimizations;
};
union dmcu_psr_level {
@@ -780,6 +800,7 @@ struct psr_context {
*/
unsigned int frame_delay;
bool allow_smu_optimizations;
+ bool allow_multi_disp_optimizations;
};
struct colorspace_transform {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
index f0cebe721bcc..f3ed8b619caf 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
@@ -99,7 +99,7 @@ bool dce_dmcu_load_iram(struct dmcu *dmcu,
return true;
}
-static void dce_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
+static void dce_get_dmcu_psr_state(struct dmcu *dmcu, enum dc_psr_state *state)
{
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
@@ -114,7 +114,7 @@ static void dce_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
REG_WRITE(DMCU_IRAM_RD_CTRL, psr_state_offset);
/* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
- *psr_state = REG_READ(DMCU_IRAM_RD_DATA);
+ *state = (enum dc_psr_state)REG_READ(DMCU_IRAM_RD_DATA);
/* Disable write access to IRAM after finished using IRAM
* in order to allow dynamic sleep state
@@ -129,7 +129,7 @@ static void dce_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
unsigned int dmcu_wait_reg_ready_interval = 100;
unsigned int retryCount;
- uint32_t psr_state = 0;
+ enum dc_psr_state state = PSR_STATE0;
/* waitDMCUReadyForCmd */
REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
@@ -148,12 +148,12 @@ static void dce_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
if (wait == true) {
for (retryCount = 0; retryCount <= 100; retryCount++) {
- dce_get_dmcu_psr_state(dmcu, &psr_state);
+ dce_get_dmcu_psr_state(dmcu, &state);
if (enable) {
- if (psr_state != 0)
+ if (state != PSR_STATE0)
break;
} else {
- if (psr_state == 0)
+ if (state == PSR_STATE0)
break;
}
udelay(10);
@@ -513,7 +513,7 @@ static bool dcn10_dmcu_load_iram(struct dmcu *dmcu,
return true;
}
-static void dcn10_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
+static void dcn10_get_dmcu_psr_state(struct dmcu *dmcu, enum dc_psr_state *state)
{
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
@@ -532,7 +532,7 @@ static void dcn10_get_dmcu_psr_state(struct dmcu *dmcu, uint32_t *psr_state)
REG_WRITE(DMCU_IRAM_RD_CTRL, psr_state_offset);
/* Read data from IRAM_RD_DATA in DMCU_IRAM_RD_DATA*/
- *psr_state = REG_READ(DMCU_IRAM_RD_DATA);
+ *state = (enum dc_psr_state)REG_READ(DMCU_IRAM_RD_DATA);
/* Disable write access to IRAM after finished using IRAM
* in order to allow dynamic sleep state
@@ -547,7 +547,7 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
unsigned int dmcu_wait_reg_ready_interval = 100;
unsigned int retryCount;
- uint32_t psr_state = 0;
+ enum dc_psr_state state = PSR_STATE0;
/* If microcontroller is not running, do nothing */
if (dmcu->dmcu_state != DMCU_RUNNING)
@@ -575,12 +575,12 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
*/
if (wait == true) {
for (retryCount = 0; retryCount <= 1000; retryCount++) {
- dcn10_get_dmcu_psr_state(dmcu, &psr_state);
+ dcn10_get_dmcu_psr_state(dmcu, &state);
if (enable) {
- if (psr_state != 0)
+ if (state != PSR_STATE0)
break;
} else {
- if (psr_state == 0)
+ if (state == PSR_STATE0)
break;
}
udelay(500);
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
index ad0ae1f7b513..fe31abfa6c85 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
@@ -597,6 +597,7 @@ struct dce_hwseq_registers {
uint32_t AZALIA_CONTROLLER_CLOCK_GATING;
uint32_t HPO_TOP_CLOCK_CONTROL;
uint32_t ODM_MEM_PWR_CTRL3;
+ uint32_t DMU_MEM_PWR_CNTL;
};
/* set field name */
#define HWS_SF(blk_name, reg_name, field_name, post_fix)\
@@ -836,7 +837,8 @@ struct dce_hwseq_registers {
HWSEQ_DCN2_MASK_SH_LIST(mask_sh), \
HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \
HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
- HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh)
+ HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
+ HWS_SF(, DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, mask_sh)
#define HWSEQ_DCN301_MASK_SH_LIST(mask_sh)\
HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
@@ -1046,7 +1048,8 @@ struct dce_hwseq_registers {
type D4VGA_MODE_ENABLE; \
type AZALIA_AUDIO_DTO_MODULE; \
type ODM_MEM_UNASSIGNED_PWR_MODE; \
- type ODM_MEM_VBLANK_PWR_MODE;
+ type ODM_MEM_VBLANK_PWR_MODE; \
+ type DMCU_ERAM_MEM_PWR_FORCE;
#define HWSEQ_DCN3_REG_FIELD_LIST(type) \
type HPO_HDMISTREAMCLK_GATE_DIS;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c
index 3e34afe8c504..7fbd92fbc63a 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c
@@ -293,6 +293,14 @@ static bool setup_engine(
{
uint32_t i2c_setup_limit = I2C_SETUP_TIME_LIMIT_DCE;
uint32_t reset_length = 0;
+
+ if (dce_i2c_hw->ctx->dc->debug.enable_mem_low_power.bits.i2c) {
+ if (dce_i2c_hw->regs->DIO_MEM_PWR_CTRL) {
+ REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 0);
+ REG_WAIT(DIO_MEM_PWR_STATUS, I2C_MEM_PWR_STATE, 0, 0, 5);
+ }
+ }
+
/* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/
REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_USE_I2C_REG_REQ, 1);
@@ -369,6 +377,10 @@ static void release_engine(
REG_UPDATE_2(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, 1,
DC_I2C_SW_USE_I2C_REG_REQ, 0);
+ if (dce_i2c_hw->ctx->dc->debug.enable_mem_low_power.bits.i2c) {
+ if (dce_i2c_hw->regs->DIO_MEM_PWR_CTRL)
+ REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1);
+ }
}
struct dce_i2c_hw *acquire_i2c_hw_engine(
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h
index fb055e6883c0..2309f2bb162c 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h
@@ -95,6 +95,11 @@ enum {
SR(DC_I2C_DATA),\
SR(MICROSECOND_TIME_BASE_DIV)
+#define I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id)\
+ I2C_HW_ENGINE_COMMON_REG_LIST(id),\
+ SR(DIO_MEM_PWR_CTRL),\
+ SR(DIO_MEM_PWR_STATUS)
+
#define I2C_SF(reg_name, field_name, post_fix)\
.field_name = reg_name ## __ ## field_name ## post_fix
@@ -179,6 +184,8 @@ struct dce_i2c_shift {
uint8_t XTAL_REF_DIV;
uint8_t DC_I2C_DDC1_SEND_RESET_LENGTH;
uint8_t DC_I2C_REG_RW_CNTL_STATUS;
+ uint8_t I2C_LIGHT_SLEEP_FORCE;
+ uint8_t I2C_MEM_PWR_STATE;
};
struct dce_i2c_mask {
@@ -220,12 +227,19 @@ struct dce_i2c_mask {
uint32_t XTAL_REF_DIV;
uint32_t DC_I2C_DDC1_SEND_RESET_LENGTH;
uint32_t DC_I2C_REG_RW_CNTL_STATUS;
+ uint32_t I2C_LIGHT_SLEEP_FORCE;
+ uint32_t I2C_MEM_PWR_STATE;
};
#define I2C_COMMON_MASK_SH_LIST_DCN2(mask_sh)\
I2C_COMMON_MASK_SH_LIST_DCE110(mask_sh),\
I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_SEND_RESET_LENGTH, mask_sh)
+#define I2C_COMMON_MASK_SH_LIST_DCN30(mask_sh)\
+ I2C_COMMON_MASK_SH_LIST_DCN2(mask_sh),\
+ I2C_SF(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh),\
+ I2C_SF(DIO_MEM_PWR_STATUS, I2C_MEM_PWR_STATE, mask_sh)
+
struct dce_i2c_registers {
uint32_t SETUP;
uint32_t SPEED;
@@ -239,6 +253,8 @@ struct dce_i2c_registers {
uint32_t DC_I2C_TRANSACTION3;
uint32_t DC_I2C_DATA;
uint32_t MICROSECOND_TIME_BASE_DIV;
+ uint32_t DIO_MEM_PWR_CTRL;
+ uint32_t DIO_MEM_PWR_STATUS;
};
enum dce_i2c_transaction_address_space {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_panel_cntl.c b/drivers/gpu/drm/amd/display/dc/dce/dce_panel_cntl.c
index 74f7619d4154..761fdfc1f5bd 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_panel_cntl.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_panel_cntl.c
@@ -108,25 +108,17 @@ static uint32_t dce_panel_cntl_hw_init(struct panel_cntl *panel_cntl)
*/
REG_GET(BL_PWM_CNTL, BL_ACTIVE_INT_FRAC_CNT, &value);
- if (value == 0 || value == 1) {
- if (panel_cntl->stored_backlight_registers.BL_PWM_CNTL != 0) {
- REG_WRITE(BL_PWM_CNTL,
- panel_cntl->stored_backlight_registers.BL_PWM_CNTL);
- REG_WRITE(BL_PWM_CNTL2,
- panel_cntl->stored_backlight_registers.BL_PWM_CNTL2);
- REG_WRITE(BL_PWM_PERIOD_CNTL,
- panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL);
- REG_UPDATE(PWRSEQ_REF_DIV,
- BL_PWM_REF_DIV,
- panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
- } else {
- /* TODO: Note: This should not really happen since VBIOS
- * should have initialized PWM registers on boot.
- */
- REG_WRITE(BL_PWM_CNTL, 0xC000FA00);
- REG_WRITE(BL_PWM_PERIOD_CNTL, 0x000C0FA0);
- }
- } else {
+ if (panel_cntl->stored_backlight_registers.BL_PWM_CNTL != 0) {
+ REG_WRITE(BL_PWM_CNTL,
+ panel_cntl->stored_backlight_registers.BL_PWM_CNTL);
+ REG_WRITE(BL_PWM_CNTL2,
+ panel_cntl->stored_backlight_registers.BL_PWM_CNTL2);
+ REG_WRITE(BL_PWM_PERIOD_CNTL,
+ panel_cntl->stored_backlight_registers.BL_PWM_PERIOD_CNTL);
+ REG_UPDATE(PWRSEQ_REF_DIV,
+ BL_PWM_REF_DIV,
+ panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
+ } else if ((value != 0) && (value != 1)) {
panel_cntl->stored_backlight_registers.BL_PWM_CNTL =
REG_READ(BL_PWM_CNTL);
panel_cntl->stored_backlight_registers.BL_PWM_CNTL2 =
@@ -136,6 +128,12 @@ static uint32_t dce_panel_cntl_hw_init(struct panel_cntl *panel_cntl)
REG_GET(PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
&panel_cntl->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
+ } else {
+ /* TODO: Note: This should not really happen since VBIOS
+ * should have initialized PWM registers on boot.
+ */
+ REG_WRITE(BL_PWM_CNTL, 0x8000FA00);
+ REG_WRITE(BL_PWM_PERIOD_CNTL, 0x000C0FA0);
}
// Have driver take backlight control
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
index 5054bb567b74..ada57f745fd7 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
@@ -1062,88 +1062,6 @@ static void dce110_reset_hdmi_stream_attribute(
#include "include/audio_types.h"
-/**
-* speakersToChannels
-*
-* @brief
-* translate speakers to channels
-*
-* FL - Front Left
-* FR - Front Right
-* RL - Rear Left
-* RR - Rear Right
-* RC - Rear Center
-* FC - Front Center
-* FLC - Front Left Center
-* FRC - Front Right Center
-* RLC - Rear Left Center
-* RRC - Rear Right Center
-* LFE - Low Freq Effect
-*
-* FC
-* FLC FRC
-* FL FR
-*
-* LFE
-* ()
-*
-*
-* RL RR
-* RLC RRC
-* RC
-*
-* ch 8 7 6 5 4 3 2 1
-* 0b00000011 - - - - - - FR FL
-* 0b00000111 - - - - - LFE FR FL
-* 0b00001011 - - - - FC - FR FL
-* 0b00001111 - - - - FC LFE FR FL
-* 0b00010011 - - - RC - - FR FL
-* 0b00010111 - - - RC - LFE FR FL
-* 0b00011011 - - - RC FC - FR FL
-* 0b00011111 - - - RC FC LFE FR FL
-* 0b00110011 - - RR RL - - FR FL
-* 0b00110111 - - RR RL - LFE FR FL
-* 0b00111011 - - RR RL FC - FR FL
-* 0b00111111 - - RR RL FC LFE FR FL
-* 0b01110011 - RC RR RL - - FR FL
-* 0b01110111 - RC RR RL - LFE FR FL
-* 0b01111011 - RC RR RL FC - FR FL
-* 0b01111111 - RC RR RL FC LFE FR FL
-* 0b11110011 RRC RLC RR RL - - FR FL
-* 0b11110111 RRC RLC RR RL - LFE FR FL
-* 0b11111011 RRC RLC RR RL FC - FR FL
-* 0b11111111 RRC RLC RR RL FC LFE FR FL
-* 0b11000011 FRC FLC - - - - FR FL
-* 0b11000111 FRC FLC - - - LFE FR FL
-* 0b11001011 FRC FLC - - FC - FR FL
-* 0b11001111 FRC FLC - - FC LFE FR FL
-* 0b11010011 FRC FLC - RC - - FR FL
-* 0b11010111 FRC FLC - RC - LFE FR FL
-* 0b11011011 FRC FLC - RC FC - FR FL
-* 0b11011111 FRC FLC - RC FC LFE FR FL
-* 0b11110011 FRC FLC RR RL - - FR FL
-* 0b11110111 FRC FLC RR RL - LFE FR FL
-* 0b11111011 FRC FLC RR RL FC - FR FL
-* 0b11111111 FRC FLC RR RL FC LFE FR FL
-*
-* @param
-* speakers - speaker information as it comes from CEA audio block
-*/
-/* translate speakers to channels */
-
-union audio_cea_channels {
- uint8_t all;
- struct audio_cea_channels_bits {
- uint32_t FL:1;
- uint32_t FR:1;
- uint32_t LFE:1;
- uint32_t FC:1;
- uint32_t RL_RC:1;
- uint32_t RR:1;
- uint32_t RC_RLC_FLC:1;
- uint32_t RRC_FRC:1;
- } channels;
-};
/* 25.2MHz/1.001*/
/* 25.2MHz/1.001*/
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 67af67ef2865..17e84f34ceba 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
@@ -34,55 +34,60 @@
/**
* Convert dmcub psr state to dmcu psr state.
*/
-static void convert_psr_state(uint32_t *psr_state)
+static enum dc_psr_state convert_psr_state(uint32_t raw_state)
{
- if (*psr_state == 0)
- *psr_state = 0;
- else if (*psr_state == 0x10)
- *psr_state = 1;
- else if (*psr_state == 0x11)
- *psr_state = 2;
- else if (*psr_state == 0x20)
- *psr_state = 3;
- else if (*psr_state == 0x21)
- *psr_state = 4;
- else if (*psr_state == 0x30)
- *psr_state = 5;
- else if (*psr_state == 0x31)
- *psr_state = 6;
- else if (*psr_state == 0x40)
- *psr_state = 7;
- else if (*psr_state == 0x41)
- *psr_state = 8;
- else if (*psr_state == 0x42)
- *psr_state = 9;
- else if (*psr_state == 0x43)
- *psr_state = 10;
- else if (*psr_state == 0x44)
- *psr_state = 11;
- else if (*psr_state == 0x50)
- *psr_state = 12;
- else if (*psr_state == 0x51)
- *psr_state = 13;
- else if (*psr_state == 0x52)
- *psr_state = 14;
- else if (*psr_state == 0x53)
- *psr_state = 15;
+ enum dc_psr_state state = PSR_STATE0;
+
+ if (raw_state == 0)
+ state = PSR_STATE0;
+ else if (raw_state == 0x10)
+ state = PSR_STATE1;
+ else if (raw_state == 0x11)
+ state = PSR_STATE1a;
+ else if (raw_state == 0x20)
+ state = PSR_STATE2;
+ else if (raw_state == 0x21)
+ state = PSR_STATE2a;
+ else if (raw_state == 0x30)
+ state = PSR_STATE3;
+ else if (raw_state == 0x31)
+ state = PSR_STATE3Init;
+ else if (raw_state == 0x40)
+ state = PSR_STATE4;
+ else if (raw_state == 0x41)
+ state = PSR_STATE4a;
+ else if (raw_state == 0x42)
+ state = PSR_STATE4b;
+ else if (raw_state == 0x43)
+ state = PSR_STATE4c;
+ else if (raw_state == 0x44)
+ state = PSR_STATE4d;
+ else if (raw_state == 0x50)
+ state = PSR_STATE5;
+ else if (raw_state == 0x51)
+ state = PSR_STATE5a;
+ else if (raw_state == 0x52)
+ state = PSR_STATE5b;
+ else if (raw_state == 0x53)
+ state = PSR_STATE5c;
+
+ return state;
}
/**
* Get PSR state from firmware.
*/
-static void dmub_psr_get_state(struct dmub_psr *dmub, uint32_t *psr_state)
+static void dmub_psr_get_state(struct dmub_psr *dmub, enum dc_psr_state *state)
{
struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;
+ uint32_t raw_state;
// Send gpint command and wait for ack
dmub_srv_send_gpint_command(srv, DMUB_GPINT__GET_PSR_STATE, 0, 30);
- dmub_srv_get_gpint_response(srv, psr_state);
+ dmub_srv_get_gpint_response(srv, &raw_state);
- convert_psr_state(psr_state);
+ *state = convert_psr_state(raw_state);
}
/**
@@ -123,7 +128,9 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait)
{
union dmub_rb_cmd cmd;
struct dc_context *dc = dmub->ctx;
- uint32_t retry_count, psr_state = 0;
+ uint32_t retry_count;
+ enum dc_psr_state state = PSR_STATE0;
+
cmd.psr_enable.header.type = DMUB_CMD__PSR;
@@ -144,13 +151,13 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait)
*/
if (wait) {
for (retry_count = 0; retry_count <= 1000; retry_count++) {
- dmub_psr_get_state(dmub, &psr_state);
+ dmub_psr_get_state(dmub, &state);
if (enable) {
- if (psr_state != 0)
+ if (state != PSR_STATE0)
break;
} else {
- if (psr_state == 0)
+ if (state == PSR_STATE0)
break;
}
@@ -169,12 +176,12 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait)
static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level)
{
union dmub_rb_cmd cmd;
- uint32_t psr_state = 0;
+ enum dc_psr_state state = PSR_STATE0;
struct dc_context *dc = dmub->ctx;
- dmub_psr_get_state(dmub, &psr_state);
+ dmub_psr_get_state(dmub, &state);
- if (psr_state == 0)
+ if (state == PSR_STATE0)
return;
cmd.psr_set_level.header.type = DMUB_CMD__PSR;
@@ -254,6 +261,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
// Misc
copy_settings_data->psr_level = psr_context->psr_level.u32all;
copy_settings_data->smu_optimizations_en = psr_context->allow_smu_optimizations;
+ copy_settings_data->multi_disp_optimizations_en = psr_context->allow_multi_disp_optimizations;
copy_settings_data->frame_delay = psr_context->frame_delay;
copy_settings_data->frame_cap_ind = psr_context->psrFrameCaptureIndicationReq;
copy_settings_data->init_sdp_deadline = psr_context->sdpTransmitLineNumDeadline;
@@ -269,11 +277,43 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
return true;
}
+/**
+ * Send command to PSR to force static ENTER and ignore all state changes until exit
+ */
+static void dmub_psr_force_static(struct dmub_psr *dmub)
+{
+ union dmub_rb_cmd cmd;
+ struct dc_context *dc = dmub->ctx;
+
+ cmd.psr_force_static.header.type = DMUB_CMD__PSR;
+ cmd.psr_force_static.header.sub_type = DMUB_CMD__PSR_FORCE_STATIC;
+ cmd.psr_enable.header.payload_bytes = 0;
+
+ dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
+ dc_dmub_srv_cmd_execute(dc->dmub_srv);
+ dc_dmub_srv_wait_idle(dc->dmub_srv);
+}
+
+/**
+ * Get PSR residency from firmware.
+ */
+static void dmub_psr_get_residency(struct dmub_psr *dmub, uint32_t *residency)
+{
+ struct dmub_srv *srv = dmub->ctx->dmub_srv->dmub;
+
+ // Send gpint command and wait for ack
+ dmub_srv_send_gpint_command(srv, DMUB_GPINT__PSR_RESIDENCY, 0, 30);
+
+ dmub_srv_get_gpint_response(srv, residency);
+}
+
static const struct dmub_psr_funcs psr_funcs = {
.psr_copy_settings = dmub_psr_copy_settings,
.psr_enable = dmub_psr_enable,
.psr_get_state = dmub_psr_get_state,
.psr_set_level = dmub_psr_set_level,
+ .psr_force_static = dmub_psr_force_static,
+ .psr_get_residency = dmub_psr_get_residency,
};
/**
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
index dc121ed92d2e..fe747c20a0d2 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
@@ -37,8 +37,10 @@ struct dmub_psr {
struct dmub_psr_funcs {
bool (*psr_copy_settings)(struct dmub_psr *dmub, struct dc_link *link, struct psr_context *psr_context);
void (*psr_enable)(struct dmub_psr *dmub, bool enable, bool wait);
- void (*psr_get_state)(struct dmub_psr *dmub, uint32_t *psr_state);
+ void (*psr_get_state)(struct dmub_psr *dmub, enum dc_psr_state *dc_psr_state);
void (*psr_set_level)(struct dmub_psr *dmub, uint16_t psr_level);
+ void (*psr_force_static)(struct dmub_psr *dmub);
+ void (*psr_get_residency)(struct dmub_psr *dmub, uint32_t *residency);
};
struct dmub_psr *dmub_psr_create(struct dc_context *ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 9f56887029ca..4c230f1de9a3 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -939,12 +939,15 @@ void dce110_edp_backlight_control(
return;
}
- if (enable && link->panel_cntl &&
- link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl)) {
- DC_LOG_HW_RESUME_S3(
- "%s: panel already powered up. Do nothing.\n",
+ if (link->panel_cntl) {
+ bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl);
+
+ if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) {
+ DC_LOG_HW_RESUME_S3(
+ "%s: panel already powered up/off. Do nothing.\n",
__func__);
- return;
+ return;
+ }
}
/* Send VBIOS command to control eDP panel backlight */
@@ -1527,6 +1530,8 @@ static void power_down_encoders(struct dc *dc)
dc->links[i]->link_enc, signal);
dc->links[i]->link_status.link_active = false;
+ memset(&dc->links[i]->cur_link_settings, 0,
+ sizeof(dc->links[i]->cur_link_settings));
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
index 2edf566b3a72..9a1f40eb5c47 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
@@ -51,6 +51,8 @@
SRI(CM_GAMUT_REMAP_C33_C34, CM, id),\
SRI(DSCL_EXT_OVERSCAN_LEFT_RIGHT, DSCL, id), \
SRI(DSCL_EXT_OVERSCAN_TOP_BOTTOM, DSCL, id), \
+ SRI(DSCL_MEM_PWR_STATUS, DSCL, id), \
+ SRI(DSCL_MEM_PWR_CTRL, DSCL, id), \
SRI(OTG_H_BLANK, DSCL, id), \
SRI(OTG_V_BLANK, DSCL, id), \
SRI(SCL_MODE, DSCL, id), \
@@ -252,6 +254,8 @@
TF_SF(DSCL0_SCL_VERT_FILTER_INIT_BOT_C, SCL_V_INIT_INT_BOT_C, mask_sh),\
TF_SF(DSCL0_SCL_MODE, SCL_CHROMA_COEF_MODE, mask_sh),\
TF_SF(DSCL0_SCL_MODE, SCL_COEF_RAM_SELECT_CURRENT, mask_sh), \
+ TF_SF(DSCL0_DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, mask_sh), \
+ TF_SF(DSCL0_DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, mask_sh), \
TF_SF(CM0_CM_ICSC_CONTROL, CM_ICSC_MODE, mask_sh), \
TF_SF(CM0_CM_ICSC_C11_C12, CM_ICSC_C11, mask_sh), \
TF_SF(CM0_CM_ICSC_C11_C12, CM_ICSC_C12, mask_sh), \
@@ -536,6 +540,8 @@
type SCL_V_INIT_INT_BOT_C; \
type SCL_CHROMA_COEF_MODE; \
type SCL_COEF_RAM_SELECT_CURRENT; \
+ type LUT_MEM_PWR_FORCE; \
+ type LUT_MEM_PWR_STATE; \
type CM_GAMUT_REMAP_MODE; \
type CM_GAMUT_REMAP_C11; \
type CM_GAMUT_REMAP_C12; \
@@ -1096,6 +1102,8 @@ struct dcn_dpp_mask {
uint32_t DSCL_EXT_OVERSCAN_TOP_BOTTOM; \
uint32_t OTG_H_BLANK; \
uint32_t OTG_V_BLANK; \
+ uint32_t DSCL_MEM_PWR_CTRL; \
+ uint32_t DSCL_MEM_PWR_STATUS; \
uint32_t SCL_MODE; \
uint32_t LB_DATA_FORMAT; \
uint32_t LB_MEMORY_CTRL; \
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
index 878b53d85694..efa86d5c6847 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
@@ -198,6 +198,20 @@ static enum dscl_mode_sel dpp1_dscl_get_dscl_mode(
return DSCL_MODE_SCALING_420_YCBCR_ENABLE;
}
+static void dpp1_power_on_dscl(
+ struct dpp *dpp_base,
+ bool power_on)
+{
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+
+ if (dpp->tf_regs->DSCL_MEM_PWR_CTRL) {
+ REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, power_on ? 0 : 3);
+ if (power_on)
+ REG_WAIT(DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, 0, 1, 5);
+ }
+}
+
+
static void dpp1_dscl_set_lb(
struct dcn10_dpp *dpp,
const struct line_buffer_params *lb_params,
@@ -678,6 +692,11 @@ void dpp1_dscl_set_scaler_manual_scale(
dpp->scl_data = *scl_data;
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.dscl) {
+ if (dscl_mode != DSCL_MODE_DSCL_BYPASS)
+ dpp1_power_on_dscl(dpp_base, true);
+ }
+
/* Autocal off */
REG_SET_3(DSCL_AUTOCAL, 0,
AUTOCAL_MODE, AUTOCAL_MODE_OFF,
@@ -697,8 +716,11 @@ void dpp1_dscl_set_scaler_manual_scale(
/* SCL mode */
REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode);
- if (dscl_mode == DSCL_MODE_DSCL_BYPASS)
+ if (dscl_mode == DSCL_MODE_DSCL_BYPASS) {
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.dscl)
+ dpp1_power_on_dscl(dpp_base, false);
return;
+ }
/* LB */
lb_config = dpp1_dscl_find_lb_memory_config(dpp, scl_data);
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 8eb88a50af51..9f7d6b087553 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
@@ -1442,16 +1442,13 @@ void dcn10_init_hw(struct dc *dc)
/* In headless boot cases, DIG may be turned
* on which causes HW/SW discrepancies.
* To avoid this, power down hardware on boot
- * if DIG is turned on and seamless boot not enabled
+ * if DIG is turned on
*/
void dcn10_power_down_on_boot(struct dc *dc)
{
int i = 0;
struct dc_link *edp_link;
- if (!dc->config.power_down_display_on_boot)
- return;
-
edp_link = get_edp_link(dc);
if (edp_link &&
edp_link->link_enc->funcs->is_dig_enabled &&
@@ -3279,6 +3276,8 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
};
bool pipe_split_on = (pipe_ctx->top_pipe != NULL) ||
(pipe_ctx->bottom_pipe != NULL);
+ bool odm_combine_on = (pipe_ctx->next_odm_pipe != NULL) ||
+ (pipe_ctx->prev_odm_pipe != NULL);
int x_plane = pipe_ctx->plane_state->dst_rect.x;
int y_plane = pipe_ctx->plane_state->dst_rect.y;
@@ -3362,16 +3361,56 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
uint32_t temp_y = pos_cpy.y;
int viewport_height =
pipe_ctx->plane_res.scl_data.viewport.height;
-
- if (pipe_split_on) {
+ int viewport_y =
+ pipe_ctx->plane_res.scl_data.viewport.y;
+
+ /**
+ * Display groups that are 1xnY, have pos_cpy.x > 2 * viewport.height
+ * For pipe split cases:
+ * - apply offset of viewport.y to normalize pos_cpy.x
+ * - calculate the pos_cpy.y as before
+ * - shift pos_cpy.y back by same offset to get final value
+ * - since we iterate through both pipes, use the lower
+ * viewport.y for offset
+ * For non pipe split cases, use the same calculation for
+ * pos_cpy.y as the 180 degree rotation case below,
+ * but use pos_cpy.x as our input because we are rotating
+ * 270 degrees
+ */
+ if (pipe_split_on || odm_combine_on) {
+ int pos_cpy_x_offset;
+ int other_pipe_viewport_y;
+
+ if (pipe_split_on) {
+ if (pipe_ctx->bottom_pipe) {
+ other_pipe_viewport_y =
+ pipe_ctx->bottom_pipe->plane_res.scl_data.viewport.y;
+ } else {
+ other_pipe_viewport_y =
+ pipe_ctx->top_pipe->plane_res.scl_data.viewport.y;
+ }
+ } else {
+ if (pipe_ctx->next_odm_pipe) {
+ other_pipe_viewport_y =
+ pipe_ctx->next_odm_pipe->plane_res.scl_data.viewport.y;
+ } else {
+ other_pipe_viewport_y =
+ pipe_ctx->prev_odm_pipe->plane_res.scl_data.viewport.y;
+ }
+ }
+ pos_cpy_x_offset = (viewport_y > other_pipe_viewport_y) ?
+ other_pipe_viewport_y : viewport_y;
+ pos_cpy.x -= pos_cpy_x_offset;
if (pos_cpy.x > viewport_height) {
pos_cpy.x = pos_cpy.x - viewport_height;
pos_cpy.y = viewport_height - pos_cpy.x;
} else {
pos_cpy.y = 2 * viewport_height - pos_cpy.x;
}
- } else
- pos_cpy.y = viewport_height - pos_cpy.x;
+ pos_cpy.y += pos_cpy_x_offset;
+ } else {
+ pos_cpy.y = (2 * viewport_y) + viewport_height - pos_cpy.x;
+ }
pos_cpy.x = temp_y;
}
// Mirror horizontally and vertically
@@ -3381,7 +3420,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
int viewport_x =
pipe_ctx->plane_res.scl_data.viewport.x;
- if (pipe_split_on) {
+ if (pipe_split_on || odm_combine_on) {
if (pos_cpy.x >= viewport_width + viewport_x) {
pos_cpy.x = 2 * viewport_width
- pos_cpy.x + 2 * viewport_x;
@@ -3399,7 +3438,17 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
} else {
pos_cpy.x = viewport_width - pos_cpy.x + 2 * viewport_x;
}
- pos_cpy.y = pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.y;
+
+ /**
+ * Display groups that are 1xnY, have pos_cpy.y > viewport.height
+ * Calculation:
+ * delta_from_bottom = viewport.y + viewport.height - pos_cpy.y
+ * pos_cpy.y_new = viewport.y + delta_from_bottom
+ * Simplify it as:
+ * pos_cpy.y = viewport.y * 2 + viewport.height - pos_cpy.y
+ */
+ pos_cpy.y = (2 * pipe_ctx->plane_res.scl_data.viewport.y) +
+ pipe_ctx->plane_res.scl_data.viewport.height - pos_cpy.y;
}
hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index e74bb2735885..bdc37831535e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -1439,6 +1439,7 @@ static bool dcn10_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 = 0;
dc->caps.color.dpp.ogam_ram = 1; // RGAM on DCN1
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
index f70fcadf1ee5..73ac78b16bd4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
@@ -1021,88 +1021,6 @@ void enc1_reset_hdmi_stream_attribute(
#include "include/audio_types.h"
-/**
-* speakersToChannels
-*
-* @brief
-* translate speakers to channels
-*
-* FL - Front Left
-* FR - Front Right
-* RL - Rear Left
-* RR - Rear Right
-* RC - Rear Center
-* FC - Front Center
-* FLC - Front Left Center
-* FRC - Front Right Center
-* RLC - Rear Left Center
-* RRC - Rear Right Center
-* LFE - Low Freq Effect
-*
-* FC
-* FLC FRC
-* FL FR
-*
-* LFE
-* ()
-*
-*
-* RL RR
-* RLC RRC
-* RC
-*
-* ch 8 7 6 5 4 3 2 1
-* 0b00000011 - - - - - - FR FL
-* 0b00000111 - - - - - LFE FR FL
-* 0b00001011 - - - - FC - FR FL
-* 0b00001111 - - - - FC LFE FR FL
-* 0b00010011 - - - RC - - FR FL
-* 0b00010111 - - - RC - LFE FR FL
-* 0b00011011 - - - RC FC - FR FL
-* 0b00011111 - - - RC FC LFE FR FL
-* 0b00110011 - - RR RL - - FR FL
-* 0b00110111 - - RR RL - LFE FR FL
-* 0b00111011 - - RR RL FC - FR FL
-* 0b00111111 - - RR RL FC LFE FR FL
-* 0b01110011 - RC RR RL - - FR FL
-* 0b01110111 - RC RR RL - LFE FR FL
-* 0b01111011 - RC RR RL FC - FR FL
-* 0b01111111 - RC RR RL FC LFE FR FL
-* 0b11110011 RRC RLC RR RL - - FR FL
-* 0b11110111 RRC RLC RR RL - LFE FR FL
-* 0b11111011 RRC RLC RR RL FC - FR FL
-* 0b11111111 RRC RLC RR RL FC LFE FR FL
-* 0b11000011 FRC FLC - - - - FR FL
-* 0b11000111 FRC FLC - - - LFE FR FL
-* 0b11001011 FRC FLC - - FC - FR FL
-* 0b11001111 FRC FLC - - FC LFE FR FL
-* 0b11010011 FRC FLC - RC - - FR FL
-* 0b11010111 FRC FLC - RC - LFE FR FL
-* 0b11011011 FRC FLC - RC FC - FR FL
-* 0b11011111 FRC FLC - RC FC LFE FR FL
-* 0b11110011 FRC FLC RR RL - - FR FL
-* 0b11110111 FRC FLC RR RL - LFE FR FL
-* 0b11111011 FRC FLC RR RL FC - FR FL
-* 0b11111111 FRC FLC RR RL FC LFE FR FL
-*
-* @param
-* speakers - speaker information as it comes from CEA audio block
-*/
-/* translate speakers to channels */
-
-union audio_cea_channels {
- uint8_t all;
- struct audio_cea_channels_bits {
- uint32_t FL:1;
- uint32_t FR:1;
- uint32_t LFE:1;
- uint32_t FC:1;
- uint32_t RL_RC:1;
- uint32_t RR:1;
- uint32_t RC_RLC_FLC:1;
- uint32_t RRC_FRC:1;
- } channels;
-};
/* 25.2MHz/1.001*/
/* 25.2MHz/1.001*/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h
index 27610251c57f..e735363d0051 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h
@@ -632,8 +632,7 @@
type CUR0_PIX_INV_MODE; \
type CUR0_PIXEL_ALPHA_MOD_EN; \
type CUR0_ROM_EN;\
- type OBUF_MEM_PWR_FORCE;\
- type LUT_MEM_PWR_FORCE
+ type OBUF_MEM_PWR_FORCE
struct dcn2_dpp_shift {
@@ -659,8 +658,7 @@ struct dcn2_dpp_mask {
uint32_t COLOR_KEYER_RED; \
uint32_t COLOR_KEYER_GREEN; \
uint32_t COLOR_KEYER_BLUE; \
- uint32_t OBUF_MEM_PWR_CTRL; \
- uint32_t DSCL_MEM_PWR_CTRL
+ uint32_t OBUF_MEM_PWR_CTRL
#define DPP_DCN2_REG_VARIABLE_LIST_CM_APPEND \
uint32_t CM_GAMUT_REMAP_B_C11_C12; \
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index d8d45d860cb7..abcb06044e6e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1163,29 +1163,32 @@ void dcn20_pipe_control_lock(
if (pipe->plane_state != NULL)
flip_immediate = pipe->plane_state->flip_immediate;
- temp_pipe = pipe->bottom_pipe;
- while (!flip_immediate && temp_pipe) {
- if (temp_pipe->plane_state != NULL)
- flip_immediate = temp_pipe->plane_state->flip_immediate;
- temp_pipe = temp_pipe->bottom_pipe;
+ if (pipe->stream_res.gsl_group > 0) {
+ temp_pipe = pipe->bottom_pipe;
+ while (!flip_immediate && temp_pipe) {
+ if (temp_pipe->plane_state != NULL)
+ flip_immediate = temp_pipe->plane_state->flip_immediate;
+ temp_pipe = temp_pipe->bottom_pipe;
+ }
}
if (flip_immediate && lock) {
const int TIMEOUT_FOR_FLIP_PENDING = 100000;
int i;
- for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) {
- if (!pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->plane_res.hubp))
- break;
- udelay(1);
- }
-
- if (pipe->bottom_pipe != NULL) {
- for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) {
- if (!pipe->bottom_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->bottom_pipe->plane_res.hubp))
- break;
- udelay(1);
+ temp_pipe = pipe;
+ while (temp_pipe) {
+ if (temp_pipe->plane_state && temp_pipe->plane_state->flip_immediate) {
+ for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) {
+ if (!temp_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(temp_pipe->plane_res.hubp))
+ break;
+ udelay(1);
+ }
+
+ /* no reason it should take this long for immediate flips */
+ ASSERT(i != TIMEOUT_FOR_FLIP_PENDING);
}
+ temp_pipe = temp_pipe->bottom_pipe;
}
}
@@ -1692,6 +1695,15 @@ void dcn20_program_front_end_for_ctx(
&& context->res_ctx.pipe_ctx[i].stream)
hws->funcs.blank_pixel_data(dc, &context->res_ctx.pipe_ctx[i], true);
+ /* wait for outstanding pending changes before adding or removing planes */
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable ||
+ context->res_ctx.pipe_ctx[i].update_flags.bits.enable) {
+ dc->hwss.wait_for_pending_cleared(dc, context);
+ break;
+ }
+ }
+
/* Disconnect mpcc */
for (i = 0; i < dc->res_pool->pipe_count; i++)
if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 3fcc31d75792..ff36db5edf6c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2012,7 +2012,10 @@ void dcn20_populate_dml_writeback_from_context(
}
int dcn20_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)
{
int pipe_cnt, i;
bool synchronized_vblank = true;
@@ -2050,6 +2053,7 @@ int dcn20_populate_dml_pipes_from_context(
v_total = timing->v_total;
front_porch = timing->v_front_porch;
+
/* todo:
pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = 0;
pipes[pipe_cnt].pipe.src.dcc = 0;
@@ -2827,7 +2831,8 @@ bool dcn20_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 };
@@ -2839,7 +2844,7 @@ bool dcn20_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;
@@ -2943,7 +2948,8 @@ static void dcn20_calculate_wm(
display_e2e_pipe_params_st *pipes,
int *out_pipe_cnt,
int *pipe_split_from,
- int vlevel)
+ int vlevel,
+ bool fast_validate)
{
int pipe_cnt, i, pipe_idx;
@@ -2988,10 +2994,10 @@ static void dcn20_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 = dcn20_populate_dml_pipes_from_context(dc,
- context, pipes);
+ context, pipes, fast_validate);
}
*out_pipe_cnt = pipe_cnt;
@@ -3136,7 +3142,7 @@ static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *co
BW_VAL_TRACE_COUNT();
- out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel);
+ out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel, fast_validate);
if (pipe_cnt == 0)
goto validate_out;
@@ -3151,7 +3157,7 @@ static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *co
goto validate_out;
}
- dcn20_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel);
+ dcn20_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();
@@ -3814,6 +3820,7 @@ static bool dcn20_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;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
index 64bce14fefa3..c8f3127bbcdf 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
@@ -50,7 +50,10 @@ unsigned int dcn20_calc_max_scaled_time(
enum mmhubbub_wbif_mode mode,
unsigned int urgent_watermark);
int dcn20_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);
struct pipe_ctx *dcn20_acquire_idle_pipe_for_layer(
struct dc_state *state,
const struct resource_pool *pool,
@@ -155,7 +158,8 @@ bool dcn20_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);
void dcn20_calculate_dlg_params(
struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile
index 51a2f3d4c194..1ee5fc03b7b3 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile
@@ -3,7 +3,7 @@
# Makefile for DCN21.
DCN21 = dcn21_init.o dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o \
- dcn21_hwseq.o dcn21_link_encoder.o
+ dcn21_hwseq.o dcn21_link_encoder.o dcn21_dccg.o
ifdef CONFIG_X86
CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -msse
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_dccg.c
new file mode 100644
index 000000000000..60cf3ff68cb0
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_dccg.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2018 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "reg_helper.h"
+#include "core_types.h"
+#include "dcn20/dcn20_dccg.h"
+#include "dcn21_dccg.h"
+
+#define TO_DCN_DCCG(dccg)\
+ container_of(dccg, struct dcn_dccg, base)
+
+#define REG(reg) \
+ (dccg_dcn->regs->reg)
+
+#undef FN
+#define FN(reg_name, field_name) \
+ dccg_dcn->dccg_shift->field_name, dccg_dcn->dccg_mask->field_name
+
+#define CTX \
+ dccg_dcn->base.ctx
+#define DC_LOGGER \
+ dccg->ctx->logger
+
+void dccg21_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (dccg->ref_dppclk) {
+ int ref_dppclk = dccg->ref_dppclk;
+ int modulo = ref_dppclk / 10000;
+ int phase;
+
+ if (req_dppclk) {
+ /*
+ * program DPP DTO phase and modulo as below
+ * phase = ceiling(dpp_pipe_clk_mhz / 10)
+ * module = trunc(dpp_global_clk_mhz / 10)
+ *
+ * storing frequencies in registers allow dmcub fw
+ * to run time lower clocks when possible for power saving
+ *
+ * ceiling phase and truncate modulo guarentees the divided
+ * down per pipe dpp clock has high enough frequency
+ */
+ phase = (req_dppclk + 9999) / 10000;
+
+ if (phase > modulo) {
+ /* phase > modulo result in screen corruption
+ * ie phase = 30, mod = 29 for 4k@60 HDMI
+ * in these case we don't want pipe clock to be divided
+ */
+ phase = modulo;
+ }
+ } else {
+ /*
+ * set phase to 10 if dpp isn't used to
+ * prevent hard hang if access dpp register
+ * on unused pipe
+ *
+ * DTO should be on to divide down un-used
+ * pipe clock for power saving
+ */
+ phase = 10;
+ }
+
+ REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
+ DPPCLK0_DTO_PHASE, phase,
+ DPPCLK0_DTO_MODULO, modulo);
+
+ REG_UPDATE(DPPCLK_DTO_CTRL,
+ DPPCLK_DTO_ENABLE[dpp_inst], 1);
+ }
+
+ dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
+}
+
+
+static const struct dccg_funcs dccg21_funcs = {
+ .update_dpp_dto = dccg21_update_dpp_dto,
+ .get_dccg_ref_freq = dccg2_get_dccg_ref_freq,
+ .dccg_init = dccg2_init
+};
+
+struct dccg *dccg21_create(
+ struct dc_context *ctx,
+ const struct dccg_registers *regs,
+ const struct dccg_shift *dccg_shift,
+ const struct dccg_mask *dccg_mask)
+{
+ struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
+ struct dccg *base;
+
+ if (dccg_dcn == NULL) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+
+ base = &dccg_dcn->base;
+ base->ctx = ctx;
+ base->funcs = &dccg21_funcs;
+
+ dccg_dcn->regs = regs;
+ dccg_dcn->dccg_shift = dccg_shift;
+ dccg_dcn->dccg_mask = dccg_mask;
+
+ return &dccg_dcn->base;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_dccg.h
new file mode 100644
index 000000000000..b7efa777ec73
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_dccg.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DCN21_DCCG_H__
+#define __DCN21_DCCG_H__
+
+struct dccg *dccg21_create(
+ struct dc_context *ctx,
+ const struct dccg_registers *regs,
+ const struct dccg_shift *dccg_shift,
+ const struct dccg_mask *dccg_mask);
+
+
+#endif /* __DCN21_DCCG_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c
index 129f0b62f751..42fbb5e6d505 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c
@@ -99,6 +99,8 @@ void dcn21_dchvm_init(struct hubbub *hubbub)
//Poll until HOSTVM_PREFETCH_DONE = 1
REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100);
+
+ hubbub->riommu_active = true;
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
index 1fa193078803..96ee0b82f458 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hwseq.c
@@ -171,9 +171,11 @@ void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
return;
}
- if (abm && panel_cntl)
+ if (abm && panel_cntl) {
dmub_abm_set_pipe(abm, otg_inst, SET_ABM_PIPE_IMMEDIATELY_DISABLE,
panel_cntl->inst);
+ panel_cntl->funcs->store_backlight_level(panel_cntl);
+ }
}
void dcn21_set_pipe(struct pipe_ctx *pipe_ctx)
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();
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c
index 2b08b1d72177..fa981cd04dd0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c
@@ -25,6 +25,7 @@
#include "dc_bios_types.h"
+#include "hw_shared.h"
#include "dcn30_afmt.h"
#include "reg_helper.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h
index 08b2d8a8170c..85d4619207e2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h
@@ -100,89 +100,6 @@ struct dcn30_afmt_mask {
};
-/**
-* speakersToChannels
-*
-* @brief
-* translate speakers to channels
-*
-* FL - Front Left
-* FR - Front Right
-* RL - Rear Left
-* RR - Rear Right
-* RC - Rear Center
-* FC - Front Center
-* FLC - Front Left Center
-* FRC - Front Right Center
-* RLC - Rear Left Center
-* RRC - Rear Right Center
-* LFE - Low Freq Effect
-*
-* FC
-* FLC FRC
-* FL FR
-*
-* LFE
-* ()
-*
-*
-* RL RR
-* RLC RRC
-* RC
-*
-* ch 8 7 6 5 4 3 2 1
-* 0b00000011 - - - - - - FR FL
-* 0b00000111 - - - - - LFE FR FL
-* 0b00001011 - - - - FC - FR FL
-* 0b00001111 - - - - FC LFE FR FL
-* 0b00010011 - - - RC - - FR FL
-* 0b00010111 - - - RC - LFE FR FL
-* 0b00011011 - - - RC FC - FR FL
-* 0b00011111 - - - RC FC LFE FR FL
-* 0b00110011 - - RR RL - - FR FL
-* 0b00110111 - - RR RL - LFE FR FL
-* 0b00111011 - - RR RL FC - FR FL
-* 0b00111111 - - RR RL FC LFE FR FL
-* 0b01110011 - RC RR RL - - FR FL
-* 0b01110111 - RC RR RL - LFE FR FL
-* 0b01111011 - RC RR RL FC - FR FL
-* 0b01111111 - RC RR RL FC LFE FR FL
-* 0b11110011 RRC RLC RR RL - - FR FL
-* 0b11110111 RRC RLC RR RL - LFE FR FL
-* 0b11111011 RRC RLC RR RL FC - FR FL
-* 0b11111111 RRC RLC RR RL FC LFE FR FL
-* 0b11000011 FRC FLC - - - - FR FL
-* 0b11000111 FRC FLC - - - LFE FR FL
-* 0b11001011 FRC FLC - - FC - FR FL
-* 0b11001111 FRC FLC - - FC LFE FR FL
-* 0b11010011 FRC FLC - RC - - FR FL
-* 0b11010111 FRC FLC - RC - LFE FR FL
-* 0b11011011 FRC FLC - RC FC - FR FL
-* 0b11011111 FRC FLC - RC FC LFE FR FL
-* 0b11110011 FRC FLC RR RL - - FR FL
-* 0b11110111 FRC FLC RR RL - LFE FR FL
-* 0b11111011 FRC FLC RR RL FC - FR FL
-* 0b11111111 FRC FLC RR RL FC LFE FR FL
-*
-* @param
-* speakers - speaker information as it comes from CEA audio block
-*/
-/* translate speakers to channels */
-
-union audio_cea_channels {
- uint8_t all;
- struct audio_cea_channels_bits {
- uint32_t FL:1;
- uint32_t FR:1;
- uint32_t LFE:1;
- uint32_t FC:1;
- uint32_t RL_RC:1;
- uint32_t RR:1;
- uint32_t RC_RLC_FLC:1;
- uint32_t RRC_FRC:1;
- } channels;
-};
-
struct afmt;
struct afmt_funcs {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
index 29231528f052..6e864b1a95c4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
@@ -500,9 +500,40 @@ static void dpp3_power_on_blnd_lut(
{
struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
- REG_SET(CM_MEM_PWR_CTRL, 0,
- BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
+ REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, power_on ? 0 : 3);
+ if (power_on)
+ REG_WAIT(CM_MEM_PWR_STATUS, BLNDGAM_MEM_PWR_STATE, 0, 1, 5);
+ } else {
+ REG_SET(CM_MEM_PWR_CTRL, 0,
+ BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0 : 1);
+ }
+}
+static void dpp3_power_on_hdr3dlut(
+ struct dpp *dpp_base,
+ bool power_on)
+{
+ struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
+
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
+ REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, power_on ? 0 : 3);
+ if (power_on)
+ REG_WAIT(CM_MEM_PWR_STATUS2, HDR3DLUT_MEM_PWR_STATE, 0, 1, 5);
+ }
+}
+
+static void dpp3_power_on_shaper(
+ struct dpp *dpp_base,
+ bool power_on)
+{
+ struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
+
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
+ REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, power_on ? 0 : 3);
+ if (power_on)
+ REG_WAIT(CM_MEM_PWR_STATUS2, SHAPER_MEM_PWR_STATE, 0, 1, 5);
+ }
}
static void dpp3_configure_blnd_lut(
@@ -675,6 +706,8 @@ bool dpp3_program_blnd_lut(
if (params == NULL) {
REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_MODE, 0);
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
+ dpp3_power_on_blnd_lut(dpp_base, false);
return false;
}
@@ -1088,8 +1121,14 @@ bool dpp3_program_shaper(
if (params == NULL) {
REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
+ dpp3_power_on_shaper(dpp_base, false);
return false;
}
+
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
+ dpp3_power_on_shaper(dpp_base, true);
+
current_mode = dpp3_get_shaper_current(dpp_base);
if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
@@ -1278,8 +1317,14 @@ bool dpp3_program_3dlut(
if (params == NULL) {
dpp3_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
+ dpp3_power_on_hdr3dlut(dpp_base, false);
return false;
}
+
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
+ dpp3_power_on_hdr3dlut(dpp_base, true);
+
mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
if (mode == LUT_BYPASS || mode == LUT_RAM_B)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h
index 81bf2ecc2831..3fa86cd090a0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h
@@ -161,6 +161,10 @@
TF_REG_LIST_DCN20_COMMON(id), \
SRI(CM_BLNDGAM_CONTROL, CM, id), \
SRI(CM_SHAPER_LUT_DATA, CM, id),\
+ SRI(CM_MEM_PWR_CTRL2, CM, id), \
+ SRI(CM_MEM_PWR_STATUS2, CM, id), \
+ SRI(DSCL_MEM_PWR_STATUS, DSCL, id), \
+ SRI(DSCL_MEM_PWR_CTRL, DSCL, id), \
SRI(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B, CM, id),\
SRI(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G, CM, id),\
SRI(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R, CM, id),\
@@ -340,9 +344,15 @@
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_PIXEL_ALPHA_MOD_EN, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ROM_EN, mask_sh),\
TF_SF(DSCL0_OBUF_MEM_PWR_CTRL, OBUF_MEM_PWR_FORCE, mask_sh),\
- TF_SF(DSCL0_DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, mask_sh)
+ TF_SF(DSCL0_DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, mask_sh),\
+ TF_SF(DSCL0_DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, mask_sh)
#define DPP_REG_LIST_SH_MASK_DCN30_UPDATED(mask_sh)\
+ TF_SF(CM0_CM_MEM_PWR_STATUS, BLNDGAM_MEM_PWR_STATE, mask_sh), \
+ TF_SF(CM0_CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, mask_sh),\
+ TF_SF(CM0_CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, mask_sh),\
+ TF_SF(CM0_CM_MEM_PWR_STATUS2, HDR3DLUT_MEM_PWR_STATE, mask_sh),\
+ TF_SF(CM0_CM_MEM_PWR_STATUS2, SHAPER_MEM_PWR_STATE, mask_sh),\
TF_SF(CM0_CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE, mask_sh), \
TF_SF(CM0_CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, mask_sh), \
TF_SF(CM0_CM_BLNDGAM_CONTROL, CM_BLNDGAM_SELECT_CURRENT, mask_sh), \
@@ -386,6 +396,8 @@
type CM_BIAS_CR_R;\
type GAMCOR_MEM_PWR_DIS; \
type GAMCOR_MEM_PWR_FORCE; \
+ type HDR3DLUT_MEM_PWR_FORCE; \
+ type SHAPER_MEM_PWR_FORCE; \
type PRE_DEGAM_MODE;\
type PRE_DEGAM_SELECT;\
type CNVC_ALPHA_PLANE_ENABLE; \
@@ -446,7 +458,10 @@
type CM_BLNDGAM_MODE_CURRENT; \
type CM_BLNDGAM_SELECT_CURRENT; \
type CM_BLNDGAM_SELECT; \
- type GAMCOR_MEM_PWR_STATE
+ type GAMCOR_MEM_PWR_STATE; \
+ type BLNDGAM_MEM_PWR_STATE; \
+ type HDR3DLUT_MEM_PWR_STATE; \
+ type SHAPER_MEM_PWR_STATE
struct dcn3_dpp_shift {
DPP_REG_FIELD_LIST_DCN3(uint8_t);
@@ -459,6 +474,8 @@ struct dcn3_dpp_mask {
#define DPP_DCN3_REG_VARIABLE_LIST_COMMON \
DPP_DCN2_REG_VARIABLE_LIST; \
uint32_t CM_MEM_PWR_STATUS;\
+ uint32_t CM_MEM_PWR_STATUS2;\
+ uint32_t CM_MEM_PWR_CTRL2;\
uint32_t CM_DEALPHA;\
uint32_t CM_BIAS_CR_R;\
uint32_t CM_BIAS_Y_G_CB_B;\
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c
index 9ab63c72f21c..9da66e491116 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c
@@ -136,9 +136,13 @@ static void dpp3_power_on_gamcor_lut(
uint32_t power_status;
struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
-
- REG_SET(CM_MEM_PWR_CTRL, 0,
- GAMCOR_MEM_PWR_DIS, power_on == true ? 0:1);
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
+ REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, power_on ? 0 : 3);
+ if (power_on)
+ REG_WAIT(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, 0, 1, 5);
+ } else
+ REG_SET(CM_MEM_PWR_CTRL, 0,
+ GAMCOR_MEM_PWR_DIS, power_on == true ? 0:1);
REG_GET(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, &power_status);
if (power_status != 0)
@@ -229,6 +233,8 @@ bool dpp3_program_gamcor_lut(
if (params == NULL) { //bypass if we have no pwl data
REG_SET(CM_GAMCOR_CONTROL, 0, CM_GAMCOR_MODE, 0);
+ if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
+ dpp3_power_on_gamcor_lut(dpp_base, false);
return false;
}
dpp3_power_on_gamcor_lut(dpp_base, true);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index e76d6ab8d93a..283995ab9eeb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -462,6 +462,13 @@ void dcn30_init_hw(struct dc *dc)
hws->funcs.disable_vga(dc->hwseq);
}
+ if (dc->debug.enable_mem_low_power.bits.dmcu) {
+ // Force ERAM to shutdown if DMCU is not enabled
+ if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {
+ REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);
+ }
+ }
+
// Set default OPTC memory power states
if (dc->debug.enable_mem_low_power.bits.optc) {
// Shutdown when unassigned and light sleep in VBLANK
@@ -825,5 +832,5 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc,
int width, int height, int offset)
{
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, 0);
+ color_space, color_depth, solid_color, width, height, offset);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
index 01ac8b2921c6..5e126fdf6ec1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
@@ -933,7 +933,7 @@ static struct dce_aux *dcn30_aux_engine_create(
return &aux_engine->base;
}
-#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
+#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id) }
static const struct dce_i2c_registers i2c_hw_regs[] = {
i2c_inst_regs(1),
@@ -945,11 +945,11 @@ static const struct dce_i2c_registers i2c_hw_regs[] = {
};
static const struct dce_i2c_shift i2c_shifts = {
- I2C_COMMON_MASK_SH_LIST_DCN2(__SHIFT)
+ I2C_COMMON_MASK_SH_LIST_DCN30(__SHIFT)
};
static const struct dce_i2c_mask i2c_masks = {
- I2C_COMMON_MASK_SH_LIST_DCN2(_MASK)
+ I2C_COMMON_MASK_SH_LIST_DCN30(_MASK)
};
static struct dce_i2c_hw *dcn30_i2c_hw_create(
@@ -1451,12 +1451,13 @@ static struct clock_source *dcn30_clock_source_create(
int dcn30_populate_dml_pipes_from_context(
struct dc *dc, struct dc_state *context,
- display_e2e_pipe_params_st *pipes)
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate)
{
int i, pipe_cnt;
struct resource_context *res_ctx = &context->res_ctx;
- dcn20_populate_dml_pipes_from_context(dc, context, pipes);
+ dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate);
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
if (!res_ctx->pipe_ctx[i].stream)
@@ -1469,20 +1470,8 @@ int dcn30_populate_dml_pipes_from_context(
return pipe_cnt;
}
-/*
- * This must be noinline to ensure anything that deals with FP registers
- * is contained within this call; previously our compiling with hard-float
- * would result in fp instructions being emitted outside of the boundaries
- * of the DC_FP_START/END macros, which makes sense as the compiler has no
- * idea about what is wrapped and what is not
- *
- * This is largely just a workaround to avoid breakage introduced with 5.6,
- * ideally all fp-using code should be moved into its own file, only that
- * should be compiled with hard-float, and all code exported from there
- * should be strictly wrapped with DC_FP_START/END
- */
-static noinline void dcn30_populate_dml_writeback_from_context_fp(
- struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
+void dcn30_populate_dml_writeback_from_context(
+ struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
{
int pipe_cnt, i, j;
double max_calc_writeback_dispclk;
@@ -1570,14 +1559,6 @@ static noinline void dcn30_populate_dml_writeback_from_context_fp(
}
-void dcn30_populate_dml_writeback_from_context(
- struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
-{
- DC_FP_START();
- dcn30_populate_dml_writeback_from_context_fp(dc, res_ctx, pipes);
- DC_FP_END();
-}
-
unsigned int dcn30_calc_max_scaled_time(
unsigned int time_per_pixel,
enum mmhubbub_wbif_mode mode,
@@ -1976,7 +1957,7 @@ static struct pipe_ctx *dcn30_find_split_pipe(
return pipe;
}
-static bool dcn30_internal_validate_bw(
+static noinline bool dcn30_internal_validate_bw(
struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
@@ -1996,8 +1977,9 @@ static bool dcn30_internal_validate_bw(
if (!pipes)
return false;
- 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);
+ DC_FP_START();
if (!pipe_cnt) {
out = true;
goto validate_out;
@@ -2210,7 +2192,7 @@ static bool dcn30_internal_validate_bw(
}
if (repopulate_pipes)
- 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);
*vlevel_out = vlevel;
*pipe_cnt_out = pipe_cnt;
@@ -2221,6 +2203,7 @@ validate_fail:
out = false;
validate_out:
+ DC_FP_END();
return out;
}
@@ -2403,7 +2386,7 @@ void dcn30_calculate_wm_and_dlg(
DC_FP_END();
}
-static noinline bool dcn30_validate_bandwidth_fp(struct dc *dc,
+bool dcn30_validate_bandwidth(struct dc *dc,
struct dc_state *context,
bool fast_validate)
{
@@ -2454,19 +2437,6 @@ validate_out:
return out;
}
-bool dcn30_validate_bandwidth(struct dc *dc,
- struct dc_state *context,
- bool fast_validate)
-{
- bool out;
-
- DC_FP_START();
- out = dcn30_validate_bandwidth_fp(dc, context, fast_validate);
- DC_FP_END();
-
- return out;
-}
-
static noinline void get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
unsigned int *optimal_dcfclk,
unsigned int *optimal_fclk)
@@ -2680,6 +2650,7 @@ static bool dcn30_resource_construct(
dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
dc->caps.color.dpp.post_csc = 1;
dc->caps.color.dpp.gamma_corr = 1;
+ dc->caps.color.dpp.dgam_rom_for_yuv = 0;
dc->caps.color.dpp.hw_3d_lut = 1;
dc->caps.color.dpp.ogam_ram = 1;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h
index d163812af858..8ce7f6d39a20 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h
@@ -65,7 +65,8 @@ void dcn30_populate_dml_writeback_from_context(
int dcn30_populate_dml_pipes_from_context(
struct dc *dc, struct dc_state *context,
- display_e2e_pipe_params_st *pipes);
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate);
bool dcn30_acquire_post_bldn_3dlut(
struct resource_context *res_ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c
index 9c0020c8a730..8cfd181b4d5f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c
@@ -103,69 +103,69 @@ static void vpg3_update_generic_info_packet(
}
}
- /* atomically update double-buffered GENERIC0 registers in frame mode
+ /* atomically update double-buffered GENERIC0 registers in immediate mode
* (update at next block_update when block_update_lock == 0).
*/
switch (packet_index) {
case 0:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC0_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC0_IMMEDIATE_UPDATE, 1);
break;
case 1:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC1_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC1_IMMEDIATE_UPDATE, 1);
break;
case 2:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC2_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC2_IMMEDIATE_UPDATE, 1);
break;
case 3:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC3_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC3_IMMEDIATE_UPDATE, 1);
break;
case 4:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC4_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC4_IMMEDIATE_UPDATE, 1);
break;
case 5:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC5_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC5_IMMEDIATE_UPDATE, 1);
break;
case 6:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC6_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC6_IMMEDIATE_UPDATE, 1);
break;
case 7:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC7_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC7_IMMEDIATE_UPDATE, 1);
break;
case 8:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC8_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC8_IMMEDIATE_UPDATE, 1);
break;
case 9:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC9_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC9_IMMEDIATE_UPDATE, 1);
break;
case 10:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC10_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC10_IMMEDIATE_UPDATE, 1);
break;
case 11:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC11_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC11_IMMEDIATE_UPDATE, 1);
break;
case 12:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC12_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC12_IMMEDIATE_UPDATE, 1);
break;
case 13:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC13_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC13_IMMEDIATE_UPDATE, 1);
break;
case 14:
- REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
- VPG_GENERIC14_FRAME_UPDATE, 1);
+ REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL,
+ VPG_GENERIC14_IMMEDIATE_UPDATE, 1);
break;
default:
break;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h
index 0284092630f1..6161e9e66355 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h
@@ -34,13 +34,15 @@
SRI(VPG_GENERIC_STATUS, VPG, id), \
SRI(VPG_GENERIC_PACKET_ACCESS_CTRL, VPG, id), \
SRI(VPG_GENERIC_PACKET_DATA, VPG, id), \
- SRI(VPG_GSP_FRAME_UPDATE_CTRL, VPG, id)
+ SRI(VPG_GSP_FRAME_UPDATE_CTRL, VPG, id), \
+ SRI(VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG, id)
struct dcn30_vpg_registers {
uint32_t VPG_GENERIC_STATUS;
uint32_t VPG_GENERIC_PACKET_ACCESS_CTRL;
uint32_t VPG_GENERIC_PACKET_DATA;
uint32_t VPG_GSP_FRAME_UPDATE_CTRL;
+ uint32_t VPG_GSP_IMMEDIATE_UPDATE_CTRL;
};
#define DCN3_VPG_MASK_SH_LIST(mask_sh)\
@@ -65,7 +67,22 @@ struct dcn30_vpg_registers {
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC11_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC12_FRAME_UPDATE, mask_sh),\
SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC13_FRAME_UPDATE, mask_sh),\
- SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC14_FRAME_UPDATE, mask_sh)
+ SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC14_FRAME_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC0_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC1_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC2_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC3_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC4_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC5_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC6_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC7_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC8_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC9_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC10_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC11_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC12_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC13_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(VPG0_VPG_GSP_IMMEDIATE_UPDATE_CTRL, VPG_GENERIC14_IMMEDIATE_UPDATE, mask_sh)
#define VPG_DCN3_REG_FIELD_LIST(type) \
type VPG_GENERIC_CONFLICT_OCCURED;\
@@ -89,7 +106,22 @@ struct dcn30_vpg_registers {
type VPG_GENERIC11_FRAME_UPDATE;\
type VPG_GENERIC12_FRAME_UPDATE;\
type VPG_GENERIC13_FRAME_UPDATE;\
- type VPG_GENERIC14_FRAME_UPDATE
+ type VPG_GENERIC14_FRAME_UPDATE;\
+ type VPG_GENERIC0_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC1_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC2_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC3_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC4_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC5_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC6_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC7_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC8_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC9_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC10_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC11_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC12_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC13_IMMEDIATE_UPDATE;\
+ type VPG_GENERIC14_IMMEDIATE_UPDATE
struct dcn30_vpg_shift {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
index 5a47b4106b7b..4825c5c1c6ed 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
@@ -73,6 +73,9 @@
#include "nbio/nbio_7_2_0_offset.h"
+#include "dcn/dpcs_3_0_0_offset.h"
+#include "dcn/dpcs_3_0_0_sh_mask.h"
+
#include "reg_helper.h"
#include "dce/dmub_abm.h"
#include "dce/dce_aux.h"
@@ -164,29 +167,63 @@ struct _vcs_dpi_ip_params_st dcn3_01_ip = {
struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc = {
.clock_limits = {
- /*TODO: fill out defaults once wm plociy is settled*/
{
.state = 0,
- .dcfclk_mhz = 810.0,
- .fabricclk_mhz = 1200.0,
+ .dram_speed_mts = 2400.0,
+ .fabricclk_mhz = 600,
+ .socclk_mhz = 278.0,
+ .dcfclk_mhz = 400.0,
+ .dscclk_mhz = 206.0,
+ .dppclk_mhz = 1015.0,
+ .dispclk_mhz = 1015.0,
+ .phyclk_mhz = 600.0,
+ },
+ {
+ .state = 1,
+ .dram_speed_mts = 2400.0,
+ .fabricclk_mhz = 688,
+ .socclk_mhz = 278.0,
+ .dcfclk_mhz = 400.0,
+ .dscclk_mhz = 206.0,
+ .dppclk_mhz = 1015.0,
.dispclk_mhz = 1015.0,
+ .phyclk_mhz = 600.0,
+ },
+ {
+ .state = 2,
+ .dram_speed_mts = 4267.0,
+ .fabricclk_mhz = 1067,
+ .socclk_mhz = 278.0,
+ .dcfclk_mhz = 608.0,
+ .dscclk_mhz = 296.0,
.dppclk_mhz = 1015.0,
+ .dispclk_mhz = 1015.0,
.phyclk_mhz = 810.0,
- .socclk_mhz = 1000.0,
+ },
+
+ {
+ .state = 3,
+ .dram_speed_mts = 4267.0,
+ .fabricclk_mhz = 1067,
+ .socclk_mhz = 715.0,
+ .dcfclk_mhz = 676.0,
.dscclk_mhz = 338.0,
- .dram_speed_mts = 4266.0,
+ .dppclk_mhz = 1015.0,
+ .dispclk_mhz = 1015.0,
+ .phyclk_mhz = 810.0,
},
+
{
- .state = 1,
+ .state = 4,
+ .dram_speed_mts = 4267.0,
+ .fabricclk_mhz = 1067,
+ .socclk_mhz = 953.0,
.dcfclk_mhz = 810.0,
- .fabricclk_mhz = 1200.0,
- .dispclk_mhz = 1015.0,
+ .dscclk_mhz = 338.0,
.dppclk_mhz = 1015.0,
+ .dispclk_mhz = 1015.0,
.phyclk_mhz = 810.0,
- .socclk_mhz = 1000.0,
- .dscclk_mhz = 338.0,
- .dram_speed_mts = 4266.0,
- }
+ },
},
.sr_exit_time_us = 9.0,
@@ -226,7 +263,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc = {
.xfc_bus_transport_time_us = 20, // ?
.xfc_xbuf_latency_tolerance_us = 4, // ?
.use_urgent_burst_bw = 1, // ?
- .num_states = 2,
+ .num_states = 5,
.do_urgent_latency_adjustment = false,
.urgent_latency_adjustment_fabric_clock_component_us = 0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
@@ -483,10 +520,13 @@ static const struct dcn10_link_enc_hpd_registers link_enc_hpd_regs[] = {
hpd_regs(3),
};
+
#define link_regs(id, phyid)\
[id] = {\
LE_DCN301_REG_LIST(id), \
UNIPHY_DCN2_REG_LIST(phyid), \
+ DPCS_DCN2_REG_LIST(id), \
+ SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
}
static const struct dce110_aux_registers_shift aux_shift = {
@@ -505,11 +545,13 @@ static const struct dcn10_link_enc_registers link_enc_regs[] = {
};
static const struct dcn10_link_enc_shift le_shift = {
- LINK_ENCODER_MASK_SH_LIST_DCN301(__SHIFT)
+ LINK_ENCODER_MASK_SH_LIST_DCN301(__SHIFT),\
+ DPCS_DCN2_MASK_SH_LIST(__SHIFT)
};
static const struct dcn10_link_enc_mask le_mask = {
- LINK_ENCODER_MASK_SH_LIST_DCN301(_MASK)
+ LINK_ENCODER_MASK_SH_LIST_DCN301(_MASK),\
+ DPCS_DCN2_MASK_SH_LIST(_MASK)
};
#define panel_cntl_regs(id)\
@@ -815,12 +857,11 @@ static const struct dc_debug_options debug_defaults_drv = {
.force_abm_enable = false,
.timing_trace = false,
.clock_trace = true,
- .disable_dpp_power_gate = true,
- .disable_hubp_power_gate = true,
+ .disable_dpp_power_gate = false,
+ .disable_hubp_power_gate = false,
.disable_clock_gate = true,
.disable_pplib_clock_request = true,
.disable_pplib_wm_range = true,
- .disable_stutter = true,
.pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
.force_single_disp_pipe_split = false,
.disable_dcc = DCC_ENABLE,
@@ -839,8 +880,8 @@ static const struct dc_debug_options debug_defaults_diags = {
.force_abm_enable = false,
.timing_trace = true,
.clock_trace = true,
- .disable_dpp_power_gate = true,
- .disable_hubp_power_gate = true,
+ .disable_dpp_power_gate = false,
+ .disable_hubp_power_gate = false,
.disable_clock_gate = true,
.disable_pplib_clock_request = true,
.disable_pplib_wm_range = true,
@@ -1189,8 +1230,6 @@ static const struct resource_create_funcs res_create_maximus_funcs = {
.create_hwseq = dcn301_hwseq_create,
};
-static void dcn301_pp_smu_destroy(struct pp_smu_funcs **pp_smu);
-
static void dcn301_destruct(struct dcn301_resource_pool *pool)
{
unsigned int i;
@@ -1311,9 +1350,6 @@ static void dcn301_destruct(struct dcn301_resource_pool *pool)
if (pool->base.dccg != NULL)
dcn_dccg_destroy(&pool->base.dccg);
-
- if (pool->base.pp_smu != NULL)
- dcn301_pp_smu_destroy(&pool->base.pp_smu);
}
struct hubp *dcn301_hubp_create(
@@ -1566,41 +1602,25 @@ static bool init_soc_bounding_box(struct dc *dc,
}
}
- if (pool->base.pp_smu) {
- struct pp_smu_nv_clock_table max_clocks = {0};
- unsigned int uclk_states[8] = {0};
- unsigned int num_states = 0;
- enum pp_smu_status status;
- bool clock_limits_available = false;
- bool uclk_states_available = false;
+ loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
+ loaded_ip->max_num_dpp = pool->base.pipe_count;
+ dcn20_patch_bounding_box(dc, loaded_bb);
- if (pool->base.pp_smu->nv_funcs.get_uclk_dpm_states) {
- status = (pool->base.pp_smu->nv_funcs.get_uclk_dpm_states)
- (&pool->base.pp_smu->nv_funcs.pp_smu, uclk_states, &num_states);
+ if (!bb && dc->ctx->dc_bios->funcs->get_soc_bb_info) {
+ struct bp_soc_bb_info bb_info = {0};
- uclk_states_available = (status == PP_SMU_RESULT_OK);
- }
+ if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) {
+ if (bb_info.dram_clock_change_latency_100ns > 0)
+ dcn3_01_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10;
- if (pool->base.pp_smu->nv_funcs.get_maximum_sustainable_clocks) {
- status = (*pool->base.pp_smu->nv_funcs.get_maximum_sustainable_clocks)
- (&pool->base.pp_smu->nv_funcs.pp_smu, &max_clocks);
- /* SMU cannot set DCF clock to anything equal to or higher than SOC clock
- */
- if (max_clocks.dcfClockInKhz >= max_clocks.socClockInKhz)
- max_clocks.dcfClockInKhz = max_clocks.socClockInKhz - 1000;
- clock_limits_available = (status == PP_SMU_RESULT_OK);
- }
+ if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
+ dcn3_01_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10;
- if (clock_limits_available && uclk_states_available && num_states)
- dcn20_update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states);
- else if (clock_limits_available)
- dcn20_cap_soc_clocks(loaded_bb, max_clocks);
+ if (bb_info.dram_sr_exit_latency_100ns > 0)
+ dcn3_01_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10;
+ }
}
- loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
- loaded_ip->max_num_dpp = pool->base.pipe_count;
- dcn20_patch_bounding_box(dc, loaded_bb);
-
return true;
}
@@ -1648,36 +1668,58 @@ static void set_wm_ranges(
pp_smu->nv_funcs.set_wm_ranges(&pp_smu->nv_funcs.pp_smu, &ranges);
}
-static struct pp_smu_funcs *dcn301_pp_smu_create(struct dc_context *ctx)
+static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
{
- struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL);
-
- if (!pp_smu)
- return pp_smu;
-
- if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment) && !IS_DIAG_DC(ctx->dce_environment)) {
- dm_pp_get_funcs(ctx, pp_smu);
-
- /* TODO: update once we have n21 smu*/
- if (pp_smu->ctx.ver != PP_SMU_VER_NV)
- pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs));
- }
-
- return pp_smu;
-}
+ struct dcn301_resource_pool *pool = TO_DCN301_RES_POOL(dc->res_pool);
+ struct clk_limit_table *clk_table = &bw_params->clk_table;
+ struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
+ unsigned int i, closest_clk_lvl;
+ int j;
+
+ // Default clock levels are used for diags, which may lead to overclocking.
+ if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
+ dcn3_01_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
+ dcn3_01_ip.max_num_dpp = pool->base.pipe_count;
+ dcn3_01_soc.num_chans = bw_params->num_channels;
+
+ ASSERT(clk_table->num_entries);
+ for (i = 0; i < clk_table->num_entries; i++) {
+ /* loop backwards*/
+ for (closest_clk_lvl = 0, j = dcn3_01_soc.num_states - 1; j >= 0; j--) {
+ if ((unsigned int) dcn3_01_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
+ closest_clk_lvl = j;
+ break;
+ }
+ }
-static void dcn301_pp_smu_destroy(struct pp_smu_funcs **pp_smu)
-{
- if (pp_smu && *pp_smu) {
- kfree(*pp_smu);
- *pp_smu = NULL;
+ clock_limits[i].state = i;
+ clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
+ clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
+ clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
+ clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
+
+ clock_limits[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
+ clock_limits[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
+ clock_limits[i].dram_bw_per_chan_gbps = dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
+ clock_limits[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
+ clock_limits[i].dtbclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
+ clock_limits[i].phyclk_d18_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
+ clock_limits[i].phyclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
+ }
+ for (i = 0; i < clk_table->num_entries; i++)
+ dcn3_01_soc.clock_limits[i] = clock_limits[i];
+ if (clk_table->num_entries) {
+ dcn3_01_soc.num_states = clk_table->num_entries;
+ /* duplicate last level */
+ dcn3_01_soc.clock_limits[dcn3_01_soc.num_states] = dcn3_01_soc.clock_limits[dcn3_01_soc.num_states - 1];
+ dcn3_01_soc.clock_limits[dcn3_01_soc.num_states].state = dcn3_01_soc.num_states;
+ }
}
-}
-static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
-{
dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
+
+ dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30);
}
static struct resource_funcs dcn301_res_pool_funcs = {
@@ -1725,7 +1767,9 @@ static bool dcn301_resource_construct(
pool->base.mpcc_count = pool->base.res_cap->num_timing_generator;
dc->caps.max_downscale_ratio = 600;
dc->caps.i2c_speed_in_khz = 100;
+ dc->caps.i2c_speed_in_khz_hdcp = 5; /*1.4 w/a enabled by default*/
dc->caps.max_cursor_size = 256;
+ dc->caps.min_horizontal_blanking_period = 80;
dc->caps.dmdata_alloc_size = 2048;
dc->caps.max_slave_planes = 1;
dc->caps.is_apu = true;
@@ -1748,6 +1792,7 @@ static bool dcn301_resource_construct(
dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
dc->caps.color.dpp.post_csc = 1;
dc->caps.color.dpp.gamma_corr = 1;
+ dc->caps.color.dpp.dgam_rom_for_yuv = 0;
dc->caps.color.dpp.hw_3d_lut = 1;
dc->caps.color.dpp.ogam_ram = 1;
@@ -1825,9 +1870,8 @@ static bool dcn301_resource_construct(
goto create_fail;
}
- /* PP Lib and SMU interfaces */
- pool->base.pp_smu = dcn301_pp_smu_create(ctx);
init_soc_bounding_box(dc, pool);
+
if (!dc->debug.disable_pplib_wm_range && pool->base.pp_smu->nv_funcs.set_wm_ranges)
set_wm_ranges(pool->base.pp_smu, &dcn3_01_soc);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
index 2345f12ceab3..808c4dcdb3ac 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
@@ -60,8 +60,8 @@
#include "vm_helper.h"
#include "dimgrey_cavefish_ip_offset.h"
-#include "dcn/dcn_3_0_0_offset.h"
-#include "dcn/dcn_3_0_0_sh_mask.h"
+#include "dcn/dcn_3_0_2_offset.h"
+#include "dcn/dcn_3_0_2_sh_mask.h"
#include "dcn/dpcs_3_0_0_offset.h"
#include "dcn/dpcs_3_0_0_sh_mask.h"
#include "nbio/nbio_7_4_offset.h"
@@ -967,6 +967,7 @@ static const struct encoder_feature_support link_enc_feature = {
[id] = {\
LE_DCN3_REG_LIST(id), \
UNIPHY_DCN2_REG_LIST(phyid), \
+ DPCS_DCN2_REG_LIST(id), \
SRI(DP_DPHY_INTERNAL_CTRL, DP, id) \
}
@@ -1306,7 +1307,9 @@ static bool dcn302_resource_construct(
pool->mpcc_count = pool->res_cap->num_timing_generator;
dc->caps.max_downscale_ratio = 600;
dc->caps.i2c_speed_in_khz = 100;
+ dc->caps.i2c_speed_in_khz_hdcp = 5; /*1.4 w/a applied by derfault*/
dc->caps.max_cursor_size = 256;
+ dc->caps.min_horizontal_blanking_period = 80;
dc->caps.dmdata_alloc_size = 2048;
dc->caps.max_slave_planes = 1;
@@ -1327,6 +1330,7 @@ static bool dcn302_resource_construct(
dc->caps.color.dpp.dgam_rom_caps.hlg = 1;
dc->caps.color.dpp.post_csc = 1;
dc->caps.color.dpp.gamma_corr = 1;
+ dc->caps.color.dpp.dgam_rom_for_yuv = 0;
dc->caps.color.dpp.hw_3d_lut = 1;
dc->caps.color.dpp.ogam_ram = 1;
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index b2cd8491c707..07e349b1067b 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -113,7 +113,7 @@ bool dm_helpers_dp_mst_start_top_mgr(
void dm_helpers_dp_mst_stop_top_mgr(
struct dc_context *ctx,
- const struct dc_link *link);
+ struct dc_link *link);
/**
* OS specific aux read callback.
*/
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
index 367c82b5ab4c..86ff24dffc3e 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
@@ -5477,7 +5477,7 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport(
}
}
- if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
+ if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0 && PrefetchMode == 0) {
*DRAMClockChangeSupport = dm_dram_clock_change_vactive;
} else if (((mode_lib->vba.SynchronizedVBlank == true
|| mode_lib->vba.TotalNumberOfActiveOTG == 1
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
index 162464261205..dd0c3b1780d7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
@@ -334,7 +334,6 @@ struct _vcs_dpi_display_pipe_dest_params_st {
unsigned int vblank_end;
unsigned int htotal;
unsigned int vtotal;
- unsigned int refresh_rate;
unsigned int vfront_porch;
unsigned int vactive;
unsigned int hactive;
@@ -345,7 +344,6 @@ struct _vcs_dpi_display_pipe_dest_params_st {
unsigned char interlaced;
double pixel_rate_mhz;
unsigned char synchronized_vblank_all_planes;
- unsigned char synchronize_timing_if_single_refresh_rate;
unsigned char otg_inst;
unsigned int odm_combine;
unsigned char use_maximum_vstartup;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
index 62740d4e423d..c9fbb33f05a3 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
@@ -469,8 +469,7 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
mode_lib->vba.DSCEnable[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
dout->dsc_slices;
- mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
- dout->output_bpc == 0 ? 12 : dout->output_bpc;
+ mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpc;
mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
mode_lib->vba.ActiveWritebacksPerPlane[mode_lib->vba.NumberOfActivePlanes] =
dout->num_active_wb;
@@ -660,10 +659,8 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
// TODO: ODMCombineEnabled => 2 * DPPPerPlane...actually maybe not since all pipes are specified
// Do we want the dscclk to automatically be halved? Guess not since the value is specified
- mode_lib->vba.SynchronizeTimingsIfSingleRefreshRate = pipes[0].pipe.dest.synchronize_timing_if_single_refresh_rate;
mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k) {
- ASSERT(mode_lib->vba.SynchronizeTimingsIfSingleRefreshRate == pipes[k].pipe.dest.synchronize_timing_if_single_refresh_rate);
ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
index 4d4ed1287673..3529fedc4c52 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
@@ -921,7 +921,6 @@ struct vba_vars_st {
bool UseMinimumRequiredDCFCLK;
bool ClampMinDCFCLK;
bool AllowDramClockChangeOneDisplayVactive;
- bool SynchronizeTimingsIfSingleRefreshRate;
};
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index 2ce8c39ca6f5..2d77eac66cb0 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -109,7 +109,8 @@ struct resource_funcs {
int (*populate_dml_pipes)(
struct dc *dc,
struct dc_state *context,
- display_e2e_pipe_params_st *pipes);
+ display_e2e_pipe_params_st *pipes,
+ bool fast_validate);
enum dc_status (*validate_global)(
struct dc *dc,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
index 5425e92efcb8..d9fd28b34f2a 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
@@ -157,6 +157,7 @@ struct hubbub_funcs {
struct hubbub {
const struct hubbub_funcs *funcs;
struct dc_context *ctx;
+ bool riommu_active;
};
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
index 5315f1f86b21..69d9fbfb4bec 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
@@ -66,7 +66,7 @@ struct dmcu_funcs {
bool (*setup_psr)(struct dmcu *dmcu,
struct dc_link *link,
struct psr_context *psr_context);
- void (*get_psr_state)(struct dmcu *dmcu, uint32_t *psr_state);
+ void (*get_psr_state)(struct dmcu *dmcu, enum dc_psr_state *dc_psr_state);
void (*set_psr_wait_loop)(struct dmcu *dmcu,
unsigned int wait_loop_number);
void (*get_psr_wait_loop)(struct dmcu *dmcu,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
index 6751186f6f90..ddbe4bb52724 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
@@ -47,7 +47,7 @@ struct dpp_input_csc_matrix {
uint16_t regval[12];
};
-static const struct dpp_input_csc_matrix dpp_input_csc_matrix[] = {
+static const struct dpp_input_csc_matrix __maybe_unused dpp_input_csc_matrix[] = {
{COLOR_SPACE_SRGB,
{0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
{COLOR_SPACE_SRGB_LIMITED,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
index a3a27c16aa2f..43e33f47734d 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
@@ -264,4 +264,88 @@ enum dc_lut_mode {
LUT_RAM_A,
LUT_RAM_B
};
+
+/**
+ * speakersToChannels
+ *
+ * @brief
+ * translate speakers to channels
+ *
+ * FL - Front Left
+ * FR - Front Right
+ * RL - Rear Left
+ * RR - Rear Right
+ * RC - Rear Center
+ * FC - Front Center
+ * FLC - Front Left Center
+ * FRC - Front Right Center
+ * RLC - Rear Left Center
+ * RRC - Rear Right Center
+ * LFE - Low Freq Effect
+ *
+ * FC
+ * FLC FRC
+ * FL FR
+ *
+ * LFE
+ * ()
+ *
+ *
+ * RL RR
+ * RLC RRC
+ * RC
+ *
+ * ch 8 7 6 5 4 3 2 1
+ * 0b00000011 - - - - - - FR FL
+ * 0b00000111 - - - - - LFE FR FL
+ * 0b00001011 - - - - FC - FR FL
+ * 0b00001111 - - - - FC LFE FR FL
+ * 0b00010011 - - - RC - - FR FL
+ * 0b00010111 - - - RC - LFE FR FL
+ * 0b00011011 - - - RC FC - FR FL
+ * 0b00011111 - - - RC FC LFE FR FL
+ * 0b00110011 - - RR RL - - FR FL
+ * 0b00110111 - - RR RL - LFE FR FL
+ * 0b00111011 - - RR RL FC - FR FL
+ * 0b00111111 - - RR RL FC LFE FR FL
+ * 0b01110011 - RC RR RL - - FR FL
+ * 0b01110111 - RC RR RL - LFE FR FL
+ * 0b01111011 - RC RR RL FC - FR FL
+ * 0b01111111 - RC RR RL FC LFE FR FL
+ * 0b11110011 RRC RLC RR RL - - FR FL
+ * 0b11110111 RRC RLC RR RL - LFE FR FL
+ * 0b11111011 RRC RLC RR RL FC - FR FL
+ * 0b11111111 RRC RLC RR RL FC LFE FR FL
+ * 0b11000011 FRC FLC - - - - FR FL
+ * 0b11000111 FRC FLC - - - LFE FR FL
+ * 0b11001011 FRC FLC - - FC - FR FL
+ * 0b11001111 FRC FLC - - FC LFE FR FL
+ * 0b11010011 FRC FLC - RC - - FR FL
+ * 0b11010111 FRC FLC - RC - LFE FR FL
+ * 0b11011011 FRC FLC - RC FC - FR FL
+ * 0b11011111 FRC FLC - RC FC LFE FR FL
+ * 0b11110011 FRC FLC RR RL - - FR FL
+ * 0b11110111 FRC FLC RR RL - LFE FR FL
+ * 0b11111011 FRC FLC RR RL FC - FR FL
+ * 0b11111111 FRC FLC RR RL FC LFE FR FL
+ *
+ * @param
+ * speakers - speaker information as it comes from CEA audio block
+ */
+/* translate speakers to channels */
+
+union audio_cea_channels {
+ uint8_t all;
+ struct audio_cea_channels_bits {
+ uint32_t FL:1;
+ uint32_t FR:1;
+ uint32_t LFE:1;
+ uint32_t FC:1;
+ uint32_t RL_RC:1;
+ uint32_t RR:1;
+ uint32_t RC_RLC_FLC:1;
+ uint32_t RRC_FRC:1;
+ } channels;
+};
+
#endif /* __DAL_HW_SHARED_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c
index 2a1fea501f8c..3f1e7a196a23 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c
@@ -299,8 +299,8 @@ irq_source_info_dcn20[DAL_IRQ_SOURCES_NUMBER] = {
pflip_int_entry(1),
pflip_int_entry(2),
pflip_int_entry(3),
- [DC_IRQ_SOURCE_PFLIP5] = dummy_irq_entry(),
- [DC_IRQ_SOURCE_PFLIP6] = dummy_irq_entry(),
+ pflip_int_entry(4),
+ pflip_int_entry(5),
[DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(),
gpio_pad_int_entry(0),
gpio_pad_int_entry(1),