* [PATCH 01/21] drm/amd/display: Migrate DCCG register access from hwseq to dccg component.
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 02/21] drm/amd/display: Add lpddr5 handling to dml2.1 Wayne Lin
` (19 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Bhuvanachandra Pinninti, Martin Leung
From: Bhuvanachandra Pinninti <bpinnint@amd.com>
[why]
Direct DCCG register access in hwseq layer was creating register conflicts.
[how]
Migrated DCCG registers from hwseq to dccg component.
Reviewed-by: Martin Leung <martin.leung@amd.com>
Signed-off-by: Bhuvanachandra Pinninti <bpinnint@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../amd/display/dc/dccg/dcn20/dcn20_dccg.c | 54 ++++++++++++++++++-
.../amd/display/dc/dccg/dcn20/dcn20_dccg.h | 18 +++++--
.../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 5 +-
.../amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 29 +++-------
.../amd/display/dc/hwss/dcn201/dcn201_hwseq.c | 5 +-
.../amd/display/dc/hwss/dcn21/dcn21_hwseq.c | 9 ++--
.../amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 5 +-
.../amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 5 +-
.../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 5 +-
.../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 3 +-
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 5 +-
drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 4 ++
12 files changed, 98 insertions(+), 49 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c
index 33d8bd91cb01..50b98822b6fd 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c
@@ -131,6 +131,54 @@ void dccg2_otg_drop_pixel(struct dccg *dccg,
void dccg2_init(struct dccg *dccg)
{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ /* Hardcoded register values for DCN20
+ * These are specific to 100Mhz refclk
+ * Different ASICs with different refclk may override this in their own init
+ */
+ REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x00120264);
+ REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x001186a0);
+ REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0x0e01003c);
+
+ if (REG(REFCLK_CNTL))
+ REG_WRITE(REFCLK_CNTL, 0);
+}
+
+void dccg2_refclk_setup(struct dccg *dccg)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ /* REFCLK programming that must occur after hubbub initialization */
+ if (REG(REFCLK_CNTL))
+ REG_WRITE(REFCLK_CNTL, 0);
+}
+
+bool dccg2_is_s0i3_golden_init_wa_done(struct dccg *dccg)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ return REG_READ(MICROSECOND_TIME_BASE_DIV) == 0x00120464;
+}
+
+void dccg2_allow_clock_gating(struct dccg *dccg, bool allow)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ if (allow) {
+ REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
+ REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+ } else {
+ REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0xFFFFFFFF);
+ REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0xFFFFFFFF);
+ }
+}
+
+void dccg2_enable_memory_low_power(struct dccg *dccg, bool enable)
+{
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, enable ? 0 : 1);
}
static const struct dccg_funcs dccg2_funcs = {
@@ -139,7 +187,11 @@ static const struct dccg_funcs dccg2_funcs = {
.set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
.otg_add_pixel = dccg2_otg_add_pixel,
.otg_drop_pixel = dccg2_otg_drop_pixel,
- .dccg_init = dccg2_init
+ .dccg_init = dccg2_init,
+ .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */
+ .allow_clock_gating = dccg2_allow_clock_gating,
+ .enable_memory_low_power = dccg2_enable_memory_low_power,
+ .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done
};
struct dccg *dccg2_create(
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
index 8bdffd9ff31b..237a684ded86 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h
@@ -46,7 +46,9 @@
DCCG_SRII(PIXEL_RATE_CNTL, OTG, 2),\
DCCG_SRII(PIXEL_RATE_CNTL, OTG, 3),\
DCCG_SRII(PIXEL_RATE_CNTL, OTG, 4),\
- DCCG_SRII(PIXEL_RATE_CNTL, OTG, 5)
+ DCCG_SRII(PIXEL_RATE_CNTL, OTG, 5),\
+ SR(DCCG_GATE_DISABLE_CNTL),\
+ SR(DCCG_GATE_DISABLE_CNTL2)
#define DCCG_SF(reg_name, field_name, post_fix)\
.field_name = reg_name ## __ ## field_name ## post_fix
@@ -81,7 +83,8 @@
DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 0, mask_sh),\
DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 1, mask_sh),\
DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 0, mask_sh),\
- DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 1, mask_sh)
+ DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 1, mask_sh),\
+ DCCG_SF(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh)
@@ -130,7 +133,8 @@
type DISPCLK_CHG_FWD_CORR_DISABLE;\
type DISPCLK_FREQ_CHANGE_CNTL;\
type OTG_ADD_PIXEL[MAX_PIPES];\
- type OTG_DROP_PIXEL[MAX_PIPES];
+ type OTG_DROP_PIXEL[MAX_PIPES];\
+ type DC_MEM_GLOBAL_PWR_REQ_DIS;
#define DCCG3_REG_FIELD_LIST(type) \
type HDMICHARCLK0_EN;\
@@ -515,6 +519,14 @@ void dccg2_otg_drop_pixel(struct dccg *dccg,
void dccg2_init(struct dccg *dccg);
+void dccg2_refclk_setup(struct dccg *dccg);
+
+bool dccg2_is_s0i3_golden_init_wa_done(struct dccg *dccg);
+
+void dccg2_allow_clock_gating(struct dccg *dccg, bool allow);
+
+void dccg2_enable_memory_low_power(struct dccg *dccg, bool enable);
+
struct dccg *dccg2_create(
struct dc_context *ctx,
const struct dccg_registers *regs,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
index c1586364ecd4..f89b2f5a9bbd 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
@@ -1885,9 +1885,8 @@ void dcn10_init_hw(struct dc *dc)
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
- REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
- REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+ if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+ dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
index a76436dcbe40..87a1dc27def4 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -357,26 +357,10 @@ void dcn20_enable_power_gating_plane(
void dcn20_dccg_init(struct dce_hwseq *hws)
{
- /*
- * set MICROSECOND_TIME_BASE_DIV
- * 100Mhz refclk -> 0x120264
- * 27Mhz refclk -> 0x12021b
- * 48Mhz refclk -> 0x120230
- *
- */
- REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x120264);
+ struct dc *dc = hws->ctx->dc;
- /*
- * set MILLISECOND_TIME_BASE_DIV
- * 100Mhz refclk -> 0x1186a0
- * 27Mhz refclk -> 0x106978
- * 48Mhz refclk -> 0x10bb80
- *
- */
- REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x1186a0);
-
- /* This value is dependent on the hardware pipeline delay so set once per SOC */
- REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0xe01003c);
+ if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->dccg_init)
+ dc->res_pool->dccg->funcs->dccg_init(dc->res_pool->dccg);
}
void dcn20_disable_vga(
@@ -3155,8 +3139,11 @@ void dcn20_fpga_init_hw(struct dc *dc)
REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF);
dcn10_hubbub_global_timer_enable(dc->res_pool->hubbub, true, 2);
- if (REG(REFCLK_CNTL))
- REG_WRITE(REFCLK_CNTL, 0);
+
+ hws->funcs.dccg_init(hws);
+
+ if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->refclk_setup)
+ dc->res_pool->dccg->funcs->refclk_setup(dc->res_pool->dccg);
//
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
index 482053c4ad22..7cd225a6cf6c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
@@ -364,9 +364,8 @@ void dcn201_init_hw(struct dc *dc)
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
- REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
- REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+ if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+ dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c
index e2269211553c..062745389d9a 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c
@@ -33,6 +33,7 @@
#include "vmid.h"
#include "reg_helper.h"
#include "hw/clk_mgr.h"
+#include "hw/dccg.h"
#include "dc_dmub_srv.h"
#include "abm.h"
#include "link_service.h"
@@ -87,12 +88,10 @@ int dcn21_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_
bool dcn21_s0i3_golden_init_wa(struct dc *dc)
{
- struct dce_hwseq *hws = dc->hwseq;
- uint32_t value = 0;
+ if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->is_s0i3_golden_init_wa_done)
+ return !dc->res_pool->dccg->funcs->is_s0i3_golden_init_wa_done(dc->res_pool->dccg);
- value = REG_READ(MICROSECOND_TIME_BASE_DIV);
-
- return value != 0x00120464;
+ return false;
}
void dcn21_exit_optimized_pwr_state(
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
index c02ddada723f..3ff15ec9dc17 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
@@ -798,9 +798,8 @@ void dcn30_init_hw(struct dc *dc)
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
- REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
- REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+ if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+ dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
index 2adbcc105aa6..91a672a46289 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
@@ -249,9 +249,8 @@ void dcn31_init_hw(struct dc *dc)
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
- REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
- REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+ if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+ dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index 3cd44c6602b3..3f76fba7dccc 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -959,9 +959,8 @@ void dcn32_init_hw(struct dc *dc)
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
- REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
- REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+ if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+ dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
index f7e16fee7594..1c7263f9ef51 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
@@ -288,7 +288,8 @@ void dcn35_init_hw(struct dc *dc)
}
if (dc->debug.disable_mem_low_power) {
- REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
+ if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->enable_memory_low_power)
+ dc->res_pool->dccg->funcs->enable_memory_low_power(dc->res_pool->dccg, false);
}
if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 86400938abd2..567ed207d7cd 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -324,9 +324,8 @@ void dcn401_init_hw(struct dc *dc)
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
- REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
-
- REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
+ if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating)
+ dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true);
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
index 1e6ffd86a4c0..a26d31ab7cba 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
@@ -224,6 +224,9 @@ struct dccg_funcs {
void (*otg_drop_pixel)(struct dccg *dccg,
uint32_t otg_inst);
void (*dccg_init)(struct dccg *dccg);
+ void (*refclk_setup)(struct dccg *dccg); /* Deprecated - for backward compatibility only */
+ void (*allow_clock_gating)(struct dccg *dccg, bool allow);
+ void (*enable_memory_low_power)(struct dccg *dccg, bool enable);
void (*set_dpstreamclk_root_clock_gating)(
struct dccg *dccg,
int dp_hpo_inst,
@@ -334,6 +337,7 @@ struct dccg_funcs {
void (*dccg_root_gate_disable_control)(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating);
void (*dccg_read_reg_state)(struct dccg *dccg, struct dcn_dccg_reg_state *dccg_reg_state);
void (*dccg_enable_global_fgcg)(struct dccg *dccg, bool enable);
+ bool (*is_s0i3_golden_init_wa_done)(struct dccg *dccg);
};
#endif //__DAL_DCCG_H__
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 02/21] drm/amd/display: Add lpddr5 handling to dml2.1
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
2026-01-28 1:51 ` [PATCH 01/21] drm/amd/display: Migrate DCCG register access from hwseq to dccg component Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 03/21] drm/amd/display: External panel replay fsm control Wayne Lin
` (18 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Dmytro Laktyushkin, Charlene Liu
From: Dmytro Laktyushkin <dmytro.laktyushkin@amd.com>
[Why & How]
Memory bandwidth calculations work differently than for ddr.
Add lpddr5 handling.
Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Signed-off-by: Dmytro Laktyushkin <dmytro.laktyushkin@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../dml21/inc/dml_top_soc_parameter_types.h | 3 +
.../src/dml2_core/dml2_core_dcn4_calcs.c | 26 ++++++--
.../dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c | 59 ++++++++++++-------
.../src/inc/dml2_internal_shared_types.h | 1 +
4 files changed, 64 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h
index 1fbc520c2540..c4cce870877a 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h
@@ -115,9 +115,12 @@ struct dml2_dram_params {
unsigned int channel_width_bytes;
unsigned int channel_count;
unsigned int transactions_per_clock;
+ bool alt_clock_bw_conversion;
};
+#define ENABLE_WCK
struct dml2_soc_state_table {
+ struct dml2_clk_table wck_ratio;
struct dml2_clk_table uclk;
struct dml2_clk_table fclk;
struct dml2_clk_table dcfclk;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
index 01b87be24ce3..37699cc9e5c1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
@@ -7077,10 +7077,21 @@ static void calculate_excess_vactive_bandwidth_required(
}
}
-static double uclk_khz_to_dram_bw_mbps(unsigned long uclk_khz, const struct dml2_dram_params *dram_config)
+static double uclk_khz_to_dram_bw_mbps(unsigned long uclk_khz, const struct dml2_dram_params *dram_config, const struct dml2_mcg_dram_bw_to_min_clk_table *dram_bw_table)
{
double bw_mbps = 0;
- bw_mbps = ((double)uclk_khz * dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock) / 1000.0;
+ int i;
+
+ if (!dram_config->alt_clock_bw_conversion)
+ bw_mbps = ((double)uclk_khz * dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock) / 1000.0;
+ else
+ for (i = 0; i < dram_bw_table->num_entries; i++)
+ if (dram_bw_table->entries[i].min_uclk_khz >= uclk_khz) {
+ bw_mbps = (double)dram_bw_table->entries[i].pre_derate_dram_bw_kbps / 1000.0;
+ break;
+ }
+
+ ASSERT(bw_mbps > 0);
return bw_mbps;
}
@@ -7964,7 +7975,9 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
mode_lib->ms.max_dispclk_freq_mhz = (double)min_clk_table->max_ss_clocks_khz.dispclk / 1000;
mode_lib->ms.max_dscclk_freq_mhz = (double)min_clk_table->max_clocks_khz.dscclk / 1000;
mode_lib->ms.max_dppclk_freq_mhz = (double)min_clk_table->max_ss_clocks_khz.dppclk / 1000;
- mode_lib->ms.uclk_freq_mhz = dram_bw_kbps_to_uclk_mhz(min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps, &mode_lib->soc.clk_table.dram_config);
+ mode_lib->ms.uclk_freq_mhz = (double)min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].min_uclk_khz / 1000.0;
+ if (!mode_lib->ms.uclk_freq_mhz)
+ mode_lib->ms.uclk_freq_mhz = dram_bw_kbps_to_uclk_mhz(min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps, &mode_lib->soc.clk_table.dram_config);
mode_lib->ms.dram_bw_mbps = ((double)min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps / 1000);
mode_lib->ms.max_dram_bw_mbps = ((double)min_clk_table->dram_bw_table.entries[min_clk_table->dram_bw_table.num_entries - 1].pre_derate_dram_bw_kbps / 1000);
mode_lib->ms.qos_param_index = get_qos_param_index((unsigned int) (mode_lib->ms.uclk_freq_mhz * 1000.0), mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params);
@@ -10407,7 +10420,7 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
mode_lib->mp.Dcfclk = programming->min_clocks.dcn4x.active.dcfclk_khz / 1000.0;
mode_lib->mp.FabricClock = programming->min_clocks.dcn4x.active.fclk_khz / 1000.0;
- mode_lib->mp.dram_bw_mbps = uclk_khz_to_dram_bw_mbps(programming->min_clocks.dcn4x.active.uclk_khz, &mode_lib->soc.clk_table.dram_config);
+ mode_lib->mp.dram_bw_mbps = uclk_khz_to_dram_bw_mbps(programming->min_clocks.dcn4x.active.uclk_khz, &mode_lib->soc.clk_table.dram_config, &min_clk_table->dram_bw_table);
mode_lib->mp.uclk_freq_mhz = programming->min_clocks.dcn4x.active.uclk_khz / 1000.0;
mode_lib->mp.GlobalDPPCLK = programming->min_clocks.dcn4x.dpprefclk_khz / 1000.0;
s->SOCCLK = (double)programming->min_clocks.dcn4x.socclk_khz / 1000;
@@ -10485,7 +10498,10 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
DML_LOG_VERBOSE("DML::%s: SOCCLK = %f\n", __func__, s->SOCCLK);
DML_LOG_VERBOSE("DML::%s: min_clk_index = %0d\n", __func__, in_out_params->min_clk_index);
DML_LOG_VERBOSE("DML::%s: min_clk_table min_fclk_khz = %ld\n", __func__, min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].min_fclk_khz);
- DML_LOG_VERBOSE("DML::%s: min_clk_table uclk_mhz = %f\n", __func__, dram_bw_kbps_to_uclk_mhz(min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps, &mode_lib->soc.clk_table.dram_config));
+ if (min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].min_uclk_khz)
+ DML_LOG_VERBOSE("DML::%s: min_clk_table uclk_mhz = %f\n", __func__, min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].min_uclk_khz / 1000.0);
+ else
+ DML_LOG_VERBOSE("DML::%s: min_clk_table uclk_mhz = %f\n", __func__, dram_bw_kbps_to_uclk_mhz(min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps, &mode_lib->soc.clk_table.dram_config));
for (k = 0; k < mode_lib->mp.num_active_pipes; ++k) {
DML_LOG_VERBOSE("DML::%s: pipe=%d is in plane=%d\n", __func__, k, mode_lib->mp.pipe_plane[k]);
DML_LOG_VERBOSE("DML::%s: Per-plane DPPPerSurface[%0d] = %d\n", __func__, k, mode_lib->mp.NoOfDPP[k]);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
index 22969a533a7b..5c713f2e6eca 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
@@ -7,14 +7,24 @@
#include "dml_top_types.h"
#include "lib_float_math.h"
-static double dram_bw_kbps_to_uclk_khz(unsigned long long bandwidth_kbps, const struct dml2_dram_params *dram_config)
+static double dram_bw_kbps_to_uclk_khz(unsigned long long bandwidth_kbps, const struct dml2_dram_params *dram_config, struct dml2_mcg_dram_bw_to_min_clk_table *dram_bw_table)
{
double uclk_khz = 0;
- unsigned long uclk_mbytes_per_tick = 0;
- uclk_mbytes_per_tick = dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock;
+ if (!dram_config->alt_clock_bw_conversion) {
+ unsigned long uclk_bytes_per_tick = 0;
- uclk_khz = (double)bandwidth_kbps / uclk_mbytes_per_tick;
+ uclk_bytes_per_tick = dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock;
+ uclk_khz = (double)bandwidth_kbps / uclk_bytes_per_tick;
+ } else {
+ int i;
+ /* For lpddr5 bytes per tick changes with mpstate, use table to find uclk*/
+ for (i = 0; i < dram_bw_table->num_entries; i++)
+ if (dram_bw_table->entries[i].pre_derate_dram_bw_kbps >= bandwidth_kbps) {
+ uclk_khz = dram_bw_table->entries[i].min_uclk_khz;
+ break;
+ }
+ }
return uclk_khz;
}
@@ -34,7 +44,7 @@ static void get_minimum_clocks_for_latency(struct dml2_dpmm_map_mode_to_soc_dpm_
*dcfclk = in_out->min_clk_table->dram_bw_table.entries[min_clock_index_for_latency].min_dcfclk_khz;
*fclk = in_out->min_clk_table->dram_bw_table.entries[min_clock_index_for_latency].min_fclk_khz;
*uclk = dram_bw_kbps_to_uclk_khz(in_out->min_clk_table->dram_bw_table.entries[min_clock_index_for_latency].pre_derate_dram_bw_kbps,
- &in_out->soc_bb->clk_table.dram_config);
+ &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
}
static unsigned long dml_round_up(double a)
@@ -53,14 +63,18 @@ static void calculate_system_active_minimums(struct dml2_dpmm_map_mode_to_soc_dp
double min_uclk_latency, min_fclk_latency, min_dcfclk_latency;
const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result;
- min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.average_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config);
- min_uclk_avg = (double)min_uclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100);
+ min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.average_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100),
+ &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
- min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.urgent_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config);
if (in_out->display_cfg->display_config.hostvm_enable)
- min_uclk_urgent = (double)min_uclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel_and_vm / 100);
+ min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.urgent_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel_and_vm / 100),
+ &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
else
- min_uclk_urgent = (double)min_uclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100);
+ min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.urgent_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100),
+ &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg;
@@ -97,11 +111,13 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm
const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result;
/* assumes DF throttling is enabled */
- min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.average_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config);
- min_uclk_avg = (double)min_uclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_average.dram_derate_percent_pixel / 100);
+ min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.average_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_average.dram_derate_percent_pixel / 100),
+ &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
- min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config);
- min_uclk_urgent = (double)min_uclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_urgent.dram_derate_percent_pixel / 100);
+ min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_urgent.dram_derate_percent_pixel / 100),
+ &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg;
@@ -128,11 +144,13 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm
in_out->programming->min_clocks.dcn4x.svp_prefetch.dcfclk_khz = dml_round_up(min_dcfclk_bw > min_dcfclk_latency ? min_dcfclk_bw : min_dcfclk_latency);
/* assumes DF throttling is disabled */
- min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.average_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config);
- min_uclk_avg = (double)min_uclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100);
+ min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.average_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100),
+ &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
- min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config);
- min_uclk_urgent = (double)min_uclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100);
+ min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100),
+ &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg;
@@ -167,8 +185,9 @@ static void calculate_idle_minimums(struct dml2_dpmm_map_mode_to_soc_dpm_params_
double min_uclk_latency, min_fclk_latency, min_dcfclk_latency;
const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result;
- min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.average_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config);
- min_uclk_avg = (double)min_uclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_idle_average.dram_derate_percent_pixel / 100);
+ min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.average_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_idle_average.dram_derate_percent_pixel / 100),
+ &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
min_fclk_avg = (double)mode_support_result->global.active.average_bw_sdp_kbps / in_out->soc_bb->fabric_datapath_to_dcn_data_return_bytes;
min_fclk_avg = (double)min_fclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_idle_average.fclk_derate_percent / 100);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h
index 1a6c0727cd2a..a6bd75f30d20 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h
@@ -16,6 +16,7 @@
struct dram_bw_to_min_clk_table_entry {
unsigned long long pre_derate_dram_bw_kbps;
+ unsigned long min_uclk_khz;
unsigned long min_fclk_khz;
unsigned long min_dcfclk_khz;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 03/21] drm/amd/display: External panel replay fsm control
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
2026-01-28 1:51 ` [PATCH 01/21] drm/amd/display: Migrate DCCG register access from hwseq to dccg component Wayne Lin
2026-01-28 1:51 ` [PATCH 02/21] drm/amd/display: Add lpddr5 handling to dml2.1 Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 04/21] drm/amd/display: Make DCN35 OTG disable w/a reusable Wayne Lin
` (17 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Peichen Huang, Robin Chen
From: Peichen Huang <PeiChen.Huang@amd.com>
[WHY]
To correctly control external panel replay fsm.
[HOW]
1. External panel replay is 1-A option only now.
2. Update cursor update and dirty rects commands for external
panel replay support.
3. Add external panel replay support flag in dc.
Reviewed-by: Robin Chen <robin.chen@amd.com>
Signed-off-by: Peichen Huang <PeiChen.Huang@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 19 +++++--
drivers/gpu/drm/amd/display/dc/dc.h | 1 +
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 15 ++++--
drivers/gpu/drm/amd/display/dc/dc_types.h | 2 +-
.../dc/link/protocols/link_dp_panel_replay.c | 52 +++++++++++++++++++
5 files changed, 80 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index cb85b7ac2697..4305691ba45e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3860,7 +3860,7 @@ void dc_dmub_update_dirty_rect(struct dc *dc,
if (!dc_dmub_should_send_dirty_rect_cmd(dc, stream))
return;
- if (!dc_get_edp_link_panel_inst(dc, stream->link, &panel_inst))
+ if (!dc->config.frame_update_cmd_version2 && !dc_get_edp_link_panel_inst(dc, stream->link, &panel_inst))
return;
memset(&cmd, 0x0, sizeof(cmd));
@@ -3880,7 +3880,11 @@ void dc_dmub_update_dirty_rect(struct dc *dc,
if (srf_updates[i].surface->flip_immediate)
continue;
- update_dirty_rect->cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
+ if (dc->config.frame_update_cmd_version2)
+ update_dirty_rect->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_2;
+ else
+ update_dirty_rect->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_1;
+
update_dirty_rect->dirty_rect_count = flip_addr->dirty_rect_count;
memcpy(update_dirty_rect->src_dirty_rects, flip_addr->dirty_rects,
sizeof(flip_addr->dirty_rects));
@@ -3894,6 +3898,7 @@ void dc_dmub_update_dirty_rect(struct dc *dc,
update_dirty_rect->panel_inst = panel_inst;
update_dirty_rect->pipe_idx = j;
+ update_dirty_rect->otg_inst = pipe_ctx->stream_res.tg->inst;
dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
}
}
@@ -3916,7 +3921,7 @@ static void build_dmub_update_dirty_rect(
if (!dc_dmub_should_send_dirty_rect_cmd(dc, stream))
return;
- if (!dc_get_edp_link_panel_inst(dc, stream->link, &panel_inst))
+ if (!dc->config.frame_update_cmd_version2 && !dc_get_edp_link_panel_inst(dc, stream->link, &panel_inst))
return;
memset(&cmd, 0x0, sizeof(cmd));
@@ -3935,7 +3940,12 @@ static void build_dmub_update_dirty_rect(
/* Do not send in immediate flip mode */
if (srf_updates[i].surface->flip_immediate)
continue;
- update_dirty_rect->cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
+
+ if (dc->config.frame_update_cmd_version2)
+ update_dirty_rect->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_2;
+ else
+ update_dirty_rect->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_1;
+
update_dirty_rect->dirty_rect_count = flip_addr->dirty_rect_count;
memcpy(update_dirty_rect->src_dirty_rects, flip_addr->dirty_rects,
sizeof(flip_addr->dirty_rects));
@@ -3948,6 +3958,7 @@ static void build_dmub_update_dirty_rect(
continue;
update_dirty_rect->panel_inst = panel_inst;
update_dirty_rect->pipe_idx = j;
+ update_dirty_rect->otg_inst = pipe_ctx->stream_res.tg->inst;
dc_dmub_cmd[*dmub_cmd_count].dmub_cmd = cmd;
dc_dmub_cmd[*dmub_cmd_count].wait_type = DM_DMUB_WAIT_TYPE_NO_WAIT;
(*dmub_cmd_count)++;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index ab19b6230945..ce2eceba2ab7 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -560,6 +560,7 @@ struct dc_config {
bool enable_dpia_pre_training;
bool unify_link_enc_assignment;
bool enable_cursor_offload;
+ bool frame_update_cmd_version2;
struct spl_sharpness_range dcn_sharpness_range;
struct spl_sharpness_range dcn_override_sharpness_range;
};
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index dc1b3f6c22c9..e4dd5ca70987 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -1034,12 +1034,19 @@ static void dc_build_cursor_update_payload0(
struct pipe_ctx *pipe_ctx, uint8_t p_idx,
struct dmub_cmd_update_cursor_payload0 *payload)
{
+ struct dc *dc = pipe_ctx->stream->ctx->dc;
struct hubp *hubp = pipe_ctx->plane_res.hubp;
unsigned int panel_inst = 0;
- if (!dc_get_edp_link_panel_inst(hubp->ctx->dc,
- pipe_ctx->stream->link, &panel_inst))
- return;
+ if (dc->config.frame_update_cmd_version2 == true) {
+ /* Don't need panel_inst for command version2 */
+ payload->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_2;
+ } else {
+ if (!dc_get_edp_link_panel_inst(hubp->ctx->dc,
+ pipe_ctx->stream->link, &panel_inst))
+ return;
+ payload->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_1;
+ }
/* Payload: Cursor Rect is built from position & attribute
* x & y are obtained from postion
@@ -1052,8 +1059,8 @@ static void dc_build_cursor_update_payload0(
payload->enable = hubp->pos.cur_ctl.bits.cur_enable;
payload->pipe_idx = p_idx;
- payload->cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
payload->panel_inst = panel_inst;
+ payload->otg_inst = pipe_ctx->stream_res.tg->inst;
}
static void dc_build_cursor_position_update_payload0(
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 0e953059ff6d..2e38b6840c71 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -1230,7 +1230,7 @@ struct replay_settings {
uint32_t replay_desync_error_fail_count;
/* The frame skip number dal send to DMUB */
uint16_t frame_skip_number;
- /* Current Panel Replay event */
+ /* Current Panel Replay events */
uint32_t replay_events;
};
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c
index bbd6f93f5c98..cc3b44cf7662 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c
@@ -35,6 +35,46 @@
#define DP_SINK_PR_ENABLE_AND_CONFIGURATION 0x37B
+static unsigned int dp_pr_calc_num_static_frames(unsigned int vsync_rate_hz)
+{
+ // at least 2 frames for static screen
+ unsigned int num_frames = 2;
+
+ // get number of frames for at least 50ms
+ if (vsync_rate_hz > 40)
+ num_frames = (vsync_rate_hz + 10) / 20;
+
+ return num_frames;
+}
+
+static void dp_pr_set_static_screen_param(struct dc_link *link)
+{
+ struct dc_static_screen_params params = {0};
+ struct dc *dc = link->ctx->dc;
+ // only support DP sst for now
+ if (!dc_is_dp_sst_signal(link->connector_signal))
+ return;
+
+ for (int i = 0; i < MAX_PIPES; i++) {
+ if (dc->current_state->res_ctx.pipe_ctx[i].stream &&
+ dc->current_state->res_ctx.pipe_ctx[i].stream->link == link) {
+ struct dc_stream_state *stream = dc->current_state->res_ctx.pipe_ctx[i].stream;
+ unsigned int vsync_rate_hz = div64_u64(div64_u64(
+ (stream->timing.pix_clk_100hz * (u64)100),
+ stream->timing.v_total),
+ stream->timing.h_total);
+
+ params.triggers.cursor_update = true;
+ params.triggers.overlay_update = true;
+ params.triggers.surface_update = true;
+ params.num_frames = dp_pr_calc_num_static_frames(vsync_rate_hz);
+
+ dc_stream_set_static_screen_params(dc, &stream, 1, ¶ms);
+ break;
+ }
+ }
+}
+
static bool dp_setup_panel_replay(struct dc_link *link, const struct dc_stream_state *stream)
{
/* To-do: Setup Replay */
@@ -159,6 +199,9 @@ bool dp_pr_get_panel_inst(const struct dc *dc,
if (!dc || !link || !inst_out)
return false;
+ if (dc->config.frame_update_cmd_version2 == false)
+ return dc_get_edp_link_panel_inst(dc, link, inst_out);
+
if (!dc_is_dp_sst_signal(link->connector_signal)) /* only supoprt DP sst (eDP included) for now */
return false;
@@ -199,6 +242,9 @@ bool dp_pr_enable(struct dc_link *link, bool enable)
if (!dp_pr_get_panel_inst(dc, link, &panel_inst))
return false;
+ if (enable && !dc_is_embedded_signal(link->connector_signal))
+ dp_pr_set_static_screen_param(link);
+
if (link->replay_settings.replay_allow_active != enable) {
//for sending PR enable commands to DMUB
memset(&cmd, 0, sizeof(cmd));
@@ -276,6 +322,12 @@ bool dp_pr_copy_settings(struct dc_link *link, struct replay_context *replay_con
pipe_ctx->stream->timing.v_border_top + pipe_ctx->stream->timing.v_border_bottom) /
pipe_ctx->stream->timing.dsc_cfg.num_slices_v;
+ if (dc_is_embedded_signal(link->connector_signal))
+ cmd.pr_copy_settings.data.main_link_activity_option = 0x03;//OPTION_1C;
+ else
+ // For external DP, use option 1-A
+ cmd.pr_copy_settings.data.main_link_activity_option = 0x01;//OPTION_1A;
+
dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
return true;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 04/21] drm/amd/display: Make DCN35 OTG disable w/a reusable
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (2 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 03/21] drm/amd/display: External panel replay fsm control Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 05/21] drm/amd/display: Make DSC FGCG a DSC block level function Wayne Lin
` (16 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Nicholas Kazlauskas, Ovidiu Bunea
From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
The logic for the OTG disable workaround is particularly complex and
should be leveraged going forward instead of reimplementing and
maintaining it for multiple ASIC.
Reviewed-by: Ovidiu Bunea <ovidiu.bunea@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 2 +-
.../gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h | 6 ++++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
index 72558cc55a9a..7abe6811e4df 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
@@ -186,7 +186,7 @@ static int dcn35_get_active_display_cnt_wa(
return display_count;
}
-static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context,
+void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context,
bool safe_to_lower, bool disable)
{
struct dc *dc = clk_mgr_base->ctx->dc;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h
index a12a9bf90806..83e2263563fe 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h
@@ -64,4 +64,10 @@ void dcn351_clk_mgr_construct(struct dc_context *ctx,
struct clk_mgr_dcn35 *clk_mgr,
struct pp_smu_funcs *pp_smu,
struct dccg *dccg);
+
+void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base,
+ struct dc_state *context,
+ bool safe_to_lower,
+ bool disable);
+
#endif //__DCN35_CLK_MGR_H__
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 05/21] drm/amd/display: Make DSC FGCG a DSC block level function
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (3 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 04/21] drm/amd/display: Make DCN35 OTG disable w/a reusable Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 06/21] drm/amd/display: Make some DCN35 DCCG symbols non-static Wayne Lin
` (15 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Nicholas Kazlauskas, Dillon Varone
From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
[Why]
FGCG shouldn't be called at the DC resource level as part of DSC
creation because dc_create is intended for SW init, not HW init, and
register access is not guaranteed to work at this phase.
[How]
Add a set_fgcg function at the DSC interface level.
Existing ASIC can continue using the function in DC resource to retain
current compatibility but further development should favor calling
the function pointer during init_hw (if it exists).
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/dsc/dsc.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dsc.h b/drivers/gpu/drm/amd/display/dc/dsc/dsc.h
index 81c83d5fe042..ad7ef83694ea 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dsc.h
@@ -115,6 +115,7 @@ struct dsc_funcs {
void (*dsc_disconnect)(struct display_stream_compressor *dsc);
void (*dsc_wait_disconnect_pending_clear)(struct display_stream_compressor *dsc);
void (*dsc_get_single_enc_caps)(struct dsc_enc_caps *dsc_enc_caps, unsigned int max_dscclk_khz);
+ void (*set_fgcg)(struct display_stream_compressor *dsc, bool enable);
};
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 06/21] drm/amd/display: Make some DCN35 DCCG symbols non-static
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (4 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 05/21] drm/amd/display: Make DSC FGCG a DSC block level function Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 07/21] drm/amd/display: Fix writeback on DCN 3.2+ Wayne Lin
` (14 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Nicholas Kazlauskas, Ovidiu Bunea
From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
In order to have few DCN35 functions be leveraged for future ASIC
implementations. Expose them to the dcn35_dccg.h header.
Reviewed-by: Ovidiu Bunea <ovidiu.bunea@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../amd/display/dc/dccg/dcn35/dcn35_dccg.c | 30 +++++++------------
.../amd/display/dc/dccg/dcn35/dcn35_dccg.h | 17 +++++++++++
2 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
index bd2f528137b2..838c6617c029 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
@@ -1105,7 +1105,7 @@ static void dccg35_enable_dpstreamclk_new(struct dccg *dccg,
dccg35_set_dpstreamclk_src_new(dccg, src, inst);
}
-static void dccg35_trigger_dio_fifo_resync(struct dccg *dccg)
+void dccg35_trigger_dio_fifo_resync(struct dccg *dccg)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
uint32_t dispclk_rdivider_value = 0;
@@ -1114,6 +1114,7 @@ static void dccg35_trigger_dio_fifo_resync(struct dccg *dccg)
if (dispclk_rdivider_value != 0)
REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value);
}
+
static void dccg35_wait_for_dentist_change_done(
struct dccg *dccg)
{
@@ -1151,8 +1152,7 @@ static void dcn35_set_dppclk_enable(struct dccg *dccg,
}
-static void dccg35_update_dpp_dto(struct dccg *dccg, int dpp_inst,
- int req_dppclk)
+void dccg35_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
@@ -1498,11 +1498,7 @@ static void dccg35_set_dpstreamclk(
__func__, dp_hpo_inst, (src == REFCLK) ? 0 : 1, otg_inst);
}
-
-static void dccg35_set_dpstreamclk_root_clock_gating(
- struct dccg *dccg,
- int dp_hpo_inst,
- bool enable)
+void dccg35_set_dpstreamclk_root_clock_gating(struct dccg *dccg, int dp_hpo_inst, bool enable)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
@@ -1669,10 +1665,7 @@ static void dccg35_set_valid_pixel_rate(
dccg35_set_dtbclk_dto(dccg, &dto_params);
}
-static void dccg35_dpp_root_clock_control(
- struct dccg *dccg,
- unsigned int dpp_inst,
- bool clock_on)
+void dccg35_dpp_root_clock_control(struct dccg *dccg, unsigned int dpp_inst, bool clock_on)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
@@ -1704,9 +1697,7 @@ static void dccg35_dpp_root_clock_control(
DC_LOG_DEBUG("%s: dpp_inst(%d) clock_on = %d\n", __func__, dpp_inst, clock_on);
}
-static void dccg35_disable_symclk32_se(
- struct dccg *dccg,
- int hpo_se_inst)
+void dccg35_disable_symclk32_se(struct dccg *dccg, int hpo_se_inst)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
@@ -1813,7 +1804,7 @@ void dccg35_enable_global_fgcg_rep(struct dccg *dccg, bool value)
REG_UPDATE(DCCG_GLOBAL_FGCG_REP_CNTL, DCCG_GLOBAL_FGCG_REP_DIS, !value);
}
-static void dccg35_enable_dscclk(struct dccg *dccg, int inst)
+void dccg35_enable_dscclk(struct dccg *dccg, int inst)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
@@ -1860,8 +1851,7 @@ static void dccg35_enable_dscclk(struct dccg *dccg, int inst)
udelay(10);
}
-static void dccg35_disable_dscclk(struct dccg *dccg,
- int inst)
+void dccg35_disable_dscclk(struct dccg *dccg, int inst)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
@@ -1906,7 +1896,7 @@ static void dccg35_disable_dscclk(struct dccg *dccg,
udelay(10);
}
-static void dccg35_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
+void dccg35_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
@@ -2013,7 +2003,7 @@ static uint8_t dccg35_get_number_enabled_symclk_fe_connected_to_be(struct dccg *
return num_enabled_symclk_fe;
}
-static void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
+void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst)
{
uint8_t num_enabled_symclk_fe = 0;
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h
index 7b9c36456cd9..554700287c1a 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h
@@ -249,8 +249,25 @@ struct dccg *dccg35_create(
void dccg35_init(struct dccg *dccg);
+void dccg35_trigger_dio_fifo_resync(struct dccg *dccg);
+
+void dccg35_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk);
+
void dccg35_enable_global_fgcg_rep(struct dccg *dccg, bool value);
void dccg35_root_gate_disable_control(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating);
+void dccg35_set_dpstreamclk_root_clock_gating(struct dccg *dccg, int dp_hpo_inst, bool enable);
+
+void dccg35_set_hdmistreamclk_root_clock_gating(struct dccg *dccg, bool enable);
+
+void dccg35_dpp_root_clock_control(struct dccg *dccg, unsigned int dpp_inst, bool clock_on);
+
+void dccg35_disable_symclk32_se(struct dccg *dccg, int hpo_se_inst);
+
+void dccg35_enable_dscclk(struct dccg *dccg, int inst);
+void dccg35_disable_dscclk(struct dccg *dccg, int inst);
+
+void dccg35_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst);
+void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst);
#endif //__DCN35_DCCG_H__
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 07/21] drm/amd/display: Fix writeback on DCN 3.2+
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (5 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 06/21] drm/amd/display: Make some DCN35 DCCG symbols non-static Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 08/21] drm/amd/display: Fix IGT link training failure on Replay panel Wayne Lin
` (13 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung
From: Alex Hung <alex.hung@amd.com>
[WHAT]
1. Set no scaling for writeback as they are hardcoded in DCN3.2+.
2. Set no fast plane update for writeback commits.
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index d8fac7e69181..572998eadb78 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10658,10 +10658,10 @@ static void dm_set_writeback(struct amdgpu_display_manager *dm,
wb_info->dwb_params.capture_rate = dwb_capture_rate_0;
- wb_info->dwb_params.scaler_taps.h_taps = 4;
- wb_info->dwb_params.scaler_taps.v_taps = 4;
- wb_info->dwb_params.scaler_taps.h_taps_c = 2;
- wb_info->dwb_params.scaler_taps.v_taps_c = 2;
+ wb_info->dwb_params.scaler_taps.h_taps = 1;
+ wb_info->dwb_params.scaler_taps.v_taps = 1;
+ wb_info->dwb_params.scaler_taps.h_taps_c = 1;
+ wb_info->dwb_params.scaler_taps.v_taps_c = 1;
wb_info->dwb_params.subsample_position = DWB_INTERSTITIAL_SUBSAMPLING;
wb_info->mcif_buf_params.luma_pitch = afb->base.pitches[0];
@@ -11677,6 +11677,8 @@ static bool should_reset_plane(struct drm_atomic_state *state,
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
struct dm_crtc_state *old_dm_crtc_state, *new_dm_crtc_state;
struct amdgpu_device *adev = drm_to_adev(plane->dev);
+ struct drm_connector_state *new_con_state;
+ struct drm_connector *connector;
int i;
/*
@@ -11687,6 +11689,15 @@ static bool should_reset_plane(struct drm_atomic_state *state,
state->allow_modeset)
return true;
+ /* Check for writeback commit */
+ for_each_new_connector_in_state(state, connector, new_con_state, i) {
+ if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
+ continue;
+
+ if (new_con_state->writeback_job)
+ return true;
+ }
+
if (amdgpu_in_reset(adev) && state->allow_modeset)
return true;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 08/21] drm/amd/display: Fix IGT link training failure on Replay panel
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (6 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 07/21] drm/amd/display: Fix writeback on DCN 3.2+ Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 09/21] drm/amd/display: Fix system resume lag issue Wayne Lin
` (12 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Ray Wu
From: Ray Wu <ray.wu@amd.com>
[Why]
IGT link-training-configs test fails to set the link rate on Replay panels
because some link rate types are not supported in debugfs. As a result,
debugfs treats these link rates as invalid, causing the IGT test to fail.
[How]
Add missing link rate types to resolve this issue.
Reviewed-by: ChiaHsuan Chung <chiahsuan.chung@amd.com>
Signed-off-by: Ray Wu <ray.wu@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index b9ed29ec60dc..5fb573214f18 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -302,8 +302,11 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
switch (param[1]) {
case LINK_RATE_LOW:
+ case LINK_RATE_RATE_2:
+ case LINK_RATE_RATE_3:
case LINK_RATE_HIGH:
case LINK_RATE_RBR2:
+ case LINK_RATE_RATE_6:
case LINK_RATE_HIGH2:
case LINK_RATE_HIGH3:
case LINK_RATE_UHBR10:
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 09/21] drm/amd/display: Fix system resume lag issue
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (7 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 08/21] drm/amd/display: Fix IGT link training failure on Replay panel Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 10/21] drm/amd/display: Add oem panel config for new features Wayne Lin
` (11 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Nicholas Kazlauskas
From: Tom Chung <chiahsuan.chung@amd.com>
[Why]
System will try to apply idle power optimizations setting during
system resume. But system power state is still in D3 state, and
it will cause the idle power optimizations command not actually
to be sent to DMUB and cause some platforms to go into IPS.
[How]
Set power state to D0 first before calling the
dc_dmub_srv_apply_idle_power_optimizations(dm->dc, false)
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 572998eadb78..fcc48994c3e3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3481,6 +3481,11 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
struct dc_commit_streams_params commit_params = {};
if (dm->dc->caps.ips_support) {
+ /* Need to set POWER_STATE_D0 first or it will not execute
+ * idle_power_optimizations command to DMUB.
+ */
+ guard(mutex)(&dm->dc_lock);
+ dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D0);
dc_dmub_srv_apply_idle_power_optimizations(dm->dc, false);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 10/21] drm/amd/display: Add oem panel config for new features
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (8 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 09/21] drm/amd/display: Fix system resume lag issue Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 11/21] drm/amd/display: Fix IGT ILR link training failure on Replay panel Wayne Lin
` (10 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Ian Chen, Robin Chen
From: Ian Chen <ian.chen@amd.com>
[WHAT]
Add oem panel config for below features:
- CACP_v2
- Adaptive VariBright
- Replay_FrameSkipping
- Replay_teamsOpt
- Ramless Idle Opt
Reviewed-by: Robin Chen <robin.chen@amd.com>
Signed-off-by: Ian Chen <ian.chen@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/dc_types.h | 25 ++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 2e38b6840c71..bddb16bb76d4 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -1256,7 +1256,7 @@ struct dc_panel_config {
unsigned int max_nonboost_brightness_millinits;
unsigned int min_brightness_millinits;
} nits_brightness;
- /* PSR */
+ /* PSR/Replay */
struct psr {
bool disable_psr;
bool disallow_psrsu;
@@ -1266,6 +1266,8 @@ struct dc_panel_config {
bool rc_allow_fullscreen_VPB;
bool read_psrcap_again;
unsigned int replay_enable_option;
+ bool enable_frame_skipping;
+ bool enable_teams_optimization;
} psr;
/* ABM */
struct varib {
@@ -1282,6 +1284,27 @@ struct dc_panel_config {
struct ilr {
bool optimize_edp_link_rate; /* eDP ILR */
} ilr;
+ /* Adaptive VariBright*/
+ struct adaptive_vb {
+ bool disable_adaptive_vb;
+ unsigned int default_abm_vb_levels; // default value = 0xDCAA6414
+ unsigned int default_cacp_vb_levels;
+ unsigned int default_abm_vb_hdr_levels; // default value = 0xB4805A40
+ unsigned int default_cacp_vb_hdr_levels;
+ unsigned int abm_scaling_factors; // default value = 0x23210012
+ unsigned int cacp_scaling_factors;
+ unsigned int battery_life_configures; // default value = 0x0A141E
+ unsigned int abm_backlight_adaptive_pwl_1; // default value = 0x6A4F7244
+ unsigned int abm_backlight_adaptive_pwl_2; // default value = 0x4C615659
+ unsigned int abm_backlight_adaptive_pwl_3; // default value = 0x0064
+ unsigned int cacp_backlight_adaptive_pwl_1;
+ unsigned int cacp_backlight_adaptive_pwl_2;
+ unsigned int cacp_backlight_adaptive_pwl_3;
+ } adaptive_vb;
+ /* Ramless Idle Opt*/
+ struct rio {
+ bool disable_rio;
+ } rio;
};
#define MAX_SINKS_PER_LINK 4
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 11/21] drm/amd/display: Fix IGT ILR link training failure on Replay panel
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (9 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 10/21] drm/amd/display: Add oem panel config for new features Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 12/21] drm/amd/display: Fix a NULL pointer dereference in dcn20_hwseq.c Wayne Lin
` (9 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Ray Wu
From: Ray Wu <ray.wu@amd.com>
[Why & How]
Fix the IGT ilr_link-training-configs test failure
by directly using the supported link rates from DPCD.
Reviewed-by: ChiaHsuan Chung <chiahsuan.chung@amd.com>
Signed-off-by: Ray Wu <ray.wu@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 21 ++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 5fb573214f18..cfe35442dfcb 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -46,6 +46,7 @@
#include "amdgpu_dm_psr.h"
#endif
+#define MULTIPLIER_TO_LR 270000
struct dmub_debugfs_trace_header {
uint32_t entry_count;
uint32_t reserved[3];
@@ -3507,6 +3508,10 @@ static ssize_t edp_ilr_write(struct file *f, const char __user *buf,
uint8_t param_nums = 0;
long param[2];
bool valid_input = true;
+ uint8_t supported_link_rates[16] = {0};
+ uint32_t entry = 0;
+ uint32_t link_rate_in_khz = 0;
+ uint8_t dpcd_rev = 0;
if (size == 0)
return -EINVAL;
@@ -3551,6 +3556,20 @@ static ssize_t edp_ilr_write(struct file *f, const char __user *buf,
return size;
}
+ if (!dm_helpers_dp_read_dpcd(link->ctx, link, DP_SUPPORTED_LINK_RATES,
+ supported_link_rates, sizeof(supported_link_rates)))
+ return -EINVAL;
+
+ dpcd_rev = link->dpcd_caps.dpcd_rev.raw;
+ if (dpcd_rev < DP_DPCD_REV_13 ||
+ (supported_link_rates[entry + 1] == 0 && supported_link_rates[entry] == 0)) {
+ return size;
+ }
+
+ entry = param[1] * 2;
+ link_rate_in_khz = (supported_link_rates[entry + 1] * 0x100 +
+ supported_link_rates[entry]) * 200;
+
/* save user force lane_count, link_rate to preferred settings
* spread spectrum will not be changed
*/
@@ -3558,7 +3577,7 @@ static ssize_t edp_ilr_write(struct file *f, const char __user *buf,
prefer_link_settings.lane_count = param[0];
prefer_link_settings.use_link_rate_set = true;
prefer_link_settings.link_rate_set = param[1];
- prefer_link_settings.link_rate = link->dpcd_caps.edp_supported_link_rates[param[1]];
+ prefer_link_settings.link_rate = link_rate_in_khz / MULTIPLIER_TO_LR;
mutex_lock(&adev->dm.dc_lock);
dc_link_set_preferred_training_settings(dc, &prefer_link_settings,
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 12/21] drm/amd/display: Fix a NULL pointer dereference in dcn20_hwseq.c
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (10 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 11/21] drm/amd/display: Fix IGT ILR link training failure on Replay panel Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 13/21] drm/amd/display: Add Gfx Base Case For Linear Tiling Handling Wayne Lin
` (8 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Wenjing Liu, Nicholas Kazlauskas
From: Wenjing Liu <wenjing.liu@amd.com>
[why]
hws->funcs.dccg_init is accessed without checking if it is NULL, which
may lead to a NULL pointer dereference.
[how]
Add a NULL check before calling dccg_init.
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
index 87a1dc27def4..307e8f8060e6 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -3140,7 +3140,8 @@ void dcn20_fpga_init_hw(struct dc *dc)
dcn10_hubbub_global_timer_enable(dc->res_pool->hubbub, true, 2);
- hws->funcs.dccg_init(hws);
+ if (hws->funcs.dccg_init)
+ hws->funcs.dccg_init(hws);
if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->refclk_setup)
dc->res_pool->dccg->funcs->refclk_setup(dc->res_pool->dccg);
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 13/21] drm/amd/display: Add Gfx Base Case For Linear Tiling Handling
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (11 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 12/21] drm/amd/display: Fix a NULL pointer dereference in dcn20_hwseq.c Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-02-16 15:16 ` Timur Kristóf
2026-01-28 1:51 ` [PATCH 14/21] drm/amd/display: Migrate DIO registers access from hwseq to dio component Wayne Lin
` (7 subsequent siblings)
20 siblings, 1 reply; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Nicholas Carbones, Dillon Varone
From: Nicholas Carbones <ncarbone@amd.com>
[Why]
Post-driver cases always use linear tiling yet there is no dedicated
Gfx handling for this condition.
[How]
Add DcGfxBase/DalGfxBase to gfx version enums and set tiling to linear
when it is used. Also, enforce the use of proper tiling format as tiling
information is used.
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Nicholas Carbones <ncarbone@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 +
drivers/gpu/drm/amd/display/dc/core/dc.c | 1 +
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 7 +++++++
drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 1 +
drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 3 ++-
drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c | 3 +++
drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c | 3 +++
drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c | 1 +
drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c | 2 ++
drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c | 2 ++
drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c | 2 ++
drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c | 7 ++++++-
.../amd/display/dc/resource/dcn32/dcn32_resource_helpers.c | 3 ++-
13 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index fcc48994c3e3..333ff8557732 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8033,6 +8033,7 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc,
dc_plane_state->plane_size.chroma_size.height = stream->src.height;
dc_plane_state->plane_size.chroma_size.width = stream->src.width;
dc_plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB8888;
+ dc_plane_state->tiling_info.gfxversion = DcGfxVersion9;
dc_plane_state->tiling_info.gfx9.swizzle = DC_SW_UNKNOWN;
dc_plane_state->rotation = ROTATION_ANGLE_0;
dc_plane_state->is_tiling_rotated = false;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 4305691ba45e..441b7e0a3b22 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2768,6 +2768,7 @@ static struct surface_update_descriptor get_plane_info_update_type(const struct
case DcGfxVersion7:
case DcGfxVersion8:
case DcGfxVersionUnknown:
+ case DcGfxBase:
default:
break;
}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 052d573408c3..a13d9d7dd6c5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -2065,6 +2065,13 @@ void get_surface_tile_visual_confirm_color(
while (bottom_pipe_ctx->bottom_pipe != NULL)
bottom_pipe_ctx = bottom_pipe_ctx->bottom_pipe;
+ if (bottom_pipe_ctx->plane_state->tiling_info.gfxversion == DcGfxBase) {
+ /* LINEAR Surface - set border color to red */
+ color->color_r_cr = color_value;
+ return;
+ }
+
+ ASSERT(bottom_pipe_ctx->plane_state->tiling_info.gfxversion == DcGfxVersion9);
switch (bottom_pipe_ctx->plane_state->tiling_info.gfx9.swizzle) {
case DC_SW_LINEAR:
/* LINEAR Surface - set border color to red */
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 848c267ef11e..b4e5a79e9749 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -4434,6 +4434,7 @@ enum dc_status dc_validate_global_state(
if (dc->res_pool->funcs->patch_unknown_plane_state &&
pipe_ctx->plane_state &&
+ pipe_ctx->plane_state->tiling_info.gfxversion == DcGfxVersion9 &&
pipe_ctx->plane_state->tiling_info.gfx9.swizzle == DC_SW_UNKNOWN) {
result = dc->res_pool->funcs->patch_unknown_plane_state(pipe_ctx->plane_state);
if (result != DC_OK)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index cfa569a7bff1..7121629da38e 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -342,7 +342,8 @@ enum swizzle_mode_addr3_values {
};
enum dc_gfxversion {
- DcGfxVersion7 = 0,
+ DcGfxBase = 0,
+ DcGfxVersion7,
DcGfxVersion8,
DcGfxVersion9,
DcGfxVersion10,
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
index 1c2009e38aa1..5df58fadc862 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
@@ -100,6 +100,7 @@ static enum mi_bits_per_pixel get_mi_bpp(
static enum mi_tiling_format get_mi_tiling(
struct dc_tiling_info *tiling_info)
{
+ ASSERT(tiling_info->gfxversion == DcGfxVersion8);
switch (tiling_info->gfx8.array_mode) {
case DC_ARRAY_1D_TILED_THIN1:
case DC_ARRAY_1D_TILED_THICK:
@@ -433,6 +434,7 @@ static void program_tiling(
struct dce_mem_input *dce_mi, const struct dc_tiling_info *info)
{
if (dce_mi->masks->GRPH_SW_MODE) { /* GFX9 */
+ ASSERT(info->gfxversion == DcGfxVersion9);
REG_UPDATE_6(GRPH_CONTROL,
GRPH_SW_MODE, info->gfx9.swizzle,
GRPH_NUM_BANKS, log_2(info->gfx9.num_banks),
@@ -447,6 +449,7 @@ static void program_tiling(
}
if (dce_mi->masks->GRPH_MICRO_TILE_MODE) { /* GFX8 */
+ ASSERT(info->gfxversion == DcGfxVersion8);
REG_UPDATE_9(GRPH_CONTROL,
GRPH_NUM_BANKS, info->gfx8.num_banks,
GRPH_BANK_WIDTH, info->gfx8.bank_width,
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
index 2c43c2422638..67cfca3361fb 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
@@ -165,6 +165,8 @@ static void program_tiling(
const struct dc_tiling_info *info,
const enum surface_pixel_format pixel_format)
{
+ ASSERT(info->gfxversion == DcGfxVersion8);
+
uint32_t value = 0;
set_reg_field_value(value, info->gfx8.num_banks,
@@ -541,6 +543,7 @@ static const unsigned int *get_dvmm_hw_setting(
else
bpp = bpp_8;
+ ASSERT(tiling_info->gfxversion == DcGfxVersion8);
switch (tiling_info->gfx8.array_mode) {
case DC_ARRAY_1D_TILED_THIN1:
case DC_ARRAY_1D_TILED_THICK:
diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
index 74962791302f..71eeee02c0fa 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
@@ -1006,6 +1006,7 @@ bool dcn_validate_bandwidth(
v->source_pixel_format[input_idx] = tl_pixel_format_to_bw_defs(
pipe->plane_state->format);
+ ASSERT(pipe->plane_state->tiling_info.gfxversion == DcGfxVersion9);
v->source_surface_mode[input_idx] = tl_sw_mode_to_bw_defs(
pipe->plane_state->tiling_info.gfx9.swizzle);
v->lb_bit_per_pixel[input_idx] = tl_lb_bpp_to_int(pipe->plane_res.scl_data.lb_params.depth);
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
index 6378e3fd7249..e697d9bf1b44 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
@@ -145,6 +145,8 @@ void hubp1_program_tiling(
{
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+ ASSERT(info->gfxversion == DcGfxVersion9);
+
REG_UPDATE_6(DCSURF_ADDR_CONFIG,
NUM_PIPES, log_2(info->gfx9.num_pipes),
NUM_BANKS, log_2(info->gfx9.num_banks),
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
index 92288de4cc10..4715e60e812a 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
@@ -313,6 +313,8 @@ static void hubp2_program_tiling(
const struct dc_tiling_info *info,
const enum surface_pixel_format pixel_format)
{
+ ASSERT(info->gfxversion == DcGfxVersion9);
+
REG_UPDATE_3(DCSURF_ADDR_CONFIG,
NUM_PIPES, log_2(info->gfx9.num_pipes),
PIPE_INTERLEAVE, info->gfx9.pipe_interleave,
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c
index 0cc6f4558989..207c2f86b7d7 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c
@@ -321,6 +321,8 @@ void hubp3_program_tiling(
const struct dc_tiling_info *info,
const enum surface_pixel_format pixel_format)
{
+ ASSERT(info->gfxversion == DcGfxVersion9);
+
REG_UPDATE_4(DCSURF_ADDR_CONFIG,
NUM_PIPES, log_2(info->gfx9.num_pipes),
PIPE_INTERLEAVE, info->gfx9.pipe_interleave,
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
index c205500290ec..861e940250af 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
@@ -589,7 +589,12 @@ void hubp401_program_tiling(
*
* DIM_TYPE field in DCSURF_TILING for Display is always 1 (2D dimension) which is HW default.
*/
- REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, info->gfx_addr3.swizzle);
+ if (info->gfxversion == DcGfxAddr3) {
+ REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, info->gfx_addr3.swizzle);
+ } else {
+ /* linear */
+ REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, 0);
+ }
}
void hubp401_program_size(
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c
index f5a4e97c40ce..7d99f5d79e6d 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c
@@ -401,7 +401,8 @@ void dcn32_set_det_allocations(struct dc *dc, struct dc_state *context,
*/
if (pipe_cnt == 1) {
pipes[0].pipe.src.det_size_override = DCN3_2_MAX_DET_SIZE;
- if (pipe->plane_state && !disable_unbounded_requesting && pipe->plane_state->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
+ if (pipe->plane_state && !disable_unbounded_requesting && pipe->plane_state->tiling_info.gfxversion != DcGfxBase &&
+ !(pipe->plane_state->tiling_info.gfxversion == DcGfxVersion9 && pipe->plane_state->tiling_info.gfx9.swizzle == DC_SW_LINEAR)) {
if (!is_dual_plane(pipe->plane_state->format)) {
pipes[0].pipe.src.det_size_override = DCN3_2_DEFAULT_DET_SIZE;
pipes[0].pipe.src.unbounded_req_mode = true;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH 13/21] drm/amd/display: Add Gfx Base Case For Linear Tiling Handling
2026-01-28 1:51 ` [PATCH 13/21] drm/amd/display: Add Gfx Base Case For Linear Tiling Handling Wayne Lin
@ 2026-02-16 15:16 ` Timur Kristóf
0 siblings, 0 replies; 23+ messages in thread
From: Timur Kristóf @ 2026-02-16 15:16 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Nicholas Carbones, Dillon Varone, Wayne Lin
On 2026. január 28., szerda 2:51:38 közép-európai téli idő Wayne Lin wrote:
> From: Nicholas Carbones <ncarbone@amd.com>
>
> [Why]
> Post-driver cases always use linear tiling yet there is no dedicated
> Gfx handling for this condition.
>
> [How]
> Add DcGfxBase/DalGfxBase to gfx version enums and set tiling to linear
> when it is used. Also, enforce the use of proper tiling format as tiling
> information is used.
>
> Reviewed-by: Dillon Varone <dillon.varone@amd.com>
> Signed-off-by: Nicholas Carbones <ncarbone@amd.com>
> Signed-off-by: Wayne Lin <wayne.lin@amd.com>
> ---
> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 +
> drivers/gpu/drm/amd/display/dc/core/dc.c | 1 +
> drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 7 +++++++
> drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 1 +
> drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 3 ++-
> drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c | 3 +++
> drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c | 3 +++
> drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c | 1 +
> drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c | 2 ++
> drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c | 2 ++
> drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c | 2 ++
> drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c | 7 ++++++-
> .../amd/display/dc/resource/dcn32/dcn32_resource_helpers.c | 3 ++-
> 13 files changed, 33 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index
> fcc48994c3e3..333ff8557732 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -8033,6 +8033,7 @@ static enum dc_status
> dm_validate_stream_and_context(struct dc *dc,
> dc_plane_state->plane_size.chroma_size.height = stream->src.height;
> dc_plane_state->plane_size.chroma_size.width = stream->src.width;
> dc_plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB8888;
> + dc_plane_state->tiling_info.gfxversion = DcGfxVersion9;
> dc_plane_state->tiling_info.gfx9.swizzle = DC_SW_UNKNOWN;
> dc_plane_state->rotation = ROTATION_ANGLE_0;
> dc_plane_state->is_tiling_rotated = false;
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c
> b/drivers/gpu/drm/amd/display/dc/core/dc.c index 4305691ba45e..441b7e0a3b22
> 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -2768,6 +2768,7 @@ static struct surface_update_descriptor
> get_plane_info_update_type(const struct case DcGfxVersion7:
> case DcGfxVersion8:
> case DcGfxVersionUnknown:
> + case DcGfxBase:
> default:
> break;
> }
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
> b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c index
> 052d573408c3..a13d9d7dd6c5 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
> @@ -2065,6 +2065,13 @@ void get_surface_tile_visual_confirm_color(
> while (bottom_pipe_ctx->bottom_pipe != NULL)
> bottom_pipe_ctx = bottom_pipe_ctx->bottom_pipe;
>
> + if (bottom_pipe_ctx->plane_state->tiling_info.gfxversion ==
DcGfxBase) {
> + /* LINEAR Surface - set border color to red */
> + color->color_r_cr = color_value;
> + return;
> + }
> +
> + ASSERT(bottom_pipe_ctx->plane_state->tiling_info.gfxversion ==
> DcGfxVersion9); switch
> (bottom_pipe_ctx->plane_state->tiling_info.gfx9.swizzle) { case
> DC_SW_LINEAR:
> /* LINEAR Surface - set border color to red */
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index
> 848c267ef11e..b4e5a79e9749 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> @@ -4434,6 +4434,7 @@ enum dc_status dc_validate_global_state(
>
> if (dc->res_pool->funcs-
>patch_unknown_plane_state &&
> pipe_ctx->plane_state
&&
> + pipe_ctx->plane_state-
>tiling_info.gfxversion == DcGfxVersion9 &&
> pipe_ctx->plane_state-
>tiling_info.gfx9.swizzle == DC_SW_UNKNOWN) {
> result =
> dc->res_pool->funcs->patch_unknown_plane_state(pipe_ctx->plane_state); if
> (result != DC_OK)
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
> b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index
> cfa569a7bff1..7121629da38e 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
> @@ -342,7 +342,8 @@ enum swizzle_mode_addr3_values {
> };
>
> enum dc_gfxversion {
> - DcGfxVersion7 = 0,
> + DcGfxBase = 0,
> + DcGfxVersion7,
> DcGfxVersion8,
> DcGfxVersion9,
> DcGfxVersion10,
> diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
> b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c index
> 1c2009e38aa1..5df58fadc862 100644
> --- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
> +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
> @@ -100,6 +100,7 @@ static enum mi_bits_per_pixel get_mi_bpp(
> static enum mi_tiling_format get_mi_tiling(
> struct dc_tiling_info *tiling_info)
> {
> + ASSERT(tiling_info->gfxversion == DcGfxVersion8);
> switch (tiling_info->gfx8.array_mode) {
> case DC_ARRAY_1D_TILED_THIN1:
> case DC_ARRAY_1D_TILED_THICK:
> @@ -433,6 +434,7 @@ static void program_tiling(
> struct dce_mem_input *dce_mi, const struct dc_tiling_info *info)
> {
> if (dce_mi->masks->GRPH_SW_MODE) { /* GFX9 */
> + ASSERT(info->gfxversion == DcGfxVersion9);
> REG_UPDATE_6(GRPH_CONTROL,
> GRPH_SW_MODE, info->gfx9.swizzle,
> GRPH_NUM_BANKS, log_2(info-
>gfx9.num_banks),
> @@ -447,6 +449,7 @@ static void program_tiling(
> }
>
> if (dce_mi->masks->GRPH_MICRO_TILE_MODE) { /* GFX8 */
> + ASSERT(info->gfxversion == DcGfxVersion8);
Hi,
GFX7 hits this assertion. Assuming that GFX7 requires the same register
programming as GFX8, the assertion should be changed to:
ASSERT(info->gfxversion == DcGfxVersion7 ||
info->gfxversion == DcGfxVersion8);
That being said, I don't see much value in these assertions, because the
"dce_mi->masks->GRPH_MICRO_TILE_MODE" check already implies that the code is
running on a GFX version that has this register.
Best regards,
Timur
> REG_UPDATE_9(GRPH_CONTROL,
> GRPH_NUM_BANKS, info-
>gfx8.num_banks,
> GRPH_BANK_WIDTH, info-
>gfx8.bank_width,
> diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
> b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c index
> 2c43c2422638..67cfca3361fb 100644
> --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
> +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
> @@ -165,6 +165,8 @@ static void program_tiling(
> const struct dc_tiling_info *info,
> const enum surface_pixel_format pixel_format)
> {
> + ASSERT(info->gfxversion == DcGfxVersion8);
> +
> uint32_t value = 0;
>
> set_reg_field_value(value, info->gfx8.num_banks,
> @@ -541,6 +543,7 @@ static const unsigned int *get_dvmm_hw_setting(
> else
> bpp = bpp_8;
>
> + ASSERT(tiling_info->gfxversion == DcGfxVersion8);
> switch (tiling_info->gfx8.array_mode) {
> case DC_ARRAY_1D_TILED_THIN1:
> case DC_ARRAY_1D_TILED_THICK:
> diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
> b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c index
> 74962791302f..71eeee02c0fa 100644
> --- a/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
> +++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
> @@ -1006,6 +1006,7 @@ bool dcn_validate_bandwidth(
>
> v->source_pixel_format[input_idx] =
tl_pixel_format_to_bw_defs(
> pipe->plane_state-
>format);
> + ASSERT(pipe->plane_state-
>tiling_info.gfxversion == DcGfxVersion9);
> v->source_surface_mode[input_idx] =
tl_sw_mode_to_bw_defs(
> pipe->plane_state-
>tiling_info.gfx9.swizzle);
> v->lb_bit_per_pixel[input_idx] =
> tl_lb_bpp_to_int(pipe->plane_res.scl_data.lb_params.depth); diff --git
> a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
> b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c index
> 6378e3fd7249..e697d9bf1b44 100644
> --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
> +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.c
> @@ -145,6 +145,8 @@ void hubp1_program_tiling(
> {
> struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
>
> + ASSERT(info->gfxversion == DcGfxVersion9);
> +
> REG_UPDATE_6(DCSURF_ADDR_CONFIG,
> NUM_PIPES, log_2(info->gfx9.num_pipes),
> NUM_BANKS, log_2(info->gfx9.num_banks),
> diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
> b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c index
> 92288de4cc10..4715e60e812a 100644
> --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
> +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
> @@ -313,6 +313,8 @@ static void hubp2_program_tiling(
> const struct dc_tiling_info *info,
> const enum surface_pixel_format pixel_format)
> {
> + ASSERT(info->gfxversion == DcGfxVersion9);
> +
> REG_UPDATE_3(DCSURF_ADDR_CONFIG,
> NUM_PIPES, log_2(info->gfx9.num_pipes),
> PIPE_INTERLEAVE, info->gfx9.pipe_interleave,
> diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c
> b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c index
> 0cc6f4558989..207c2f86b7d7 100644
> --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c
> +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c
> @@ -321,6 +321,8 @@ void hubp3_program_tiling(
> const struct dc_tiling_info *info,
> const enum surface_pixel_format pixel_format)
> {
> + ASSERT(info->gfxversion == DcGfxVersion9);
> +
> REG_UPDATE_4(DCSURF_ADDR_CONFIG,
> NUM_PIPES, log_2(info->gfx9.num_pipes),
> PIPE_INTERLEAVE, info->gfx9.pipe_interleave,
> diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
> b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c index
> c205500290ec..861e940250af 100644
> --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
> +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
> @@ -589,7 +589,12 @@ void hubp401_program_tiling(
> *
> * DIM_TYPE field in DCSURF_TILING for Display is always 1 (2D
dimension)
> which is HW default. */
> - REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, info-
>gfx_addr3.swizzle);
> + if (info->gfxversion == DcGfxAddr3) {
> + REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, info-
>gfx_addr3.swizzle);
> + } else {
> + /* linear */
> + REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, 0);
> + }
> }
>
> void hubp401_program_size(
> diff --git
> a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c
> b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c
> index f5a4e97c40ce..7d99f5d79e6d 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c
> +++
> b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource_helpers.c @@
> -401,7 +401,8 @@ void dcn32_set_det_allocations(struct dc *dc, struct
> dc_state *context, */
> if (pipe_cnt == 1) {
> pipes[0].pipe.src.det_size_override =
DCN3_2_MAX_DET_SIZE;
> - if (pipe->plane_state && !disable_unbounded_requesting
&&
> pipe->plane_state->tiling_info.gfx9.swizzle != DC_SW_LINEAR) { +
if
> (pipe->plane_state && !disable_unbounded_requesting &&
> pipe->plane_state->tiling_info.gfxversion != DcGfxBase &&
> + !(pipe->plane_state->tiling_info.gfxversion
== DcGfxVersion9 &&
> pipe->plane_state->tiling_info.gfx9.swizzle == DC_SW_LINEAR)) { if
> (!is_dual_plane(pipe->plane_state->format)) {
>
pipes[0].pipe.src.det_size_override = DCN3_2_DEFAULT_DET_SIZE;
>
pipes[0].pipe.src.unbounded_req_mode = true;
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 14/21] drm/amd/display: Migrate DIO registers access from hwseq to dio component.
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (12 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 13/21] drm/amd/display: Add Gfx Base Case For Linear Tiling Handling Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 15/21] drm/amd/display: Match expected data types Wayne Lin
` (6 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Bhuvanachandra Pinninti, Jun Lei
From: Bhuvanachandra Pinninti <bpinnint@amd.com>
[why]
Direct DIO registers access in hwseq layer was creating register conflicts.
[how]
Migrated DIO registers from hwseq to dio component.
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Signed-off-by: Bhuvanachandra Pinninti <bpinnint@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/dio/Makefile | 2 +-
.../drm/amd/display/dc/dio/dcn10/dcn10_dio.c | 47 +++++++++++++++++++
.../drm/amd/display/dc/dio/dcn10/dcn10_dio.h | 42 +++++++++++++++++
.../amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 4 +-
.../amd/display/dc/hwss/dcn201/dcn201_hwseq.c | 5 +-
.../amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 4 +-
.../amd/display/dc/hwss/dcn31/dcn31_hwseq.c | 10 ++--
.../amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 4 +-
.../amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 10 ++--
.../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 4 +-
.../gpu/drm/amd/display/dc/inc/core_types.h | 2 +
drivers/gpu/drm/amd/display/dc/inc/hw/dio.h | 22 +++++++++
.../dc/resource/dcn401/dcn401_resource.c | 41 ++++++++++++++++
13 files changed, 179 insertions(+), 18 deletions(-)
create mode 100644 drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.c
create mode 100644 drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.h
create mode 100644 drivers/gpu/drm/amd/display/dc/inc/hw/dio.h
diff --git a/drivers/gpu/drm/amd/display/dc/dio/Makefile b/drivers/gpu/drm/amd/display/dc/dio/Makefile
index 0dfd480976f7..02eec03dc204 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dio/Makefile
@@ -27,7 +27,7 @@ ifdef CONFIG_DRM_AMD_DC_FP
###############################################################################
# DCN10
###############################################################################
-DIO_DCN10 = dcn10_link_encoder.o dcn10_stream_encoder.o
+DIO_DCN10 = dcn10_link_encoder.o dcn10_stream_encoder.o dcn10_dio.o
AMD_DAL_DIO_DCN10 = $(addprefix $(AMDDALPATH)/dc/dio/dcn10/,$(DIO_DCN10))
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.c b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.c
new file mode 100644
index 000000000000..edcf4e67483b
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2025 Advanced Micro Devices, Inc.
+
+#include "dc_hw_types.h"
+#include "dm_services.h"
+#include "reg_helper.h"
+#include "dcn10_dio.h"
+
+#define CTX \
+ dio10->base.ctx
+#define REG(reg)\
+ dio10->regs->reg
+
+#undef FN
+#define FN(reg_name, field_name) \
+ dio10->shifts->field_name, dio10->masks->field_name
+
+static void dcn10_dio_mem_pwr_ctrl(struct dio *dio, bool enable_i2c_light_sleep)
+{
+ struct dcn10_dio *dio10 = TO_DCN10_DIO(dio);
+
+ /* power AFMT HDMI memory */
+ REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+
+ if (enable_i2c_light_sleep)
+ REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1);
+}
+
+static const struct dio_funcs dcn10_dio_funcs = {
+ .mem_pwr_ctrl = dcn10_dio_mem_pwr_ctrl,
+};
+
+void dcn10_dio_construct(
+ struct dcn10_dio *dio10,
+ struct dc_context *ctx,
+ const struct dcn_dio_registers *regs,
+ const struct dcn_dio_shift *shifts,
+ const struct dcn_dio_mask *masks)
+{
+ dio10->base.ctx = ctx;
+ dio10->base.funcs = &dcn10_dio_funcs;
+
+ dio10->regs = regs;
+ dio10->shifts = shifts;
+ dio10->masks = masks;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.h b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.h
new file mode 100644
index 000000000000..369c5996326e
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.h
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2025 Advanced Micro Devices, Inc.
+
+#ifndef __DCN10_DIO_H__
+#define __DCN10_DIO_H__
+
+#include "dio.h"
+
+#define TO_DCN10_DIO(dio_base) \
+ container_of(dio_base, struct dcn10_dio, base)
+
+#define DIO_REG_LIST_DCN10()\
+ SR(DIO_MEM_PWR_CTRL)
+
+struct dcn_dio_registers {
+ uint32_t DIO_MEM_PWR_CTRL;
+};
+
+struct dcn_dio_shift {
+ uint8_t I2C_LIGHT_SLEEP_FORCE;
+};
+
+struct dcn_dio_mask {
+ uint32_t I2C_LIGHT_SLEEP_FORCE;
+};
+
+struct dcn10_dio {
+ struct dio base;
+ const struct dcn_dio_registers *regs;
+ const struct dcn_dio_shift *shifts;
+ const struct dcn_dio_mask *masks;
+};
+
+void dcn10_dio_construct(
+ struct dcn10_dio *dio10,
+ struct dc_context *ctx,
+ const struct dcn_dio_registers *regs,
+ const struct dcn_dio_shift *shifts,
+ const struct dcn_dio_mask *masks);
+
+#endif /* __DCN10_DIO_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
index f89b2f5a9bbd..5243177c1faa 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
@@ -50,6 +50,7 @@
#include "link_hwss.h"
#include "dpcd_defs.h"
#include "dsc.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dce/dmub_psr.h"
#include "dc_dmub_srv.h"
#include "dce/dmub_hw_lock_mgr.h"
@@ -1881,7 +1882,8 @@ void dcn10_init_hw(struct dc *dc)
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
if (!is_optimized_init_done)
- REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+ if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
+ dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false);
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
index 7cd225a6cf6c..ce18d75fd991 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
@@ -40,6 +40,8 @@
#include "clk_mgr.h"
#include "reg_helper.h"
#include "dcn10/dcn10_hubbub.h"
+#include "dio/dcn10/dcn10_dio.h"
+
#define CTX \
hws->ctx
@@ -360,7 +362,8 @@ void dcn201_init_hw(struct dc *dc)
}
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
- REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+ if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
+ dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false);
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
index 3ff15ec9dc17..d58f2cf2615c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
@@ -53,6 +53,7 @@
#include "dcn30/dcn30_resource.h"
#include "link_service.h"
#include "dc_state_priv.h"
+#include "dio/dcn10/dcn10_dio.h"
#define TO_DCN_DCCG(dccg)\
container_of(dccg, struct dcn_dccg, base)
@@ -794,7 +795,8 @@ void dcn30_init_hw(struct dc *dc)
}
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
- REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+ if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
+ dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false);
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
index 91a672a46289..db2f7cbb12ff 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
@@ -53,6 +53,7 @@
#include "dcn30/dcn30_vpg.h"
#include "dce/dce_i2c_hw.h"
#include "dce/dmub_abm_lcd.h"
+#include "dio/dcn10/dcn10_dio.h"
#define DC_LOGGER_INIT(logger)
@@ -237,12 +238,9 @@ void dcn31_init_hw(struct dc *dc)
abms[i]->funcs->abm_init(abms[i], backlight, user_level);
}
- /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
- REG_WRITE(DIO_MEM_PWR_CTRL, 0);
-
- // Set i2c to light sleep until engine is setup
- if (dc->debug.enable_mem_low_power.bits.i2c)
- REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1);
+ /* Power on DIO memory (AFMT HDMI) and set I2C to light sleep */
+ if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
+ dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, dc->debug.enable_mem_low_power.bits.i2c);
if (hws->funcs.setup_hpo_hw_control)
hws->funcs.setup_hpo_hw_control(hws, false);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index 3f76fba7dccc..37300e12e645 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -52,6 +52,7 @@
#include "link_service.h"
#include "../dcn20/dcn20_hwseq.h"
#include "dc_state_priv.h"
+#include "dio/dcn10/dcn10_dio.h"
#define DC_LOGGER_INIT(logger)
@@ -955,7 +956,8 @@ void dcn32_init_hw(struct dc *dc)
}
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
- REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+ if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
+ dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false);
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
index 1c7263f9ef51..b5a4cefbd35f 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
@@ -53,6 +53,7 @@
#include "dcn30/dcn30_vpg.h"
#include "dce/dce_i2c_hw.h"
#include "dsc.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dcn20/dcn20_optc.h"
#include "dcn30/dcn30_cm_common.h"
#include "dcn31/dcn31_hwseq.h"
@@ -272,12 +273,9 @@ void dcn35_init_hw(struct dc *dc)
}
}
- /* power AFMT HDMI memory TODO: may move to dis/en output save power*/
- REG_WRITE(DIO_MEM_PWR_CTRL, 0);
-
- // Set i2c to light sleep until engine is setup
- if (dc->debug.enable_mem_low_power.bits.i2c)
- REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 0);
+ /* Power on DIO memory (AFMT HDMI) and optionally disable I2C light sleep */
+ if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
+ dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, !dc->debug.enable_mem_low_power.bits.i2c);
if (hws->funcs.setup_hpo_hw_control)
hws->funcs.setup_hpo_hw_control(hws, false);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 567ed207d7cd..9cda39d0ed95 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -39,6 +39,7 @@
#include "dc_state_priv.h"
#include "link_enc_cfg.h"
#include "../hw_sequencer.h"
+#include "dio/dcn10/dcn10_dio.h"
#define DC_LOGGER_INIT(logger)
@@ -320,7 +321,8 @@ void dcn401_init_hw(struct dc *dc)
}
/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
- REG_WRITE(DIO_MEM_PWR_CTRL, 0);
+ if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl)
+ dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false);
if (!dc->debug.disable_clock_gate) {
/* enable all DCN clock gating */
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 61d8ef759aca..43579b0e1482 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -35,6 +35,7 @@
#include "hubp.h"
#include "mpc.h"
#include "dwb.h"
+#include "hw/dio.h"
#include "mcif_wb.h"
#include "panel_cntl.h"
#include "dmub/inc/dmub_cmd.h"
@@ -250,6 +251,7 @@ struct resource_pool {
struct timing_generator *timing_generators[MAX_PIPES];
struct stream_encoder *stream_enc[MAX_PIPES * 2];
struct hubbub *hubbub;
+ struct dio *dio;
struct mpc *mpc;
struct pp_smu_funcs *pp_smu;
struct dce_aux *engines[MAX_PIPES];
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dio.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dio.h
new file mode 100644
index 000000000000..532bf54cf2c4
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dio.h
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2025 Advanced Micro Devices, Inc.
+
+#ifndef __DC_DIO_H__
+#define __DC_DIO_H__
+
+#include "dc_types.h"
+
+struct dc_context;
+struct dio;
+
+struct dio_funcs {
+ void (*mem_pwr_ctrl)(struct dio *dio, bool enable_i2c_light_sleep);
+};
+
+struct dio {
+ const struct dio_funcs *funcs;
+ struct dc_context *ctx;
+};
+
+#endif /* __DC_DIO_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
index 1cdbb65da4a3..df3acf589582 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
@@ -21,6 +21,7 @@
#include "dcn401/dcn401_hubbub.h"
#include "dcn401/dcn401_mpc.h"
#include "dcn401/dcn401_hubp.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "irq/dcn401/irq_service_dcn401.h"
#include "dcn401/dcn401_dpp.h"
#include "dcn401/dcn401_optc.h"
@@ -634,6 +635,22 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+#define dio_regs_init() \
+ DIO_REG_LIST_DCN10()
+
+static struct dcn_dio_registers dio_regs;
+
+#define DIO_MASK_SH_LIST_DCN401(mask_sh)\
+ HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
+
+static const struct dcn_dio_shift dio_shift = {
+ DIO_MASK_SH_LIST_DCN401(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST_DCN401(_MASK)
+};
+
static const struct resource_caps res_cap_dcn4_01 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -881,6 +898,22 @@ static struct hubbub *dcn401_hubbub_create(struct dc_context *ctx)
return &hubbub2->base;
}
+static struct dio *dcn401_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc(sizeof(struct dcn10_dio), GFP_KERNEL);
+
+ if (!dio10)
+ return NULL;
+
+#undef REG_STRUCT
+#define REG_STRUCT dio_regs
+ dio_regs_init();
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubp *dcn401_hubp_create(
struct dc_context *ctx,
uint32_t inst)
@@ -2071,6 +2104,14 @@ static bool dcn401_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn401_dio_create(ctx);
+ if (pool->base.dio == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create dio!\n");
+ goto create_fail;
+ }
+
/* HUBPs, DPPs, OPPs, TGs, ABMs */
for (i = 0, j = 0; i < pool->base.res_cap->num_timing_generator; i++) {
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 15/21] drm/amd/display: Match expected data types
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (13 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 14/21] drm/amd/display: Migrate DIO registers access from hwseq to dio component Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 16/21] drm/amd/display: Add CRC 32-bit mode support for DCN3.6+ Wayne Lin
` (5 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Zheng Austin, Dillon Varone
From: Zheng Austin <Austin.Zheng@amd.com>
[Why/How]
Data types should match what is expected.
Update/cast data accordingly.
Also change ASSERT to use DML_ASSERT instead
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Zheng Austin <Austin.Zheng@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../src/dml2_core/dml2_core_dcn4_calcs.c | 4 +--
.../dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c | 34 +++++++++----------
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
index 37699cc9e5c1..ca5ac3c0deb5 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
@@ -7080,7 +7080,7 @@ static void calculate_excess_vactive_bandwidth_required(
static double uclk_khz_to_dram_bw_mbps(unsigned long uclk_khz, const struct dml2_dram_params *dram_config, const struct dml2_mcg_dram_bw_to_min_clk_table *dram_bw_table)
{
double bw_mbps = 0;
- int i;
+ unsigned int i;
if (!dram_config->alt_clock_bw_conversion)
bw_mbps = ((double)uclk_khz * dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock) / 1000.0;
@@ -7091,7 +7091,7 @@ static double uclk_khz_to_dram_bw_mbps(unsigned long uclk_khz, const struct dml2
break;
}
- ASSERT(bw_mbps > 0);
+ DML_ASSERT(bw_mbps > 0);
return bw_mbps;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
index 5c713f2e6eca..9d7741fd0adb 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
@@ -17,7 +17,7 @@ static double dram_bw_kbps_to_uclk_khz(unsigned long long bandwidth_kbps, const
uclk_bytes_per_tick = dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock;
uclk_khz = (double)bandwidth_kbps / uclk_bytes_per_tick;
} else {
- int i;
+ unsigned int i;
/* For lpddr5 bytes per tick changes with mpstate, use table to find uclk*/
for (i = 0; i < dram_bw_table->num_entries; i++)
if (dram_bw_table->entries[i].pre_derate_dram_bw_kbps >= bandwidth_kbps) {
@@ -63,17 +63,17 @@ static void calculate_system_active_minimums(struct dml2_dpmm_map_mode_to_soc_dp
double min_uclk_latency, min_fclk_latency, min_dcfclk_latency;
const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result;
- min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.average_bw_dram_kbps
- / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100),
+ min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.average_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100)),
&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
if (in_out->display_cfg->display_config.hostvm_enable)
- min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.urgent_bw_dram_kbps
- / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel_and_vm / 100),
+ min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.urgent_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel_and_vm / 100)),
&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
else
- min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.urgent_bw_dram_kbps
- / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100),
+ min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.urgent_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100)),
&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg;
@@ -111,12 +111,12 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm
const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result;
/* assumes DF throttling is enabled */
- min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.average_bw_dram_kbps
- / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_average.dram_derate_percent_pixel / 100),
+ min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.average_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_average.dram_derate_percent_pixel / 100)),
&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
- min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps
- / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_urgent.dram_derate_percent_pixel / 100),
+ min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_urgent.dram_derate_percent_pixel / 100)),
&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg;
@@ -144,12 +144,12 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm
in_out->programming->min_clocks.dcn4x.svp_prefetch.dcfclk_khz = dml_round_up(min_dcfclk_bw > min_dcfclk_latency ? min_dcfclk_bw : min_dcfclk_latency);
/* assumes DF throttling is disabled */
- min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.average_bw_dram_kbps
- / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100),
+ min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.average_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100)),
&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
- min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps
- / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100),
+ min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100)),
&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg;
@@ -185,8 +185,8 @@ static void calculate_idle_minimums(struct dml2_dpmm_map_mode_to_soc_dpm_params_
double min_uclk_latency, min_fclk_latency, min_dcfclk_latency;
const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result;
- min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.average_bw_dram_kbps
- / ((double)in_out->soc_bb->qos_parameters.derate_table.system_idle_average.dram_derate_percent_pixel / 100),
+ min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.average_bw_dram_kbps
+ / ((double)in_out->soc_bb->qos_parameters.derate_table.system_idle_average.dram_derate_percent_pixel / 100)),
&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
min_fclk_avg = (double)mode_support_result->global.active.average_bw_sdp_kbps / in_out->soc_bb->fabric_datapath_to_dcn_data_return_bytes;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 16/21] drm/amd/display: Add CRC 32-bit mode support for DCN3.6+
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (14 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 15/21] drm/amd/display: Match expected data types Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 17/21] drm/amd/display: Init DMUB DPIA Only for APU Wayne Lin
` (4 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Chenyu Chen
From: Chenyu Chen <chen-yu.chen@amd.com>
[Why]
DCN 3.6+ hardware supports CRC-32 polynomial in addition to the
legacy CRC-16. Enable 32-bit CRC values per color component for
improvement of precision in display validation.
[How]
When userspace sets crc_poly_mode (0=CRC-16, 1=CRC-32) via the debugfs
interface, the value is stored in dm_irq_params.crc_poly_mode. When CRC
source configuration triggers amdgpu_dm_crtc_configure_crc_source(),
crc_poly_mode is retrieved from dm_irq_params and passed to
dc_stream_configure_crc().
In the DC layer, dc_stream_configure_crc() sets crc_poly_mode into the
crc_params structure and passes it to optc35_configure_crc(). If the
hardware supports the OTG_CRC_POLY_SEL register, the register is
programmed to select CRC-16 or CRC-32 polynomial.
When reading CRC values, optc35_get_crc() checks whether CRC32 register
masks are available. If present, it reads 32-bit CRC values from
OTG_CRC0/1_DATA_R32/G32/B32 registers; otherwise, it falls back
to reading 16-bit CRC values from legacy OTG_CRC0/1_DATA_RG/B
registers.
Reviewed-by: ChiaHsuan Chung <chiahsuan.chung@amd.com>
Signed-off-by: Chenyu Chen <chen-yu.chen@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 15 ++-
.../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 46 +++++++++
.../display/amdgpu_dm/amdgpu_dm_irq_params.h | 1 +
drivers/gpu/drm/amd/display/dc/core/dc.c | 4 +-
drivers/gpu/drm/amd/display/dc/dc_stream.h | 3 +-
.../amd/display/dc/inc/hw/timing_generator.h | 7 ++
.../amd/display/dc/optc/dcn10/dcn10_optc.h | 19 +++-
.../amd/display/dc/optc/dcn35/dcn35_optc.c | 96 ++++++++++++++++++-
.../amd/display/dc/optc/dcn35/dcn35_optc.h | 10 ++
.../dc/resource/dcn36/dcn36_resource.c | 12 ++-
10 files changed, 203 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
index 5851f2d55dde..1b03f2bf8d7a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -506,6 +506,7 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc,
struct amdgpu_dm_connector *aconnector = NULL;
bool enable = amdgpu_dm_is_valid_crc_source(source);
int ret = 0;
+ enum crc_poly_mode crc_poly_mode = CRC_POLY_MODE_16;
/* Configuration will be deferred to stream enable. */
if (!stream_state)
@@ -528,10 +529,18 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc,
amdgpu_dm_replay_disable(stream_state);
}
+ /* CRC polynomial selection only support for DCN3.6+ except DCN4.0.1 */
+ if ((amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 6, 0)) &&
+ (amdgpu_ip_version(adev, DCE_HWIP, 0) != IP_VERSION(4, 0, 1))) {
+ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
+
+ crc_poly_mode = acrtc->dm_irq_params.crc_poly_mode;
+ }
+
/* Enable or disable CRTC CRC generation */
if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) {
if (!dc_stream_configure_crc(stream_state->ctx->dc,
- stream_state, NULL, enable, enable, 0, true)) {
+ stream_state, NULL, enable, enable, 0, true, crc_poly_mode)) {
ret = -EINVAL;
goto unlock;
}
@@ -877,7 +886,7 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
else if (adev->dm.secure_display_ctx.op_mode == DISPLAY_CRC_MODE)
/* update ROI via dm*/
dc_stream_configure_crc(stream_state->ctx->dc, stream_state,
- &crc_window, true, true, i, false);
+ &crc_window, true, true, i, false, (enum crc_poly_mode)acrtc->dm_irq_params.crc_poly_mode);
reset_crc_frame_count[i] = true;
@@ -901,7 +910,7 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
else if (adev->dm.secure_display_ctx.op_mode == DISPLAY_CRC_MODE)
/* Avoid ROI window get changed, keep overwriting. */
dc_stream_configure_crc(stream_state->ctx->dc, stream_state,
- &crc_window, true, true, i, false);
+ &crc_window, true, true, i, false, (enum crc_poly_mode)acrtc->dm_irq_params.crc_poly_mode);
/* crc ready for psp to read out */
crtc_ctx->crc_info.crc[i].crc_ready = true;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index cfe35442dfcb..d6d43f1bf6d2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -3839,6 +3839,50 @@ static int crc_win_update_get(void *data, u64 *val)
DEFINE_DEBUGFS_ATTRIBUTE(crc_win_update_fops, crc_win_update_get,
crc_win_update_set, "%llu\n");
+
+/*
+ * Trigger to set crc polynomial mode
+ * 0: 16-bit CRC, 1: 32-bit CRC
+ * only accepts 0 or 1 for supported hwip versions
+ */
+static int crc_poly_mode_set(void *data, u64 val)
+{
+ struct drm_crtc *crtc = data;
+ struct amdgpu_crtc *acrtc;
+ struct amdgpu_device *adev = drm_to_adev(crtc->dev);
+
+ if ((amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 6, 0)) &&
+ (amdgpu_ip_version(adev, DCE_HWIP, 0) != IP_VERSION(4, 0, 1)) &&
+ (val < 2)) {
+ acrtc = to_amdgpu_crtc(crtc);
+ mutex_lock(&adev->dm.dc_lock);
+ spin_lock_irq(&adev_to_drm(adev)->event_lock);
+ acrtc->dm_irq_params.crc_poly_mode = val;
+ spin_unlock_irq(&adev_to_drm(adev)->event_lock);
+ mutex_unlock(&adev->dm.dc_lock);
+ }
+
+ return 0;
+}
+
+/*
+ * Get crc polynomial mode (0: 16-bit CRC, 1: 32-bit CRC)
+ */
+static int crc_poly_mode_get(void *data, u64 *val)
+{
+ struct drm_crtc *crtc = data;
+ struct drm_device *drm_dev = crtc->dev;
+ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
+
+ spin_lock_irq(&drm_dev->event_lock);
+ *val = acrtc->dm_irq_params.crc_poly_mode;
+ spin_unlock_irq(&drm_dev->event_lock);
+
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(crc_poly_mode_fops, crc_poly_mode_get,
+ crc_poly_mode_set, "%llu\n");
#endif
void crtc_debugfs_init(struct drm_crtc *crtc)
{
@@ -3858,6 +3902,8 @@ void crtc_debugfs_init(struct drm_crtc *crtc)
&crc_win_y_end_fops);
debugfs_create_file_unsafe("crc_win_update", 0644, dir, crtc,
&crc_win_update_fops);
+ debugfs_create_file_unsafe("crc_poly_mode", 0644, dir, crtc,
+ &crc_poly_mode_fops);
dput(dir);
#endif
debugfs_create_file("amdgpu_current_bpc", 0644, crtc->debugfs_entry,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h
index 3c9995275cbd..f0c1b0c1faa9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h
@@ -39,6 +39,7 @@ struct dm_irq_params {
#ifdef CONFIG_DEBUG_FS
enum amdgpu_dm_pipe_crc_source crc_src;
+ int crc_poly_mode; /* enum crc_poly_mode from timing_generator.h */
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
struct crc_window_param window_param[MAX_CRC_WINDOW_NUM];
/* At least one CRC window is activated or not*/
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 441b7e0a3b22..e7d2b861dedd 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -701,6 +701,7 @@ dc_stream_forward_multiple_crc_window(struct dc_stream_state *stream,
* once.
* @idx: Capture CRC on which CRC engine instance
* @reset: Reset CRC engine before the configuration
+ * @crc_poly_mode: CRC polynomial mode
*
* By default, the entire frame is used to calculate the CRC.
*
@@ -709,7 +710,7 @@ dc_stream_forward_multiple_crc_window(struct dc_stream_state *stream,
*/
bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
struct crc_params *crc_window, bool enable, bool continuous,
- uint8_t idx, bool reset)
+ uint8_t idx, bool reset, enum crc_poly_mode crc_poly_mode)
{
struct pipe_ctx *pipe;
struct crc_params param;
@@ -733,6 +734,7 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
param.windowb_y_start = 0;
param.windowb_x_end = pipe->stream->timing.h_addressable;
param.windowb_y_end = pipe->stream->timing.v_addressable;
+ param.crc_poly_mode = crc_poly_mode;
if (crc_window) {
param.windowa_x_start = crc_window->windowa_x_start;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index 719b98d8e8ca..9960494007ff 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -584,7 +584,8 @@ bool dc_stream_configure_crc(struct dc *dc,
bool enable,
bool continuous,
uint8_t idx,
- bool reset);
+ bool reset,
+ enum crc_poly_mode crc_poly_mode);
bool dc_stream_get_crc(struct dc *dc,
struct dc_stream_state *stream,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
index da7bf59c4b9d..671ab1fc7320 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
@@ -122,6 +122,12 @@ enum timing_synchronization_type {
VBLANK_SYNCHRONIZABLE
};
+enum crc_poly_mode {
+ CRC_POLY_MODE_16,
+ CRC_POLY_MODE_32,
+ CRC_POLY_MODE_MAX,
+};
+
struct crc_params {
/* Regions used to calculate CRC*/
uint16_t windowa_x_start;
@@ -144,6 +150,7 @@ struct crc_params {
uint8_t crc_eng_inst;
bool reset;
+ enum crc_poly_mode crc_poly_mode;
};
struct dcn_otg_state {
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
index 803bcc25601c..0b3f974f452e 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
@@ -244,7 +244,13 @@
uint32_t OTG_TRIGB_MANUAL_TRIG; \
uint32_t OTG_UPDATE_LOCK; \
uint32_t OTG_V_TOTAL_INT_STATUS; \
- uint32_t OTG_VSYNC_NOM_INT_STATUS
+ uint32_t OTG_VSYNC_NOM_INT_STATUS; \
+ uint32_t OTG_CRC0_DATA_R32; \
+ uint32_t OTG_CRC0_DATA_G32; \
+ uint32_t OTG_CRC0_DATA_B32; \
+ uint32_t OTG_CRC1_DATA_R32; \
+ uint32_t OTG_CRC1_DATA_G32; \
+ uint32_t OTG_CRC1_DATA_B32
struct dcn_optc_registers {
@@ -657,6 +663,15 @@ struct dcn_optc_registers {
type OTG_V_COUNT_STOP;\
type OTG_V_COUNT_STOP_TIMER;
+#define TG_REG_FIELD_LIST_DCN3_6(type) \
+ type OTG_CRC_POLY_SEL; \
+ type CRC0_R_CR32; \
+ type CRC0_G_Y32; \
+ type CRC0_B_CB32; \
+ type CRC1_R_CR32; \
+ type CRC1_G_Y32; \
+ type CRC1_B_CB32;
+
#define TG_REG_FIELD_LIST_DCN401(type) \
type OPTC_SEGMENT_WIDTH_LAST;\
type OTG_PSTATE_KEEPOUT_START;\
@@ -670,6 +685,7 @@ struct dcn_optc_shift {
TG_REG_FIELD_LIST_DCN2_0(uint8_t)
TG_REG_FIELD_LIST_DCN3_2(uint8_t)
TG_REG_FIELD_LIST_DCN3_5(uint8_t)
+ TG_REG_FIELD_LIST_DCN3_6(uint8_t)
TG_REG_FIELD_LIST_DCN401(uint8_t)
};
@@ -678,6 +694,7 @@ struct dcn_optc_mask {
TG_REG_FIELD_LIST_DCN2_0(uint32_t)
TG_REG_FIELD_LIST_DCN3_2(uint32_t)
TG_REG_FIELD_LIST_DCN3_5(uint32_t)
+ TG_REG_FIELD_LIST_DCN3_6(uint32_t)
TG_REG_FIELD_LIST_DCN401(uint32_t)
};
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
index f699e95059f3..0953acbcc6d4 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
@@ -180,6 +180,96 @@ static void optc35_phantom_crtc_post_enable(struct timing_generator *optc)
REG_WAIT(OTG_CLOCK_CONTROL, OTG_BUSY, 0, 1, 100000);
}
+/**
+ * optc35_get_crc - Capture CRC result per component
+ *
+ * @optc: timing_generator instance.
+ * @idx: index of crc engine to get CRC from
+ * @r_cr: primary CRC signature for red data.
+ * @g_y: primary CRC signature for green data.
+ * @b_cb: primary CRC signature for blue data.
+ *
+ * This function reads the CRC signature from the OPTC registers. Notice that
+ * we have three registers to keep the CRC result per color component (RGB).
+ *
+ * For different DCN versions:
+ * - If CRC32 registers (OTG_CRC0_DATA_R32/G32/B32) are available, read from
+ * 32-bit CRC registers. DCN 3.6+ supports both CRC-32 and CRC-16 polynomials
+ * selectable via OTG_CRC_POLY_SEL.
+ * - Otherwise, read from legacy 16-bit CRC registers (OTG_CRC0_DATA_RG/B)
+ * which only support CRC-16 polynomial.
+ *
+ * Returns:
+ * If CRC is disabled, return false; otherwise, return true, and the CRC
+ * results in the parameters.
+ */
+static bool optc35_get_crc(struct timing_generator *optc, uint8_t idx,
+ uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
+{
+ uint32_t field = 0;
+ struct optc *optc1 = DCN10TG_FROM_TG(optc);
+
+ REG_GET(OTG_CRC_CNTL, OTG_CRC_EN, &field);
+
+ /* Early return if CRC is not enabled for this CRTC */
+ if (!field)
+ return false;
+
+ if (optc1->tg_mask->CRC0_R_CR32 != 0 && optc1->tg_mask->CRC1_R_CR32 != 0 &&
+ optc1->tg_mask->CRC0_G_Y32 != 0 && optc1->tg_mask->CRC1_G_Y32 != 0 &&
+ optc1->tg_mask->CRC0_B_CB32 != 0 && optc1->tg_mask->CRC1_B_CB32 != 0) {
+ switch (idx) {
+ case 0:
+ /* OTG_CRC0_DATA_R32/G32/B32 has the CRC32 results */
+ REG_GET(OTG_CRC0_DATA_R32,
+ CRC0_R_CR32, r_cr);
+ REG_GET(OTG_CRC0_DATA_G32,
+ CRC0_G_Y32, g_y);
+ REG_GET(OTG_CRC0_DATA_B32,
+ CRC0_B_CB32, b_cb);
+ break;
+ case 1:
+ /* OTG_CRC1_DATA_R32/G32/B32 has the CRC32 results */
+ REG_GET(OTG_CRC1_DATA_R32,
+ CRC1_R_CR32, r_cr);
+ REG_GET(OTG_CRC1_DATA_G32,
+ CRC1_G_Y32, g_y);
+ REG_GET(OTG_CRC1_DATA_B32,
+ CRC1_B_CB32, b_cb);
+ break;
+ default:
+ return false;
+ }
+ } else {
+ switch (idx) {
+ case 0:
+ /* OTG_CRC0_DATA_RG has the CRC16 results for the red and green component */
+ REG_GET_2(OTG_CRC0_DATA_RG,
+ CRC0_R_CR, r_cr,
+ CRC0_G_Y, g_y);
+
+ /* OTG_CRC0_DATA_B has the CRC16 results for the blue component */
+ REG_GET(OTG_CRC0_DATA_B,
+ CRC0_B_CB, b_cb);
+ break;
+ case 1:
+ /* OTG_CRC1_DATA_RG has the CRC16 results for the red and green component */
+ REG_GET_2(OTG_CRC1_DATA_RG,
+ CRC1_R_CR, r_cr,
+ CRC1_G_Y, g_y);
+
+ /* OTG_CRC1_DATA_B has the CRC16 results for the blue component */
+ REG_GET(OTG_CRC1_DATA_B,
+ CRC1_B_CB, b_cb);
+ break;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+}
+
static bool optc35_configure_crc(struct timing_generator *optc,
const struct crc_params *params)
{
@@ -266,6 +356,10 @@ static bool optc35_configure_crc(struct timing_generator *optc,
default:
return false;
}
+ if (optc1->tg_mask->OTG_CRC_POLY_SEL != 0) {
+ REG_UPDATE(OTG_CRC_CNTL,
+ OTG_CRC_POLY_SEL, params->crc_poly_mode);
+ }
return true;
}
@@ -488,7 +582,7 @@ static const struct timing_generator_funcs dcn35_tg_funcs = {
.is_optc_underflow_occurred = optc1_is_optc_underflow_occurred,
.clear_optc_underflow = optc1_clear_optc_underflow,
.setup_global_swap_lock = NULL,
- .get_crc = optc1_get_crc,
+ .get_crc = optc35_get_crc,
.configure_crc = optc35_configure_crc,
.set_dsc_config = optc3_set_dsc_config,
.get_dsc_status = optc2_get_dsc_status,
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h
index 733a2f149d9a..5c2cb1f27783 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h
@@ -74,6 +74,16 @@
SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh),\
SF(OTG0_INTERRUPT_DEST, OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST, mask_sh)
+#define OPTC_COMMON_MASK_SH_LIST_DCN3_6(mask_sh)\
+ OPTC_COMMON_MASK_SH_LIST_DCN3_5(mask_sh),\
+ SF(OTG0_OTG_CRC_CNTL, OTG_CRC_POLY_SEL, mask_sh),\
+ SF(OTG_CRC320_OTG_CRC0_DATA_R32, CRC0_R_CR32, mask_sh),\
+ SF(OTG_CRC320_OTG_CRC0_DATA_G32, CRC0_G_Y32, mask_sh),\
+ SF(OTG_CRC320_OTG_CRC0_DATA_B32, CRC0_B_CB32, mask_sh),\
+ SF(OTG_CRC320_OTG_CRC1_DATA_R32, CRC1_R_CR32, mask_sh),\
+ SF(OTG_CRC320_OTG_CRC1_DATA_G32, CRC1_G_Y32, mask_sh),\
+ SF(OTG_CRC320_OTG_CRC1_DATA_B32, CRC1_B_CB32, mask_sh)
+
void dcn35_timing_generator_init(struct optc *optc1);
void dcn35_timing_generator_set_fgcg(struct optc *optc1, bool enable);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c
index 6469d5fe2e6d..0ee16926db4e 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c
@@ -460,16 +460,22 @@ static const struct dcn30_mpc_mask mpc_mask = {
};
#define optc_regs_init(id)\
- OPTC_COMMON_REG_LIST_DCN3_5_RI(id)
+ OPTC_COMMON_REG_LIST_DCN3_5_RI(id),\
+ SRI_ARR(OTG_CRC0_DATA_R32, OTG_CRC32, id),\
+ SRI_ARR(OTG_CRC0_DATA_G32, OTG_CRC32, id),\
+ SRI_ARR(OTG_CRC0_DATA_B32, OTG_CRC32, id),\
+ SRI_ARR(OTG_CRC1_DATA_R32, OTG_CRC32, id),\
+ SRI_ARR(OTG_CRC1_DATA_G32, OTG_CRC32, id),\
+ SRI_ARR(OTG_CRC1_DATA_B32, OTG_CRC32, id)
static struct dcn_optc_registers optc_regs[4];
static const struct dcn_optc_shift optc_shift = {
- OPTC_COMMON_MASK_SH_LIST_DCN3_5(__SHIFT)
+ OPTC_COMMON_MASK_SH_LIST_DCN3_6(__SHIFT)
};
static const struct dcn_optc_mask optc_mask = {
- OPTC_COMMON_MASK_SH_LIST_DCN3_5(_MASK)
+ OPTC_COMMON_MASK_SH_LIST_DCN3_6(_MASK)
};
#define hubp_regs_init(id)\
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 17/21] drm/amd/display: Init DMUB DPIA Only for APU
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (15 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 16/21] drm/amd/display: Add CRC 32-bit mode support for DCN3.6+ Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 18/21] drm/amd/display: DIO memory leak fix Wayne Lin
` (3 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Fangzhi Zuo
From: Fangzhi Zuo <Jerry.Zuo@amd.com>
[why & how]
1. There is no need to init dpia in dgpu
2. Add additional dpia flags
a. dpia hpd dynamic control
b. consolidated dpia link training to dp
c. dynamic bw allocation support
Reviewed-by: Roman Li <roman.li@amd.com>
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 +++++++++----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 333ff8557732..917224075ca2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1244,6 +1244,7 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
struct dmub_srv *dmub_srv = adev->dm.dmub_srv;
struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info;
const struct firmware *dmub_fw = adev->dm.dmub_fw;
+ struct dc *dc = adev->dm.dc;
struct dmcu *dmcu = adev->dm.dc->res_pool->dmcu;
struct abm *abm = adev->dm.dc->res_pool->abm;
struct dc_context *ctx = adev->dm.dc->ctx;
@@ -1349,18 +1350,15 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
for (i = 0; i < fb_info->num_fb; ++i)
hw_params.fb[i] = &fb_info->fb[i];
- switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
- case IP_VERSION(3, 1, 3):
- case IP_VERSION(3, 1, 4):
- case IP_VERSION(3, 5, 0):
- case IP_VERSION(3, 5, 1):
- case IP_VERSION(3, 6, 0):
- case IP_VERSION(4, 0, 1):
+ /* Enable usb4 dpia in the FW APU */
+ if (dc->caps.is_apu &&
+ dc->res_pool->usb4_dpia_count != 0 &&
+ !dc->debug.dpia_debug.bits.disable_dpia) {
hw_params.dpia_supported = true;
- hw_params.disable_dpia = adev->dm.dc->debug.dpia_debug.bits.disable_dpia;
- break;
- default:
- break;
+ hw_params.disable_dpia = dc->debug.dpia_debug.bits.disable_dpia;
+ hw_params.dpia_hpd_int_enable_supported = false;
+ hw_params.enable_non_transparent_setconfig = dc->config.consolidated_dpia_dp_lt;
+ hw_params.disable_dpia_bw_allocation = !dc->config.usb4_bw_alloc_support;
}
switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 18/21] drm/amd/display: DIO memory leak fix.
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (16 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 17/21] drm/amd/display: Init DMUB DPIA Only for APU Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 19/21] drm/amd/display: Add Handling for gfxversion DcGfxBase Wayne Lin
` (2 subsequent siblings)
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Bhuvanachandra Pinninti, Aric Cyr
From: Bhuvanachandra Pinninti <bpinnint@amd.com>
[why]
Allocated memory for dcn10_dio but not freed in dcn401_resource.
[how]
Add kfree for it in dcn401_resource.
Reviewed-by: Aric Cyr <aric.cyr@amd.com>
Signed-off-by: Bhuvanachandra Pinninti <bpinnint@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
index df3acf589582..4875faffe873 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
@@ -1532,6 +1532,11 @@ static void dcn401_resource_destruct(struct dcn401_resource_pool *pool)
if (pool->base.dccg != NULL)
dcn_dccg_destroy(&pool->base.dccg);
+ if (pool->base.dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->base.dio));
+ pool->base.dio = NULL;
+ }
+
if (pool->base.oem_device != NULL) {
struct dc *dc = pool->base.oem_device->ctx->dc;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 19/21] drm/amd/display: Add Handling for gfxversion DcGfxBase
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (17 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 18/21] drm/amd/display: DIO memory leak fix Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 20/21] drm/amd/display: [FW Promotion] Release 0.1.45.0 Wayne Lin
2026-01-28 1:51 ` [PATCH 21/21] drm/amd/display: Promote DC to 3.2.368 Wayne Lin
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Nicholas Carbones, Dillon Varone
From: Nicholas Carbones <ncarbone@amd.com>
[Why]
There is no way to set tiling in dml in the case that gfxversion is
DcGfxBase.
[How]
Where tiling is updated based on Gfx, add case for DcGfxBase and set
tiling to dml2_sw_linear.
Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Nicholas Carbones <ncarbone@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
.../drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
index bf5e7f4e0416..3f4963ce3a00 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
@@ -460,6 +460,9 @@ static void populate_dml21_surface_config_from_plane_state(
case DcGfxAddr3:
surface->tiling = gfx_addr3_to_dml2_swizzle_mode(plane_state->tiling_info.gfx_addr3.swizzle);
break;
+ case DcGfxBase:
+ surface->tiling = dml2_sw_linear;
+ break;
}
}
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 20/21] drm/amd/display: [FW Promotion] Release 0.1.45.0
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (18 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 19/21] drm/amd/display: Add Handling for gfxversion DcGfxBase Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
2026-01-28 1:51 ` [PATCH 21/21] drm/amd/display: Promote DC to 3.2.368 Wayne Lin
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Taimur Hassan
From: Taimur Hassan <Syed.Hassan@amd.com>
Add new enum definition for panel replay ml activity options.
Acked-by: ChiaHsuan Chung <chiahsuan.chung@amd.com>
Signed-off-by: Taimur Hassan <Syed.Hassan@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index 18e0bdfd6ff4..3b4f5e990ec5 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -736,6 +736,16 @@ union pr_hw_flags {
uint32_t u32All;
};
+/**
+ * Definition of Panel Replay ML Activity Options
+ */
+enum pr_ml_activity_option {
+ OPTION_DEFAULT = 0x00, // VESA Option Default (1C)
+ OPTION_1A = 0x01, // VESA Option 1A
+ OPTION_1B = 0x02, // VESA Option 1B
+ OPTION_1C = 0x03, // VESA Option 1C
+};
+
union fw_assisted_mclk_switch_version {
struct {
uint8_t minor : 5;
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 21/21] drm/amd/display: Promote DC to 3.2.368
2026-01-28 1:51 [PATCH 00/21] DC Patches February 02, 2026 Wayne Lin
` (19 preceding siblings ...)
2026-01-28 1:51 ` [PATCH 20/21] drm/amd/display: [FW Promotion] Release 0.1.45.0 Wayne Lin
@ 2026-01-28 1:51 ` Wayne Lin
20 siblings, 0 replies; 23+ messages in thread
From: Wayne Lin @ 2026-01-28 1:51 UTC (permalink / raw)
To: amd-gfx
Cc: Harry Wentland, Leo Li, Aurabindo Pillai, Roman Li, Wayne Lin,
Tom Chung, Fangzhi Zuo, Dan Wheeler, Ray Wu, Ivan Lipski,
Alex Hung, Taimur Hassan
From: Taimur Hassan <Syed.Hassan@amd.com>
This version brings along following fixes:
- Migrate DCCG register access from hwseq to dccg component.
- Add lpddr5 handling to dml2.1
- Correct external panel replay fsm control
- Make DCN35 OTG disable w/a reusable
- Make DSC FGCG a DSC block level function
- Make some DCN35 DCCG symbols reusable
- Fix writeback on DCN 3.2+
- Fix IGT link training failure on Replay panel
- Fix system resume lag issue
- Add oem panel config for new features
- Fix IGT ILR link training failure on Replay panel
- Fix a NULL pointer dereference in dcn20_hwseq.c
- Add Gfx Base Case For Linear Tiling Handling
- Migrate DIO registers access from hwseq to dio component.
- Match expected data types
- Add CRC 32-bit mode support for DCN3.6+
- Init DMUB DPIA Only for APU
- DIO memory leak fix.
- Add Handling for gfxversion DcGfxBase
Acked-by: ChiaHsuan Chung <chiahsuan.chung@amd.com>
Signed-off-by: Taimur Hassan <Syed.Hassan@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
---
drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index ce2eceba2ab7..fdfcfa416d16 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -63,7 +63,7 @@ struct dcn_dsc_reg_state;
struct dcn_optc_reg_state;
struct dcn_dccg_reg_state;
-#define DC_VER "3.2.367"
+#define DC_VER "3.2.368"
/**
* MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC
--
2.43.0
^ permalink raw reply related [flat|nested] 23+ messages in thread