* [PATCH] drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations
@ 2026-03-23 21:13 Ionut Nechita (Sunlight Linux)
2026-03-24 14:37 ` Alex Deucher
0 siblings, 1 reply; 5+ messages in thread
From: Ionut Nechita (Sunlight Linux) @ 2026-03-23 21:13 UTC (permalink / raw)
To: amd-gfx
Cc: harry.wentland, sunpeng.li, siqueira, alexander.deucher,
christian.koenig, airlied, simona, dri-devel, Ionut Nechita
From: Ionut Nechita <ionut_n2001@yahoo.com>
Description:
- Commit b82f0759346617b2 ("drm/amd/display: Migrate DIO registers access
from hwseq to dio component") moved DIO_MEM_PWR_CTRL register access
behind the new dio abstraction layer but only created the dio object for
DCN 4.01. On all other generations (DCN 10/20/21/201/30/301/302/303/
31/314/315/316/32/321/35/351/36), the dio pointer is NULL, causing the
register write to be silently skipped.
This results in AFMT HDMI memory not being powered on during init_hw,
which can cause HDMI audio failures and display issues on affected
hardware including Renoir/Cezanne (DCN 2.1) APUs that use dcn10_init_hw.
Call dcn10_dio_construct() in each older DCN generation's resource.c
to create the dio object, following the same pattern as DCN 4.01. This
ensures the dio pointer is non-NULL and the mem_pwr_ctrl callback works
through the dio abstraction for all DCN generations.
Fixes: b82f0759346617b2 ("drm/amd/display: Migrate DIO registers access from hwseq to dio component.")
Signed-off-by: Ionut Nechita <ionut_n2001@yahoo.com>
---
.../dc/resource/dcn10/dcn10_resource.c | 41 ++++++++++++++++++
.../dc/resource/dcn20/dcn20_resource.c | 42 ++++++++++++++++++
.../dc/resource/dcn201/dcn201_resource.c | 41 ++++++++++++++++++
.../dc/resource/dcn21/dcn21_resource.c | 34 +++++++++++++++
.../dc/resource/dcn30/dcn30_resource.c | 42 ++++++++++++++++++
.../dc/resource/dcn301/dcn301_resource.c | 42 ++++++++++++++++++
.../dc/resource/dcn302/dcn302_resource.c | 41 ++++++++++++++++++
.../dc/resource/dcn303/dcn303_resource.c | 41 ++++++++++++++++++
.../dc/resource/dcn31/dcn31_resource.c | 40 +++++++++++++++++
.../dc/resource/dcn314/dcn314_resource.c | 40 +++++++++++++++++
.../dc/resource/dcn315/dcn315_resource.c | 40 +++++++++++++++++
.../dc/resource/dcn316/dcn316_resource.c | 40 +++++++++++++++++
.../dc/resource/dcn32/dcn32_resource.c | 43 +++++++++++++++++++
.../dc/resource/dcn321/dcn321_resource.c | 43 +++++++++++++++++++
.../dc/resource/dcn35/dcn35_resource.c | 43 +++++++++++++++++++
.../dc/resource/dcn351/dcn351_resource.c | 43 +++++++++++++++++++
.../dc/resource/dcn36/dcn36_resource.c | 43 +++++++++++++++++++
17 files changed, 699 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c
index bbe185e15eb67..4663456a736a2 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c
@@ -71,6 +71,7 @@
#include "dce/dce_dmcu.h"
#include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
+#include "dio/dcn10/dcn10_dio.h"
#ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
@@ -444,6 +445,33 @@ static const struct dcn_hubbub_mask hubbub_mask = {
HUBBUB_MASK_SH_LIST_DCN10(_MASK)
};
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
+static struct dio *dcn10_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static int map_transmitter_id_to_phy_instance(
enum transmitter transmitter)
{
@@ -917,6 +945,11 @@ static void dcn10_resource_destruct(struct dcn10_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
+ if (pool->base.dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->base.dio));
+ pool->base.dio = NULL;
+ }
+
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.opps[i] != NULL)
pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
@@ -1653,6 +1686,14 @@ static bool dcn10_resource_construct(
goto fail;
}
+ /* DIO */
+ pool->base.dio = dcn10_dio_create(ctx);
+ if (pool->base.dio == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create dio!\n");
+ goto fail;
+ }
+
if (!resource_construct(num_virtual_links, dc, &pool->base,
&res_create_funcs))
goto fail;
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
index 8b555187ac753..74e8d229c9dd3 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
@@ -82,6 +82,7 @@
#include "dce/dce_dmcu.h"
#include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "vm_helper.h"
#include "link_enc_cfg.h"
@@ -550,6 +551,33 @@ static const struct dcn_hubbub_mask hubbub_mask = {
HUBBUB_MASK_SH_LIST_DCN20(_MASK)
};
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
+static struct dio *dcn20_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
#define vmid_regs(id)\
[id] = {\
DCN20_VMID_REG_LIST(id)\
@@ -1104,6 +1132,12 @@ static void dcn20_resource_destruct(struct dcn20_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
+
+ if (pool->base.dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->base.dio));
+ pool->base.dio = NULL;
+ }
+
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn20_dpp_destroy(&pool->base.dpps[i]);
@@ -2692,6 +2726,14 @@ static bool dcn20_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn20_dio_create(ctx);
+ if (pool->base.dio == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create dio!\n");
+ goto create_fail;
+ }
+
for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
pool->base.dscs[i] = dcn20_dsc_create(ctx, i);
if (pool->base.dscs[i] == NULL) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
index 4ea76e46ab15d..e289be70efb54 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
@@ -56,6 +56,7 @@
#include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
#include "dcn10/dcn10_resource.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "cyan_skillfish_ip_offset.h"
@@ -755,6 +756,33 @@ static struct hubbub *dcn201_hubbub_create(struct dc_context *ctx)
return &hubbub->base;
}
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
+static struct dio *dcn201_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct timing_generator *dcn201_timing_generator_create(
struct dc_context *ctx,
uint32_t instance)
@@ -930,6 +958,11 @@ static void dcn201_resource_destruct(struct dcn201_resource_pool *pool)
pool->base.hubbub = NULL;
}
+ if (pool->base.dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->base.dio));
+ pool->base.dio = NULL;
+ }
+
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn201_dpp_destroy(&pool->base.dpps[i]);
@@ -1276,6 +1309,14 @@ static bool dcn201_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn201_dio_create(ctx);
+ if (pool->base.dio == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create dio!\n");
+ goto create_fail;
+ }
+
if (!resource_construct(num_virtual_links, dc, &pool->base,
&res_create_funcs))
goto create_fail;
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
index 0f4307f8f3dd5..4333baac96ad7 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
@@ -84,6 +84,7 @@
#include "dce/dce_dmcu.h"
#include "dce/dce_aux.h"
#include "dce/dce_i2c.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dcn21_resource.h"
#include "vm_helper.h"
#include "dcn20/dcn20_vmid.h"
@@ -329,6 +330,25 @@ static const struct dcn_hubbub_mask hubbub_mask = {
HUBBUB_MASK_SH_LIST_DCN21(_MASK)
};
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+static const struct dcn_dio_shift dio_shift = { 0 };
+
+static const struct dcn_dio_mask dio_mask = { 0 };
+
+static struct dio *dcn21_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
#define vmid_regs(id)\
[id] = {\
@@ -677,6 +697,12 @@ static void dcn21_resource_destruct(struct dcn21_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
+
+ if (pool->base.dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->base.dio));
+ pool->base.dio = NULL;
+ }
+
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn20_dpp_destroy(&pool->base.dpps[i]);
@@ -1654,6 +1680,14 @@ static bool dcn21_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn21_dio_create(ctx);
+ if (pool->base.dio == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create dio!\n");
+ goto create_fail;
+ }
+
for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
pool->base.dscs[i] = dcn21_dsc_create(ctx, i);
if (pool->base.dscs[i] == NULL) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
index 2fa86b9587ed0..87b7b4ee04c64 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
@@ -60,6 +60,7 @@
#include "dml/display_mode_vba.h"
#include "dcn30/dcn30_dccg.h"
#include "dcn10/dcn10_resource.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "link_service.h"
#include "dce/dce_panel_cntl.h"
@@ -886,6 +887,33 @@ static struct hubbub *dcn30_hubbub_create(struct dc_context *ctx)
return &hubbub3->base;
}
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
+static struct dio *dcn30_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct timing_generator *dcn30_timing_generator_create(
struct dc_context *ctx,
uint32_t instance)
@@ -1095,6 +1123,12 @@ static void dcn30_resource_destruct(struct dcn30_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
+
+ if (pool->base.dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->base.dio));
+ pool->base.dio = NULL;
+ }
+
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn30_dpp_destroy(&pool->base.dpps[i]);
@@ -2464,6 +2498,14 @@ static bool dcn30_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn30_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 and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn30_hubp_create(ctx, i);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
index 7842bee57e636..6bb1c62124bb4 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
@@ -59,6 +59,7 @@
#include "dml/display_mode_vba.h"
#include "dcn301/dcn301_dccg.h"
#include "dcn10/dcn10_resource.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dcn30/dcn30_dio_stream_encoder.h"
#include "dcn301/dcn301_dio_link_encoder.h"
#include "dcn301/dcn301_panel_cntl.h"
@@ -843,6 +844,33 @@ static struct hubbub *dcn301_hubbub_create(struct dc_context *ctx)
return &hubbub3->base;
}
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
+static struct dio *dcn301_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct timing_generator *dcn301_timing_generator_create(
struct dc_context *ctx, uint32_t instance)
{
@@ -1066,6 +1094,12 @@ static void dcn301_destruct(struct dcn301_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
+
+ if (pool->base.dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->base.dio));
+ pool->base.dio = NULL;
+ }
+
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn301_dpp_destroy(&pool->base.dpps[i]);
@@ -1582,6 +1616,14 @@ static bool dcn301_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn301_dio_create(ctx);
+ if (pool->base.dio == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create dio!\n");
+ goto create_fail;
+ }
+
j = 0;
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
index 1874d5d6b7820..d02aafd06fd45 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
@@ -46,6 +46,7 @@
#include "dml/dcn30/dcn30_fpu.h"
#include "dcn10/dcn10_resource.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "link_service.h"
@@ -253,6 +254,33 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
+static struct dio *dcn302_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubbub *dcn302_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1022,6 +1050,11 @@ static void dcn302_resource_destruct(struct resource_pool *pool)
pool->hubbub = NULL;
}
+ if (pool->dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->dio));
+ pool->dio = NULL;
+ }
+
for (i = 0; i < pool->pipe_count; i++) {
if (pool->dpps[i] != NULL) {
kfree(TO_DCN20_DPP(pool->dpps[i]));
@@ -1372,6 +1405,14 @@ static bool dcn302_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->dio = dcn302_dio_create(ctx);
+ if (pool->dio == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create dio!\n");
+ goto create_fail;
+ }
+
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->pipe_count; i++) {
pool->hubps[i] = dcn302_hubp_create(ctx, i);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
index d52201cb359fd..30b1403112c6c 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
@@ -46,6 +46,7 @@
#include "dml/dcn30/dcn30_fpu.h"
#include "dcn10/dcn10_resource.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "link_service.h"
@@ -249,6 +250,33 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
+static struct dio *dcn303_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubbub *dcn303_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -966,6 +994,11 @@ static void dcn303_resource_destruct(struct resource_pool *pool)
pool->hubbub = NULL;
}
+ if (pool->dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->dio));
+ pool->dio = NULL;
+ }
+
for (i = 0; i < pool->pipe_count; i++) {
if (pool->dpps[i] != NULL) {
kfree(TO_DCN20_DPP(pool->dpps[i]));
@@ -1304,6 +1337,14 @@ static bool dcn303_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->dio = dcn303_dio_create(ctx);
+ if (pool->dio == NULL) {
+ BREAK_TO_DEBUGGER();
+ dm_error("DC: failed to create dio!\n");
+ goto create_fail;
+ }
+
/* HUBPs, DPPs, OPPs and TGs */
for (i = 0; i < pool->pipe_count; i++) {
pool->hubps[i] = dcn303_hubp_create(ctx, i);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
index 2055f1f8af652..4e9c041c707a6 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
@@ -64,6 +64,7 @@
#include "dce/dce_audio.h"
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
@@ -810,6 +811,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
static const struct resource_caps res_cap_dcn31 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -1021,6 +1037,18 @@ static struct mpc *dcn31_mpc_create(
return &mpc30->base;
}
+static struct dio *dcn31_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1396,6 +1424,10 @@ static void dcn31_resource_destruct(struct dcn31_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
+ if (pool->base.dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->base.dio));
+ pool->base.dio = NULL;
+ }
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn31_dpp_destroy(&pool->base.dpps[i]);
@@ -2063,6 +2095,14 @@ static bool dcn31_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn31_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 and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
index 1939f720ba295..e26a6427916a0 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
@@ -66,6 +66,7 @@
#include "dce/dce_audio.h"
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
@@ -822,6 +823,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
static const struct resource_caps res_cap_dcn314 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -1079,6 +1095,18 @@ static struct mpc *dcn31_mpc_create(
return &mpc30->base;
}
+static struct dio *dcn314_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1455,6 +1483,10 @@ static void dcn314_resource_destruct(struct dcn314_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
+ if (pool->base.dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->base.dio));
+ pool->base.dio = NULL;
+ }
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn31_dpp_destroy(&pool->base.dpps[i]);
@@ -1987,6 +2019,14 @@ static bool dcn314_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn314_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 and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
index e8377c190f635..131a6cd4c7352 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
@@ -63,6 +63,7 @@
#include "dce/dce_audio.h"
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
@@ -809,6 +810,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
static const struct resource_caps res_cap_dcn31 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -1020,6 +1036,18 @@ static struct mpc *dcn31_mpc_create(
return &mpc30->base;
}
+static struct dio *dcn315_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1397,6 +1425,10 @@ static void dcn315_resource_destruct(struct dcn315_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
+ if (pool->base.dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->base.dio));
+ pool->base.dio = NULL;
+ }
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn31_dpp_destroy(&pool->base.dpps[i]);
@@ -2012,6 +2044,14 @@ static bool dcn315_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn315_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 and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
index 045ce01bd74eb..c8c0ce6efcfdc 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
@@ -63,6 +63,7 @@
#include "dce/dce_audio.h"
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dio/virtual/virtual_stream_encoder.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
@@ -804,6 +805,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+static const struct dcn_dio_registers dio_regs = {
+ DIO_REG_LIST_DCN10()
+};
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
static const struct resource_caps res_cap_dcn31 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -1013,6 +1029,18 @@ static struct mpc *dcn31_mpc_create(
return &mpc30->base;
}
+static struct dio *dcn316_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1392,6 +1420,10 @@ static void dcn316_resource_destruct(struct dcn316_resource_pool *pool)
kfree(pool->base.hubbub);
pool->base.hubbub = NULL;
}
+ if (pool->base.dio != NULL) {
+ kfree(TO_DCN10_DIO(pool->base.dio));
+ pool->base.dio = NULL;
+ }
for (i = 0; i < pool->base.pipe_count; i++) {
if (pool->base.dpps[i] != NULL)
dcn31_dpp_destroy(&pool->base.dpps[i]);
@@ -1887,6 +1919,14 @@ static bool dcn316_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn316_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 and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
index c7fd604024d64..c3a6ae14de18b 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
@@ -66,6 +66,7 @@
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/virtual/virtual_stream_encoder.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dml/display_mode_vba.h"
#include "dcn32/dcn32_dccg.h"
#include "dcn10/dcn10_resource.h"
@@ -643,6 +644,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+static struct dcn_dio_registers dio_regs;
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
static const struct resource_caps res_cap_dcn32 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -833,6 +847,22 @@ static struct clock_source *dcn32_clock_source_create(
return NULL;
}
+static struct dio *dcn32_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+#undef REG_STRUCT
+#define REG_STRUCT dio_regs
+ DIO_REG_LIST_DCN10();
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubbub *dcn32_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1494,6 +1524,11 @@ static void dcn32_resource_destruct(struct dcn32_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;
@@ -2373,6 +2408,14 @@ static bool dcn32_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn32_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++) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
index c1582c27ac872..990aec7eb3d07 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
@@ -69,6 +69,7 @@
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/virtual/virtual_stream_encoder.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dml/display_mode_vba.h"
#include "dcn32/dcn32_dccg.h"
#include "dcn10/dcn10_resource.h"
@@ -639,6 +640,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+static struct dcn_dio_registers dio_regs;
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
static const struct resource_caps res_cap_dcn321 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -827,6 +841,22 @@ static struct clock_source *dcn321_clock_source_create(
return NULL;
}
+static struct dio *dcn321_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+#undef REG_STRUCT
+#define REG_STRUCT dio_regs
+ DIO_REG_LIST_DCN10();
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubbub *dcn321_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1474,6 +1504,11 @@ static void dcn321_resource_destruct(struct dcn321_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;
@@ -1872,6 +1907,14 @@ static bool dcn321_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn321_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++) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
index 3494a40cea99f..598b2f25881da 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
@@ -71,6 +71,7 @@
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/virtual/virtual_stream_encoder.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
#include "dcn35/dcn35_dccg.h"
@@ -664,6 +665,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+static struct dcn_dio_registers dio_regs;
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
static const struct resource_caps res_cap_dcn35 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -973,6 +987,22 @@ static struct mpc *dcn35_mpc_create(
return &mpc30->base;
}
+static struct dio *dcn35_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+#undef REG_STRUCT
+#define REG_STRUCT dio_regs
+ DIO_REG_LIST_DCN10();
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1563,6 +1593,11 @@ static void dcn35_resource_destruct(struct dcn35_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;
+ }
}
static struct hubp *dcn35_hubp_create(
@@ -2033,6 +2068,14 @@ static bool dcn35_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn35_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 and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
index 080bc7f24ffaa..7e15d07df7a33 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
@@ -50,6 +50,7 @@
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/virtual/virtual_stream_encoder.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
#include "dcn35/dcn35_dccg.h"
@@ -644,6 +645,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+static struct dcn_dio_registers dio_regs;
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
static const struct resource_caps res_cap_dcn351 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -953,6 +967,22 @@ static struct mpc *dcn35_mpc_create(
return &mpc30->base;
}
+static struct dio *dcn351_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+#undef REG_STRUCT
+#define REG_STRUCT dio_regs
+ DIO_REG_LIST_DCN10();
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1543,6 +1573,11 @@ static void dcn351_resource_destruct(struct dcn351_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;
+ }
}
static struct hubp *dcn35_hubp_create(
@@ -2005,6 +2040,14 @@ static bool dcn351_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn351_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 and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
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 af51ac4ea59e2..83fee2ca61bff 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
@@ -50,6 +50,7 @@
#include "dce/dce_hwseq.h"
#include "clk_mgr.h"
#include "dio/virtual/virtual_stream_encoder.h"
+#include "dio/dcn10/dcn10_dio.h"
#include "dce110/dce110_resource.h"
#include "dml/display_mode_vba.h"
#include "dcn35/dcn35_dccg.h"
@@ -651,6 +652,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
DCN20_VMID_MASK_SH_LIST(_MASK)
};
+static struct dcn_dio_registers dio_regs;
+
+#define DIO_MASK_SH_LIST(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(__SHIFT)
+};
+
+static const struct dcn_dio_mask dio_mask = {
+ DIO_MASK_SH_LIST(_MASK)
+};
+
static const struct resource_caps res_cap_dcn36 = {
.num_timing_generator = 4,
.num_opp = 4,
@@ -960,6 +974,22 @@ static struct mpc *dcn35_mpc_create(
return &mpc30->base;
}
+static struct dio *dcn36_dio_create(struct dc_context *ctx)
+{
+ struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
+
+ if (!dio10)
+ return NULL;
+
+#undef REG_STRUCT
+#define REG_STRUCT dio_regs
+ DIO_REG_LIST_DCN10();
+
+ dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
+
+ return &dio10->base;
+}
+
static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
{
int i;
@@ -1550,6 +1580,11 @@ static void dcn36_resource_destruct(struct dcn36_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;
+ }
}
static struct hubp *dcn35_hubp_create(
@@ -2012,6 +2047,14 @@ static bool dcn36_resource_construct(
goto create_fail;
}
+ /* DIO */
+ pool->base.dio = dcn36_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 and TGs */
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH] drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations
2026-03-23 21:13 [PATCH] drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations Ionut Nechita (Sunlight Linux)
@ 2026-03-24 14:37 ` Alex Deucher
2026-03-24 16:42 ` LIPSKI, IVAN
0 siblings, 1 reply; 5+ messages in thread
From: Alex Deucher @ 2026-03-24 14:37 UTC (permalink / raw)
To: Ionut Nechita (Sunlight Linux), LIPSKI, IVAN
Cc: amd-gfx, harry.wentland, sunpeng.li, siqueira, alexander.deucher,
christian.koenig, airlied, simona, dri-devel, Ionut Nechita
+ Ivan
On Mon, Mar 23, 2026 at 5:24 PM Ionut Nechita (Sunlight Linux)
<sunlightlinux@gmail.com> wrote:
>
> From: Ionut Nechita <ionut_n2001@yahoo.com>
>
> Description:
> - Commit b82f0759346617b2 ("drm/amd/display: Migrate DIO registers access
> from hwseq to dio component") moved DIO_MEM_PWR_CTRL register access
> behind the new dio abstraction layer but only created the dio object for
> DCN 4.01. On all other generations (DCN 10/20/21/201/30/301/302/303/
> 31/314/315/316/32/321/35/351/36), the dio pointer is NULL, causing the
> register write to be silently skipped.
>
> This results in AFMT HDMI memory not being powered on during init_hw,
> which can cause HDMI audio failures and display issues on affected
> hardware including Renoir/Cezanne (DCN 2.1) APUs that use dcn10_init_hw.
>
> Call dcn10_dio_construct() in each older DCN generation's resource.c
> to create the dio object, following the same pattern as DCN 4.01. This
> ensures the dio pointer is non-NULL and the mem_pwr_ctrl callback works
> through the dio abstraction for all DCN generations.
>
> Fixes: b82f0759346617b2 ("drm/amd/display: Migrate DIO registers access from hwseq to dio component.")
> Signed-off-by: Ionut Nechita <ionut_n2001@yahoo.com>
> ---
> .../dc/resource/dcn10/dcn10_resource.c | 41 ++++++++++++++++++
> .../dc/resource/dcn20/dcn20_resource.c | 42 ++++++++++++++++++
> .../dc/resource/dcn201/dcn201_resource.c | 41 ++++++++++++++++++
> .../dc/resource/dcn21/dcn21_resource.c | 34 +++++++++++++++
> .../dc/resource/dcn30/dcn30_resource.c | 42 ++++++++++++++++++
> .../dc/resource/dcn301/dcn301_resource.c | 42 ++++++++++++++++++
> .../dc/resource/dcn302/dcn302_resource.c | 41 ++++++++++++++++++
> .../dc/resource/dcn303/dcn303_resource.c | 41 ++++++++++++++++++
> .../dc/resource/dcn31/dcn31_resource.c | 40 +++++++++++++++++
> .../dc/resource/dcn314/dcn314_resource.c | 40 +++++++++++++++++
> .../dc/resource/dcn315/dcn315_resource.c | 40 +++++++++++++++++
> .../dc/resource/dcn316/dcn316_resource.c | 40 +++++++++++++++++
> .../dc/resource/dcn32/dcn32_resource.c | 43 +++++++++++++++++++
> .../dc/resource/dcn321/dcn321_resource.c | 43 +++++++++++++++++++
> .../dc/resource/dcn35/dcn35_resource.c | 43 +++++++++++++++++++
> .../dc/resource/dcn351/dcn351_resource.c | 43 +++++++++++++++++++
> .../dc/resource/dcn36/dcn36_resource.c | 43 +++++++++++++++++++
> 17 files changed, 699 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c
> index bbe185e15eb67..4663456a736a2 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c
> @@ -71,6 +71,7 @@
> #include "dce/dce_dmcu.h"
> #include "dce/dce_aux.h"
> #include "dce/dce_i2c.h"
> +#include "dio/dcn10/dcn10_dio.h"
>
> #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
> #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
> @@ -444,6 +445,33 @@ static const struct dcn_hubbub_mask hubbub_mask = {
> HUBBUB_MASK_SH_LIST_DCN10(_MASK)
> };
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> +static struct dio *dcn10_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static int map_transmitter_id_to_phy_instance(
> enum transmitter transmitter)
> {
> @@ -917,6 +945,11 @@ static void dcn10_resource_destruct(struct dcn10_resource_pool *pool)
> kfree(pool->base.hubbub);
> pool->base.hubbub = NULL;
>
> + if (pool->base.dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->base.dio));
> + pool->base.dio = NULL;
> + }
> +
> for (i = 0; i < pool->base.pipe_count; i++) {
> if (pool->base.opps[i] != NULL)
> pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
> @@ -1653,6 +1686,14 @@ static bool dcn10_resource_construct(
> goto fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn10_dio_create(ctx);
> + if (pool->base.dio == NULL) {
> + BREAK_TO_DEBUGGER();
> + dm_error("DC: failed to create dio!\n");
> + goto fail;
> + }
> +
> if (!resource_construct(num_virtual_links, dc, &pool->base,
> &res_create_funcs))
> goto fail;
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
> index 8b555187ac753..74e8d229c9dd3 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
> @@ -82,6 +82,7 @@
> #include "dce/dce_dmcu.h"
> #include "dce/dce_aux.h"
> #include "dce/dce_i2c.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "vm_helper.h"
>
> #include "link_enc_cfg.h"
> @@ -550,6 +551,33 @@ static const struct dcn_hubbub_mask hubbub_mask = {
> HUBBUB_MASK_SH_LIST_DCN20(_MASK)
> };
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> +static struct dio *dcn20_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> #define vmid_regs(id)\
> [id] = {\
> DCN20_VMID_REG_LIST(id)\
> @@ -1104,6 +1132,12 @@ static void dcn20_resource_destruct(struct dcn20_resource_pool *pool)
> kfree(pool->base.hubbub);
> pool->base.hubbub = NULL;
> }
> +
> + if (pool->base.dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->base.dio));
> + pool->base.dio = NULL;
> + }
> +
> for (i = 0; i < pool->base.pipe_count; i++) {
> if (pool->base.dpps[i] != NULL)
> dcn20_dpp_destroy(&pool->base.dpps[i]);
> @@ -2692,6 +2726,14 @@ static bool dcn20_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn20_dio_create(ctx);
> + if (pool->base.dio == NULL) {
> + BREAK_TO_DEBUGGER();
> + dm_error("DC: failed to create dio!\n");
> + goto create_fail;
> + }
> +
> for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
> pool->base.dscs[i] = dcn20_dsc_create(ctx, i);
> if (pool->base.dscs[i] == NULL) {
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
> index 4ea76e46ab15d..e289be70efb54 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
> @@ -56,6 +56,7 @@
> #include "dce/dce_aux.h"
> #include "dce/dce_i2c.h"
> #include "dcn10/dcn10_resource.h"
> +#include "dio/dcn10/dcn10_dio.h"
>
> #include "cyan_skillfish_ip_offset.h"
>
> @@ -755,6 +756,33 @@ static struct hubbub *dcn201_hubbub_create(struct dc_context *ctx)
> return &hubbub->base;
> }
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> +static struct dio *dcn201_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct timing_generator *dcn201_timing_generator_create(
> struct dc_context *ctx,
> uint32_t instance)
> @@ -930,6 +958,11 @@ static void dcn201_resource_destruct(struct dcn201_resource_pool *pool)
> pool->base.hubbub = NULL;
> }
>
> + if (pool->base.dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->base.dio));
> + pool->base.dio = NULL;
> + }
> +
> for (i = 0; i < pool->base.pipe_count; i++) {
> if (pool->base.dpps[i] != NULL)
> dcn201_dpp_destroy(&pool->base.dpps[i]);
> @@ -1276,6 +1309,14 @@ static bool dcn201_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn201_dio_create(ctx);
> + if (pool->base.dio == NULL) {
> + BREAK_TO_DEBUGGER();
> + dm_error("DC: failed to create dio!\n");
> + goto create_fail;
> + }
> +
> if (!resource_construct(num_virtual_links, dc, &pool->base,
> &res_create_funcs))
> goto create_fail;
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
> index 0f4307f8f3dd5..4333baac96ad7 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
> @@ -84,6 +84,7 @@
> #include "dce/dce_dmcu.h"
> #include "dce/dce_aux.h"
> #include "dce/dce_i2c.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "dcn21_resource.h"
> #include "vm_helper.h"
> #include "dcn20/dcn20_vmid.h"
> @@ -329,6 +330,25 @@ static const struct dcn_hubbub_mask hubbub_mask = {
> HUBBUB_MASK_SH_LIST_DCN21(_MASK)
> };
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +static const struct dcn_dio_shift dio_shift = { 0 };
> +
> +static const struct dcn_dio_mask dio_mask = { 0 };
> +
> +static struct dio *dcn21_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
>
> #define vmid_regs(id)\
> [id] = {\
> @@ -677,6 +697,12 @@ static void dcn21_resource_destruct(struct dcn21_resource_pool *pool)
> kfree(pool->base.hubbub);
> pool->base.hubbub = NULL;
> }
> +
> + if (pool->base.dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->base.dio));
> + pool->base.dio = NULL;
> + }
> +
> for (i = 0; i < pool->base.pipe_count; i++) {
> if (pool->base.dpps[i] != NULL)
> dcn20_dpp_destroy(&pool->base.dpps[i]);
> @@ -1654,6 +1680,14 @@ static bool dcn21_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn21_dio_create(ctx);
> + if (pool->base.dio == NULL) {
> + BREAK_TO_DEBUGGER();
> + dm_error("DC: failed to create dio!\n");
> + goto create_fail;
> + }
> +
> for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
> pool->base.dscs[i] = dcn21_dsc_create(ctx, i);
> if (pool->base.dscs[i] == NULL) {
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
> index 2fa86b9587ed0..87b7b4ee04c64 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
> @@ -60,6 +60,7 @@
> #include "dml/display_mode_vba.h"
> #include "dcn30/dcn30_dccg.h"
> #include "dcn10/dcn10_resource.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "link_service.h"
> #include "dce/dce_panel_cntl.h"
>
> @@ -886,6 +887,33 @@ static struct hubbub *dcn30_hubbub_create(struct dc_context *ctx)
> return &hubbub3->base;
> }
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> +static struct dio *dcn30_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct timing_generator *dcn30_timing_generator_create(
> struct dc_context *ctx,
> uint32_t instance)
> @@ -1095,6 +1123,12 @@ static void dcn30_resource_destruct(struct dcn30_resource_pool *pool)
> kfree(pool->base.hubbub);
> pool->base.hubbub = NULL;
> }
> +
> + if (pool->base.dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->base.dio));
> + pool->base.dio = NULL;
> + }
> +
> for (i = 0; i < pool->base.pipe_count; i++) {
> if (pool->base.dpps[i] != NULL)
> dcn30_dpp_destroy(&pool->base.dpps[i]);
> @@ -2464,6 +2498,14 @@ static bool dcn30_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn30_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 and TGs */
> for (i = 0; i < pool->base.pipe_count; i++) {
> pool->base.hubps[i] = dcn30_hubp_create(ctx, i);
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
> index 7842bee57e636..6bb1c62124bb4 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
> @@ -59,6 +59,7 @@
> #include "dml/display_mode_vba.h"
> #include "dcn301/dcn301_dccg.h"
> #include "dcn10/dcn10_resource.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "dcn30/dcn30_dio_stream_encoder.h"
> #include "dcn301/dcn301_dio_link_encoder.h"
> #include "dcn301/dcn301_panel_cntl.h"
> @@ -843,6 +844,33 @@ static struct hubbub *dcn301_hubbub_create(struct dc_context *ctx)
> return &hubbub3->base;
> }
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> +static struct dio *dcn301_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct timing_generator *dcn301_timing_generator_create(
> struct dc_context *ctx, uint32_t instance)
> {
> @@ -1066,6 +1094,12 @@ static void dcn301_destruct(struct dcn301_resource_pool *pool)
> kfree(pool->base.hubbub);
> pool->base.hubbub = NULL;
> }
> +
> + if (pool->base.dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->base.dio));
> + pool->base.dio = NULL;
> + }
> +
> for (i = 0; i < pool->base.pipe_count; i++) {
> if (pool->base.dpps[i] != NULL)
> dcn301_dpp_destroy(&pool->base.dpps[i]);
> @@ -1582,6 +1616,14 @@ static bool dcn301_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn301_dio_create(ctx);
> + if (pool->base.dio == NULL) {
> + BREAK_TO_DEBUGGER();
> + dm_error("DC: failed to create dio!\n");
> + goto create_fail;
> + }
> +
> j = 0;
> /* HUBPs, DPPs, OPPs and TGs */
> for (i = 0; i < pool->base.pipe_count; i++) {
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
> index 1874d5d6b7820..d02aafd06fd45 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
> @@ -46,6 +46,7 @@
> #include "dml/dcn30/dcn30_fpu.h"
>
> #include "dcn10/dcn10_resource.h"
> +#include "dio/dcn10/dcn10_dio.h"
>
> #include "link_service.h"
>
> @@ -253,6 +254,33 @@ static const struct dcn20_vmid_mask vmid_masks = {
> DCN20_VMID_MASK_SH_LIST(_MASK)
> };
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> +static struct dio *dcn302_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct hubbub *dcn302_hubbub_create(struct dc_context *ctx)
> {
> int i;
> @@ -1022,6 +1050,11 @@ static void dcn302_resource_destruct(struct resource_pool *pool)
> pool->hubbub = NULL;
> }
>
> + if (pool->dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->dio));
> + pool->dio = NULL;
> + }
> +
> for (i = 0; i < pool->pipe_count; i++) {
> if (pool->dpps[i] != NULL) {
> kfree(TO_DCN20_DPP(pool->dpps[i]));
> @@ -1372,6 +1405,14 @@ static bool dcn302_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->dio = dcn302_dio_create(ctx);
> + if (pool->dio == NULL) {
> + BREAK_TO_DEBUGGER();
> + dm_error("DC: failed to create dio!\n");
> + goto create_fail;
> + }
> +
> /* HUBPs, DPPs, OPPs and TGs */
> for (i = 0; i < pool->pipe_count; i++) {
> pool->hubps[i] = dcn302_hubp_create(ctx, i);
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
> index d52201cb359fd..30b1403112c6c 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
> @@ -46,6 +46,7 @@
> #include "dml/dcn30/dcn30_fpu.h"
>
> #include "dcn10/dcn10_resource.h"
> +#include "dio/dcn10/dcn10_dio.h"
>
> #include "link_service.h"
>
> @@ -249,6 +250,33 @@ static const struct dcn20_vmid_mask vmid_masks = {
> DCN20_VMID_MASK_SH_LIST(_MASK)
> };
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> +static struct dio *dcn303_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct hubbub *dcn303_hubbub_create(struct dc_context *ctx)
> {
> int i;
> @@ -966,6 +994,11 @@ static void dcn303_resource_destruct(struct resource_pool *pool)
> pool->hubbub = NULL;
> }
>
> + if (pool->dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->dio));
> + pool->dio = NULL;
> + }
> +
> for (i = 0; i < pool->pipe_count; i++) {
> if (pool->dpps[i] != NULL) {
> kfree(TO_DCN20_DPP(pool->dpps[i]));
> @@ -1304,6 +1337,14 @@ static bool dcn303_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->dio = dcn303_dio_create(ctx);
> + if (pool->dio == NULL) {
> + BREAK_TO_DEBUGGER();
> + dm_error("DC: failed to create dio!\n");
> + goto create_fail;
> + }
> +
> /* HUBPs, DPPs, OPPs and TGs */
> for (i = 0; i < pool->pipe_count; i++) {
> pool->hubps[i] = dcn303_hubp_create(ctx, i);
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
> index 2055f1f8af652..4e9c041c707a6 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
> @@ -64,6 +64,7 @@
> #include "dce/dce_audio.h"
> #include "dce/dce_hwseq.h"
> #include "clk_mgr.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "dio/virtual/virtual_stream_encoder.h"
> #include "dce110/dce110_resource.h"
> #include "dml/display_mode_vba.h"
> @@ -810,6 +811,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
> DCN20_VMID_MASK_SH_LIST(_MASK)
> };
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> static const struct resource_caps res_cap_dcn31 = {
> .num_timing_generator = 4,
> .num_opp = 4,
> @@ -1021,6 +1037,18 @@ static struct mpc *dcn31_mpc_create(
> return &mpc30->base;
> }
>
> +static struct dio *dcn31_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
> {
> int i;
> @@ -1396,6 +1424,10 @@ static void dcn31_resource_destruct(struct dcn31_resource_pool *pool)
> kfree(pool->base.hubbub);
> pool->base.hubbub = NULL;
> }
> + if (pool->base.dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->base.dio));
> + pool->base.dio = NULL;
> + }
> for (i = 0; i < pool->base.pipe_count; i++) {
> if (pool->base.dpps[i] != NULL)
> dcn31_dpp_destroy(&pool->base.dpps[i]);
> @@ -2063,6 +2095,14 @@ static bool dcn31_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn31_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 and TGs */
> for (i = 0; i < pool->base.pipe_count; i++) {
> pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
> index 1939f720ba295..e26a6427916a0 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
> @@ -66,6 +66,7 @@
> #include "dce/dce_audio.h"
> #include "dce/dce_hwseq.h"
> #include "clk_mgr.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "dio/virtual/virtual_stream_encoder.h"
> #include "dce110/dce110_resource.h"
> #include "dml/display_mode_vba.h"
> @@ -822,6 +823,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
> DCN20_VMID_MASK_SH_LIST(_MASK)
> };
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> static const struct resource_caps res_cap_dcn314 = {
> .num_timing_generator = 4,
> .num_opp = 4,
> @@ -1079,6 +1095,18 @@ static struct mpc *dcn31_mpc_create(
> return &mpc30->base;
> }
>
> +static struct dio *dcn314_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
> {
> int i;
> @@ -1455,6 +1483,10 @@ static void dcn314_resource_destruct(struct dcn314_resource_pool *pool)
> kfree(pool->base.hubbub);
> pool->base.hubbub = NULL;
> }
> + if (pool->base.dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->base.dio));
> + pool->base.dio = NULL;
> + }
> for (i = 0; i < pool->base.pipe_count; i++) {
> if (pool->base.dpps[i] != NULL)
> dcn31_dpp_destroy(&pool->base.dpps[i]);
> @@ -1987,6 +2019,14 @@ static bool dcn314_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn314_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 and TGs */
> for (i = 0; i < pool->base.pipe_count; i++) {
> pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
> index e8377c190f635..131a6cd4c7352 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
> @@ -63,6 +63,7 @@
> #include "dce/dce_audio.h"
> #include "dce/dce_hwseq.h"
> #include "clk_mgr.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "dio/virtual/virtual_stream_encoder.h"
> #include "dce110/dce110_resource.h"
> #include "dml/display_mode_vba.h"
> @@ -809,6 +810,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
> DCN20_VMID_MASK_SH_LIST(_MASK)
> };
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> static const struct resource_caps res_cap_dcn31 = {
> .num_timing_generator = 4,
> .num_opp = 4,
> @@ -1020,6 +1036,18 @@ static struct mpc *dcn31_mpc_create(
> return &mpc30->base;
> }
>
> +static struct dio *dcn315_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
> {
> int i;
> @@ -1397,6 +1425,10 @@ static void dcn315_resource_destruct(struct dcn315_resource_pool *pool)
> kfree(pool->base.hubbub);
> pool->base.hubbub = NULL;
> }
> + if (pool->base.dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->base.dio));
> + pool->base.dio = NULL;
> + }
> for (i = 0; i < pool->base.pipe_count; i++) {
> if (pool->base.dpps[i] != NULL)
> dcn31_dpp_destroy(&pool->base.dpps[i]);
> @@ -2012,6 +2044,14 @@ static bool dcn315_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn315_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 and TGs */
> for (i = 0; i < pool->base.pipe_count; i++) {
> pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
> index 045ce01bd74eb..c8c0ce6efcfdc 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
> @@ -63,6 +63,7 @@
> #include "dce/dce_audio.h"
> #include "dce/dce_hwseq.h"
> #include "clk_mgr.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "dio/virtual/virtual_stream_encoder.h"
> #include "dce110/dce110_resource.h"
> #include "dml/display_mode_vba.h"
> @@ -804,6 +805,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
> DCN20_VMID_MASK_SH_LIST(_MASK)
> };
>
> +static const struct dcn_dio_registers dio_regs = {
> + DIO_REG_LIST_DCN10()
> +};
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> static const struct resource_caps res_cap_dcn31 = {
> .num_timing_generator = 4,
> .num_opp = 4,
> @@ -1013,6 +1029,18 @@ static struct mpc *dcn31_mpc_create(
> return &mpc30->base;
> }
>
> +static struct dio *dcn316_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
> {
> int i;
> @@ -1392,6 +1420,10 @@ static void dcn316_resource_destruct(struct dcn316_resource_pool *pool)
> kfree(pool->base.hubbub);
> pool->base.hubbub = NULL;
> }
> + if (pool->base.dio != NULL) {
> + kfree(TO_DCN10_DIO(pool->base.dio));
> + pool->base.dio = NULL;
> + }
> for (i = 0; i < pool->base.pipe_count; i++) {
> if (pool->base.dpps[i] != NULL)
> dcn31_dpp_destroy(&pool->base.dpps[i]);
> @@ -1887,6 +1919,14 @@ static bool dcn316_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn316_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 and TGs */
> for (i = 0; i < pool->base.pipe_count; i++) {
> pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
> index c7fd604024d64..c3a6ae14de18b 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
> @@ -66,6 +66,7 @@
> #include "dce/dce_hwseq.h"
> #include "clk_mgr.h"
> #include "dio/virtual/virtual_stream_encoder.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "dml/display_mode_vba.h"
> #include "dcn32/dcn32_dccg.h"
> #include "dcn10/dcn10_resource.h"
> @@ -643,6 +644,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
> DCN20_VMID_MASK_SH_LIST(_MASK)
> };
>
> +static struct dcn_dio_registers dio_regs;
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> static const struct resource_caps res_cap_dcn32 = {
> .num_timing_generator = 4,
> .num_opp = 4,
> @@ -833,6 +847,22 @@ static struct clock_source *dcn32_clock_source_create(
> return NULL;
> }
>
> +static struct dio *dcn32_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> +#undef REG_STRUCT
> +#define REG_STRUCT dio_regs
> + DIO_REG_LIST_DCN10();
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct hubbub *dcn32_hubbub_create(struct dc_context *ctx)
> {
> int i;
> @@ -1494,6 +1524,11 @@ static void dcn32_resource_destruct(struct dcn32_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;
>
> @@ -2373,6 +2408,14 @@ static bool dcn32_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn32_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++) {
>
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
> index c1582c27ac872..990aec7eb3d07 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
> @@ -69,6 +69,7 @@
> #include "dce/dce_hwseq.h"
> #include "clk_mgr.h"
> #include "dio/virtual/virtual_stream_encoder.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "dml/display_mode_vba.h"
> #include "dcn32/dcn32_dccg.h"
> #include "dcn10/dcn10_resource.h"
> @@ -639,6 +640,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
> DCN20_VMID_MASK_SH_LIST(_MASK)
> };
>
> +static struct dcn_dio_registers dio_regs;
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> static const struct resource_caps res_cap_dcn321 = {
> .num_timing_generator = 4,
> .num_opp = 4,
> @@ -827,6 +841,22 @@ static struct clock_source *dcn321_clock_source_create(
> return NULL;
> }
>
> +static struct dio *dcn321_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> +#undef REG_STRUCT
> +#define REG_STRUCT dio_regs
> + DIO_REG_LIST_DCN10();
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct hubbub *dcn321_hubbub_create(struct dc_context *ctx)
> {
> int i;
> @@ -1474,6 +1504,11 @@ static void dcn321_resource_destruct(struct dcn321_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;
>
> @@ -1872,6 +1907,14 @@ static bool dcn321_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn321_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++) {
>
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
> index 3494a40cea99f..598b2f25881da 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
> @@ -71,6 +71,7 @@
> #include "dce/dce_hwseq.h"
> #include "clk_mgr.h"
> #include "dio/virtual/virtual_stream_encoder.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "dce110/dce110_resource.h"
> #include "dml/display_mode_vba.h"
> #include "dcn35/dcn35_dccg.h"
> @@ -664,6 +665,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
> DCN20_VMID_MASK_SH_LIST(_MASK)
> };
>
> +static struct dcn_dio_registers dio_regs;
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> static const struct resource_caps res_cap_dcn35 = {
> .num_timing_generator = 4,
> .num_opp = 4,
> @@ -973,6 +987,22 @@ static struct mpc *dcn35_mpc_create(
> return &mpc30->base;
> }
>
> +static struct dio *dcn35_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> +#undef REG_STRUCT
> +#define REG_STRUCT dio_regs
> + DIO_REG_LIST_DCN10();
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
> {
> int i;
> @@ -1563,6 +1593,11 @@ static void dcn35_resource_destruct(struct dcn35_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;
> + }
> }
>
> static struct hubp *dcn35_hubp_create(
> @@ -2033,6 +2068,14 @@ static bool dcn35_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn35_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 and TGs */
> for (i = 0; i < pool->base.pipe_count; i++) {
> pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
> index 080bc7f24ffaa..7e15d07df7a33 100644
> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
> @@ -50,6 +50,7 @@
> #include "dce/dce_hwseq.h"
> #include "clk_mgr.h"
> #include "dio/virtual/virtual_stream_encoder.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "dce110/dce110_resource.h"
> #include "dml/display_mode_vba.h"
> #include "dcn35/dcn35_dccg.h"
> @@ -644,6 +645,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
> DCN20_VMID_MASK_SH_LIST(_MASK)
> };
>
> +static struct dcn_dio_registers dio_regs;
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> static const struct resource_caps res_cap_dcn351 = {
> .num_timing_generator = 4,
> .num_opp = 4,
> @@ -953,6 +967,22 @@ static struct mpc *dcn35_mpc_create(
> return &mpc30->base;
> }
>
> +static struct dio *dcn351_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> +#undef REG_STRUCT
> +#define REG_STRUCT dio_regs
> + DIO_REG_LIST_DCN10();
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
> {
> int i;
> @@ -1543,6 +1573,11 @@ static void dcn351_resource_destruct(struct dcn351_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;
> + }
> }
>
> static struct hubp *dcn35_hubp_create(
> @@ -2005,6 +2040,14 @@ static bool dcn351_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn351_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 and TGs */
> for (i = 0; i < pool->base.pipe_count; i++) {
> pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
> 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 af51ac4ea59e2..83fee2ca61bff 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
> @@ -50,6 +50,7 @@
> #include "dce/dce_hwseq.h"
> #include "clk_mgr.h"
> #include "dio/virtual/virtual_stream_encoder.h"
> +#include "dio/dcn10/dcn10_dio.h"
> #include "dce110/dce110_resource.h"
> #include "dml/display_mode_vba.h"
> #include "dcn35/dcn35_dccg.h"
> @@ -651,6 +652,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
> DCN20_VMID_MASK_SH_LIST(_MASK)
> };
>
> +static struct dcn_dio_registers dio_regs;
> +
> +#define DIO_MASK_SH_LIST(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(__SHIFT)
> +};
> +
> +static const struct dcn_dio_mask dio_mask = {
> + DIO_MASK_SH_LIST(_MASK)
> +};
> +
> static const struct resource_caps res_cap_dcn36 = {
> .num_timing_generator = 4,
> .num_opp = 4,
> @@ -960,6 +974,22 @@ static struct mpc *dcn35_mpc_create(
> return &mpc30->base;
> }
>
> +static struct dio *dcn36_dio_create(struct dc_context *ctx)
> +{
> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
> +
> + if (!dio10)
> + return NULL;
> +
> +#undef REG_STRUCT
> +#define REG_STRUCT dio_regs
> + DIO_REG_LIST_DCN10();
> +
> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
> +
> + return &dio10->base;
> +}
> +
> static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
> {
> int i;
> @@ -1550,6 +1580,11 @@ static void dcn36_resource_destruct(struct dcn36_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;
> + }
> }
>
> static struct hubp *dcn35_hubp_create(
> @@ -2012,6 +2047,14 @@ static bool dcn36_resource_construct(
> goto create_fail;
> }
>
> + /* DIO */
> + pool->base.dio = dcn36_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 and TGs */
> for (i = 0; i < pool->base.pipe_count; i++) {
> pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations
2026-03-24 14:37 ` Alex Deucher
@ 2026-03-24 16:42 ` LIPSKI, IVAN
2026-04-01 7:14 ` Ionut Nechita (Sunlight Linux)
0 siblings, 1 reply; 5+ messages in thread
From: LIPSKI, IVAN @ 2026-03-24 16:42 UTC (permalink / raw)
To: Alex Deucher, Ionut Nechita (Sunlight Linux), LIPSKI, IVAN
Cc: amd-gfx, harry.wentland, sunpeng.li, siqueira, alexander.deucher,
christian.koenig, airlied, simona, dri-devel, Ionut Nechita
On 3/24/2026 10:37 AM, Alex Deucher wrote:
> + Ivan
>
> On Mon, Mar 23, 2026 at 5:24 PM Ionut Nechita (Sunlight Linux)
> <sunlightlinux@gmail.com> wrote:
>>
>> From: Ionut Nechita <ionut_n2001@yahoo.com>
>>
>> Description:
>> - Commit b82f0759346617b2 ("drm/amd/display: Migrate DIO registers access
>> from hwseq to dio component") moved DIO_MEM_PWR_CTRL register access
>> behind the new dio abstraction layer but only created the dio object for
>> DCN 4.01. On all other generations (DCN 10/20/21/201/30/301/302/303/
>> 31/314/315/316/32/321/35/351/36), the dio pointer is NULL, causing the
>> register write to be silently skipped.
>>
>> This results in AFMT HDMI memory not being powered on during init_hw,
>> which can cause HDMI audio failures and display issues on affected
>> hardware including Renoir/Cezanne (DCN 2.1) APUs that use dcn10_init_hw.
>>
>> Call dcn10_dio_construct() in each older DCN generation's resource.c
>> to create the dio object, following the same pattern as DCN 4.01. This
>> ensures the dio pointer is non-NULL and the mem_pwr_ctrl callback works
>> through the dio abstraction for all DCN generations.
>>
>> Fixes: b82f0759346617b2 ("drm/amd/display: Migrate DIO registers access from hwseq to dio component.")
>> Signed-off-by: Ionut Nechita <ionut_n2001@yahoo.com>
Thank you, Ionut.
We'll test this patch in the next week's display driver promotion cycle
before merging.
In the meantime, this patch is
Reviewed-by: Ivan Lipski <ivan.lipski@amd.com>
>> ---
>> .../dc/resource/dcn10/dcn10_resource.c | 41 ++++++++++++++++++
>> .../dc/resource/dcn20/dcn20_resource.c | 42 ++++++++++++++++++
>> .../dc/resource/dcn201/dcn201_resource.c | 41 ++++++++++++++++++
>> .../dc/resource/dcn21/dcn21_resource.c | 34 +++++++++++++++
>> .../dc/resource/dcn30/dcn30_resource.c | 42 ++++++++++++++++++
>> .../dc/resource/dcn301/dcn301_resource.c | 42 ++++++++++++++++++
>> .../dc/resource/dcn302/dcn302_resource.c | 41 ++++++++++++++++++
>> .../dc/resource/dcn303/dcn303_resource.c | 41 ++++++++++++++++++
>> .../dc/resource/dcn31/dcn31_resource.c | 40 +++++++++++++++++
>> .../dc/resource/dcn314/dcn314_resource.c | 40 +++++++++++++++++
>> .../dc/resource/dcn315/dcn315_resource.c | 40 +++++++++++++++++
>> .../dc/resource/dcn316/dcn316_resource.c | 40 +++++++++++++++++
>> .../dc/resource/dcn32/dcn32_resource.c | 43 +++++++++++++++++++
>> .../dc/resource/dcn321/dcn321_resource.c | 43 +++++++++++++++++++
>> .../dc/resource/dcn35/dcn35_resource.c | 43 +++++++++++++++++++
>> .../dc/resource/dcn351/dcn351_resource.c | 43 +++++++++++++++++++
>> .../dc/resource/dcn36/dcn36_resource.c | 43 +++++++++++++++++++
>> 17 files changed, 699 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c
>> index bbe185e15eb67..4663456a736a2 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c
>> @@ -71,6 +71,7 @@
>> #include "dce/dce_dmcu.h"
>> #include "dce/dce_aux.h"
>> #include "dce/dce_i2c.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>>
>> #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
>> #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x210f
>> @@ -444,6 +445,33 @@ static const struct dcn_hubbub_mask hubbub_mask = {
>> HUBBUB_MASK_SH_LIST_DCN10(_MASK)
>> };
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> +static struct dio *dcn10_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static int map_transmitter_id_to_phy_instance(
>> enum transmitter transmitter)
>> {
>> @@ -917,6 +945,11 @@ static void dcn10_resource_destruct(struct dcn10_resource_pool *pool)
>> kfree(pool->base.hubbub);
>> pool->base.hubbub = NULL;
>>
>> + if (pool->base.dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->base.dio));
>> + pool->base.dio = NULL;
>> + }
>> +
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> if (pool->base.opps[i] != NULL)
>> pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
>> @@ -1653,6 +1686,14 @@ static bool dcn10_resource_construct(
>> goto fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn10_dio_create(ctx);
>> + if (pool->base.dio == NULL) {
>> + BREAK_TO_DEBUGGER();
>> + dm_error("DC: failed to create dio!\n");
>> + goto fail;
>> + }
>> +
>> if (!resource_construct(num_virtual_links, dc, &pool->base,
>> &res_create_funcs))
>> goto fail;
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
>> index 8b555187ac753..74e8d229c9dd3 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
>> @@ -82,6 +82,7 @@
>> #include "dce/dce_dmcu.h"
>> #include "dce/dce_aux.h"
>> #include "dce/dce_i2c.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "vm_helper.h"
>>
>> #include "link_enc_cfg.h"
>> @@ -550,6 +551,33 @@ static const struct dcn_hubbub_mask hubbub_mask = {
>> HUBBUB_MASK_SH_LIST_DCN20(_MASK)
>> };
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> +static struct dio *dcn20_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> #define vmid_regs(id)\
>> [id] = {\
>> DCN20_VMID_REG_LIST(id)\
>> @@ -1104,6 +1132,12 @@ static void dcn20_resource_destruct(struct dcn20_resource_pool *pool)
>> kfree(pool->base.hubbub);
>> pool->base.hubbub = NULL;
>> }
>> +
>> + if (pool->base.dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->base.dio));
>> + pool->base.dio = NULL;
>> + }
>> +
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> if (pool->base.dpps[i] != NULL)
>> dcn20_dpp_destroy(&pool->base.dpps[i]);
>> @@ -2692,6 +2726,14 @@ static bool dcn20_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn20_dio_create(ctx);
>> + if (pool->base.dio == NULL) {
>> + BREAK_TO_DEBUGGER();
>> + dm_error("DC: failed to create dio!\n");
>> + goto create_fail;
>> + }
>> +
>> for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
>> pool->base.dscs[i] = dcn20_dsc_create(ctx, i);
>> if (pool->base.dscs[i] == NULL) {
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
>> index 4ea76e46ab15d..e289be70efb54 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
>> @@ -56,6 +56,7 @@
>> #include "dce/dce_aux.h"
>> #include "dce/dce_i2c.h"
>> #include "dcn10/dcn10_resource.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>>
>> #include "cyan_skillfish_ip_offset.h"
>>
>> @@ -755,6 +756,33 @@ static struct hubbub *dcn201_hubbub_create(struct dc_context *ctx)
>> return &hubbub->base;
>> }
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> +static struct dio *dcn201_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct timing_generator *dcn201_timing_generator_create(
>> struct dc_context *ctx,
>> uint32_t instance)
>> @@ -930,6 +958,11 @@ static void dcn201_resource_destruct(struct dcn201_resource_pool *pool)
>> pool->base.hubbub = NULL;
>> }
>>
>> + if (pool->base.dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->base.dio));
>> + pool->base.dio = NULL;
>> + }
>> +
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> if (pool->base.dpps[i] != NULL)
>> dcn201_dpp_destroy(&pool->base.dpps[i]);
>> @@ -1276,6 +1309,14 @@ static bool dcn201_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn201_dio_create(ctx);
>> + if (pool->base.dio == NULL) {
>> + BREAK_TO_DEBUGGER();
>> + dm_error("DC: failed to create dio!\n");
>> + goto create_fail;
>> + }
>> +
>> if (!resource_construct(num_virtual_links, dc, &pool->base,
>> &res_create_funcs))
>> goto create_fail;
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
>> index 0f4307f8f3dd5..4333baac96ad7 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
>> @@ -84,6 +84,7 @@
>> #include "dce/dce_dmcu.h"
>> #include "dce/dce_aux.h"
>> #include "dce/dce_i2c.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "dcn21_resource.h"
>> #include "vm_helper.h"
>> #include "dcn20/dcn20_vmid.h"
>> @@ -329,6 +330,25 @@ static const struct dcn_hubbub_mask hubbub_mask = {
>> HUBBUB_MASK_SH_LIST_DCN21(_MASK)
>> };
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +static const struct dcn_dio_shift dio_shift = { 0 };
>> +
>> +static const struct dcn_dio_mask dio_mask = { 0 };
>> +
>> +static struct dio *dcn21_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>>
>> #define vmid_regs(id)\
>> [id] = {\
>> @@ -677,6 +697,12 @@ static void dcn21_resource_destruct(struct dcn21_resource_pool *pool)
>> kfree(pool->base.hubbub);
>> pool->base.hubbub = NULL;
>> }
>> +
>> + if (pool->base.dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->base.dio));
>> + pool->base.dio = NULL;
>> + }
>> +
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> if (pool->base.dpps[i] != NULL)
>> dcn20_dpp_destroy(&pool->base.dpps[i]);
>> @@ -1654,6 +1680,14 @@ static bool dcn21_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn21_dio_create(ctx);
>> + if (pool->base.dio == NULL) {
>> + BREAK_TO_DEBUGGER();
>> + dm_error("DC: failed to create dio!\n");
>> + goto create_fail;
>> + }
>> +
>> for (i = 0; i < pool->base.res_cap->num_dsc; i++) {
>> pool->base.dscs[i] = dcn21_dsc_create(ctx, i);
>> if (pool->base.dscs[i] == NULL) {
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
>> index 2fa86b9587ed0..87b7b4ee04c64 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
>> @@ -60,6 +60,7 @@
>> #include "dml/display_mode_vba.h"
>> #include "dcn30/dcn30_dccg.h"
>> #include "dcn10/dcn10_resource.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "link_service.h"
>> #include "dce/dce_panel_cntl.h"
>>
>> @@ -886,6 +887,33 @@ static struct hubbub *dcn30_hubbub_create(struct dc_context *ctx)
>> return &hubbub3->base;
>> }
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> +static struct dio *dcn30_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct timing_generator *dcn30_timing_generator_create(
>> struct dc_context *ctx,
>> uint32_t instance)
>> @@ -1095,6 +1123,12 @@ static void dcn30_resource_destruct(struct dcn30_resource_pool *pool)
>> kfree(pool->base.hubbub);
>> pool->base.hubbub = NULL;
>> }
>> +
>> + if (pool->base.dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->base.dio));
>> + pool->base.dio = NULL;
>> + }
>> +
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> if (pool->base.dpps[i] != NULL)
>> dcn30_dpp_destroy(&pool->base.dpps[i]);
>> @@ -2464,6 +2498,14 @@ static bool dcn30_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn30_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 and TGs */
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> pool->base.hubps[i] = dcn30_hubp_create(ctx, i);
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
>> index 7842bee57e636..6bb1c62124bb4 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
>> @@ -59,6 +59,7 @@
>> #include "dml/display_mode_vba.h"
>> #include "dcn301/dcn301_dccg.h"
>> #include "dcn10/dcn10_resource.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "dcn30/dcn30_dio_stream_encoder.h"
>> #include "dcn301/dcn301_dio_link_encoder.h"
>> #include "dcn301/dcn301_panel_cntl.h"
>> @@ -843,6 +844,33 @@ static struct hubbub *dcn301_hubbub_create(struct dc_context *ctx)
>> return &hubbub3->base;
>> }
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> +static struct dio *dcn301_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct timing_generator *dcn301_timing_generator_create(
>> struct dc_context *ctx, uint32_t instance)
>> {
>> @@ -1066,6 +1094,12 @@ static void dcn301_destruct(struct dcn301_resource_pool *pool)
>> kfree(pool->base.hubbub);
>> pool->base.hubbub = NULL;
>> }
>> +
>> + if (pool->base.dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->base.dio));
>> + pool->base.dio = NULL;
>> + }
>> +
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> if (pool->base.dpps[i] != NULL)
>> dcn301_dpp_destroy(&pool->base.dpps[i]);
>> @@ -1582,6 +1616,14 @@ static bool dcn301_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn301_dio_create(ctx);
>> + if (pool->base.dio == NULL) {
>> + BREAK_TO_DEBUGGER();
>> + dm_error("DC: failed to create dio!\n");
>> + goto create_fail;
>> + }
>> +
>> j = 0;
>> /* HUBPs, DPPs, OPPs and TGs */
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
>> index 1874d5d6b7820..d02aafd06fd45 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
>> @@ -46,6 +46,7 @@
>> #include "dml/dcn30/dcn30_fpu.h"
>>
>> #include "dcn10/dcn10_resource.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>>
>> #include "link_service.h"
>>
>> @@ -253,6 +254,33 @@ static const struct dcn20_vmid_mask vmid_masks = {
>> DCN20_VMID_MASK_SH_LIST(_MASK)
>> };
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> +static struct dio *dcn302_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct hubbub *dcn302_hubbub_create(struct dc_context *ctx)
>> {
>> int i;
>> @@ -1022,6 +1050,11 @@ static void dcn302_resource_destruct(struct resource_pool *pool)
>> pool->hubbub = NULL;
>> }
>>
>> + if (pool->dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->dio));
>> + pool->dio = NULL;
>> + }
>> +
>> for (i = 0; i < pool->pipe_count; i++) {
>> if (pool->dpps[i] != NULL) {
>> kfree(TO_DCN20_DPP(pool->dpps[i]));
>> @@ -1372,6 +1405,14 @@ static bool dcn302_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->dio = dcn302_dio_create(ctx);
>> + if (pool->dio == NULL) {
>> + BREAK_TO_DEBUGGER();
>> + dm_error("DC: failed to create dio!\n");
>> + goto create_fail;
>> + }
>> +
>> /* HUBPs, DPPs, OPPs and TGs */
>> for (i = 0; i < pool->pipe_count; i++) {
>> pool->hubps[i] = dcn302_hubp_create(ctx, i);
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
>> index d52201cb359fd..30b1403112c6c 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
>> @@ -46,6 +46,7 @@
>> #include "dml/dcn30/dcn30_fpu.h"
>>
>> #include "dcn10/dcn10_resource.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>>
>> #include "link_service.h"
>>
>> @@ -249,6 +250,33 @@ static const struct dcn20_vmid_mask vmid_masks = {
>> DCN20_VMID_MASK_SH_LIST(_MASK)
>> };
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> +static struct dio *dcn303_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct hubbub *dcn303_hubbub_create(struct dc_context *ctx)
>> {
>> int i;
>> @@ -966,6 +994,11 @@ static void dcn303_resource_destruct(struct resource_pool *pool)
>> pool->hubbub = NULL;
>> }
>>
>> + if (pool->dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->dio));
>> + pool->dio = NULL;
>> + }
>> +
>> for (i = 0; i < pool->pipe_count; i++) {
>> if (pool->dpps[i] != NULL) {
>> kfree(TO_DCN20_DPP(pool->dpps[i]));
>> @@ -1304,6 +1337,14 @@ static bool dcn303_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->dio = dcn303_dio_create(ctx);
>> + if (pool->dio == NULL) {
>> + BREAK_TO_DEBUGGER();
>> + dm_error("DC: failed to create dio!\n");
>> + goto create_fail;
>> + }
>> +
>> /* HUBPs, DPPs, OPPs and TGs */
>> for (i = 0; i < pool->pipe_count; i++) {
>> pool->hubps[i] = dcn303_hubp_create(ctx, i);
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
>> index 2055f1f8af652..4e9c041c707a6 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
>> @@ -64,6 +64,7 @@
>> #include "dce/dce_audio.h"
>> #include "dce/dce_hwseq.h"
>> #include "clk_mgr.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "dio/virtual/virtual_stream_encoder.h"
>> #include "dce110/dce110_resource.h"
>> #include "dml/display_mode_vba.h"
>> @@ -810,6 +811,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
>> DCN20_VMID_MASK_SH_LIST(_MASK)
>> };
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> static const struct resource_caps res_cap_dcn31 = {
>> .num_timing_generator = 4,
>> .num_opp = 4,
>> @@ -1021,6 +1037,18 @@ static struct mpc *dcn31_mpc_create(
>> return &mpc30->base;
>> }
>>
>> +static struct dio *dcn31_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
>> {
>> int i;
>> @@ -1396,6 +1424,10 @@ static void dcn31_resource_destruct(struct dcn31_resource_pool *pool)
>> kfree(pool->base.hubbub);
>> pool->base.hubbub = NULL;
>> }
>> + if (pool->base.dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->base.dio));
>> + pool->base.dio = NULL;
>> + }
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> if (pool->base.dpps[i] != NULL)
>> dcn31_dpp_destroy(&pool->base.dpps[i]);
>> @@ -2063,6 +2095,14 @@ static bool dcn31_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn31_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 and TGs */
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
>> index 1939f720ba295..e26a6427916a0 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
>> @@ -66,6 +66,7 @@
>> #include "dce/dce_audio.h"
>> #include "dce/dce_hwseq.h"
>> #include "clk_mgr.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "dio/virtual/virtual_stream_encoder.h"
>> #include "dce110/dce110_resource.h"
>> #include "dml/display_mode_vba.h"
>> @@ -822,6 +823,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
>> DCN20_VMID_MASK_SH_LIST(_MASK)
>> };
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> static const struct resource_caps res_cap_dcn314 = {
>> .num_timing_generator = 4,
>> .num_opp = 4,
>> @@ -1079,6 +1095,18 @@ static struct mpc *dcn31_mpc_create(
>> return &mpc30->base;
>> }
>>
>> +static struct dio *dcn314_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
>> {
>> int i;
>> @@ -1455,6 +1483,10 @@ static void dcn314_resource_destruct(struct dcn314_resource_pool *pool)
>> kfree(pool->base.hubbub);
>> pool->base.hubbub = NULL;
>> }
>> + if (pool->base.dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->base.dio));
>> + pool->base.dio = NULL;
>> + }
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> if (pool->base.dpps[i] != NULL)
>> dcn31_dpp_destroy(&pool->base.dpps[i]);
>> @@ -1987,6 +2019,14 @@ static bool dcn314_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn314_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 and TGs */
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
>> index e8377c190f635..131a6cd4c7352 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
>> @@ -63,6 +63,7 @@
>> #include "dce/dce_audio.h"
>> #include "dce/dce_hwseq.h"
>> #include "clk_mgr.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "dio/virtual/virtual_stream_encoder.h"
>> #include "dce110/dce110_resource.h"
>> #include "dml/display_mode_vba.h"
>> @@ -809,6 +810,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
>> DCN20_VMID_MASK_SH_LIST(_MASK)
>> };
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> static const struct resource_caps res_cap_dcn31 = {
>> .num_timing_generator = 4,
>> .num_opp = 4,
>> @@ -1020,6 +1036,18 @@ static struct mpc *dcn31_mpc_create(
>> return &mpc30->base;
>> }
>>
>> +static struct dio *dcn315_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
>> {
>> int i;
>> @@ -1397,6 +1425,10 @@ static void dcn315_resource_destruct(struct dcn315_resource_pool *pool)
>> kfree(pool->base.hubbub);
>> pool->base.hubbub = NULL;
>> }
>> + if (pool->base.dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->base.dio));
>> + pool->base.dio = NULL;
>> + }
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> if (pool->base.dpps[i] != NULL)
>> dcn31_dpp_destroy(&pool->base.dpps[i]);
>> @@ -2012,6 +2044,14 @@ static bool dcn315_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn315_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 and TGs */
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
>> index 045ce01bd74eb..c8c0ce6efcfdc 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
>> @@ -63,6 +63,7 @@
>> #include "dce/dce_audio.h"
>> #include "dce/dce_hwseq.h"
>> #include "clk_mgr.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "dio/virtual/virtual_stream_encoder.h"
>> #include "dce110/dce110_resource.h"
>> #include "dml/display_mode_vba.h"
>> @@ -804,6 +805,21 @@ static const struct dcn20_vmid_mask vmid_masks = {
>> DCN20_VMID_MASK_SH_LIST(_MASK)
>> };
>>
>> +static const struct dcn_dio_registers dio_regs = {
>> + DIO_REG_LIST_DCN10()
>> +};
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> static const struct resource_caps res_cap_dcn31 = {
>> .num_timing_generator = 4,
>> .num_opp = 4,
>> @@ -1013,6 +1029,18 @@ static struct mpc *dcn31_mpc_create(
>> return &mpc30->base;
>> }
>>
>> +static struct dio *dcn316_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx)
>> {
>> int i;
>> @@ -1392,6 +1420,10 @@ static void dcn316_resource_destruct(struct dcn316_resource_pool *pool)
>> kfree(pool->base.hubbub);
>> pool->base.hubbub = NULL;
>> }
>> + if (pool->base.dio != NULL) {
>> + kfree(TO_DCN10_DIO(pool->base.dio));
>> + pool->base.dio = NULL;
>> + }
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> if (pool->base.dpps[i] != NULL)
>> dcn31_dpp_destroy(&pool->base.dpps[i]);
>> @@ -1887,6 +1919,14 @@ static bool dcn316_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn316_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 and TGs */
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> pool->base.hubps[i] = dcn31_hubp_create(ctx, i);
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
>> index c7fd604024d64..c3a6ae14de18b 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
>> @@ -66,6 +66,7 @@
>> #include "dce/dce_hwseq.h"
>> #include "clk_mgr.h"
>> #include "dio/virtual/virtual_stream_encoder.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "dml/display_mode_vba.h"
>> #include "dcn32/dcn32_dccg.h"
>> #include "dcn10/dcn10_resource.h"
>> @@ -643,6 +644,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
>> DCN20_VMID_MASK_SH_LIST(_MASK)
>> };
>>
>> +static struct dcn_dio_registers dio_regs;
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> static const struct resource_caps res_cap_dcn32 = {
>> .num_timing_generator = 4,
>> .num_opp = 4,
>> @@ -833,6 +847,22 @@ static struct clock_source *dcn32_clock_source_create(
>> return NULL;
>> }
>>
>> +static struct dio *dcn32_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> +#undef REG_STRUCT
>> +#define REG_STRUCT dio_regs
>> + DIO_REG_LIST_DCN10();
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct hubbub *dcn32_hubbub_create(struct dc_context *ctx)
>> {
>> int i;
>> @@ -1494,6 +1524,11 @@ static void dcn32_resource_destruct(struct dcn32_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;
>>
>> @@ -2373,6 +2408,14 @@ static bool dcn32_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn32_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++) {
>>
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
>> index c1582c27ac872..990aec7eb3d07 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
>> @@ -69,6 +69,7 @@
>> #include "dce/dce_hwseq.h"
>> #include "clk_mgr.h"
>> #include "dio/virtual/virtual_stream_encoder.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "dml/display_mode_vba.h"
>> #include "dcn32/dcn32_dccg.h"
>> #include "dcn10/dcn10_resource.h"
>> @@ -639,6 +640,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
>> DCN20_VMID_MASK_SH_LIST(_MASK)
>> };
>>
>> +static struct dcn_dio_registers dio_regs;
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> static const struct resource_caps res_cap_dcn321 = {
>> .num_timing_generator = 4,
>> .num_opp = 4,
>> @@ -827,6 +841,22 @@ static struct clock_source *dcn321_clock_source_create(
>> return NULL;
>> }
>>
>> +static struct dio *dcn321_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> +#undef REG_STRUCT
>> +#define REG_STRUCT dio_regs
>> + DIO_REG_LIST_DCN10();
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct hubbub *dcn321_hubbub_create(struct dc_context *ctx)
>> {
>> int i;
>> @@ -1474,6 +1504,11 @@ static void dcn321_resource_destruct(struct dcn321_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;
>>
>> @@ -1872,6 +1907,14 @@ static bool dcn321_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn321_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++) {
>>
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
>> index 3494a40cea99f..598b2f25881da 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
>> @@ -71,6 +71,7 @@
>> #include "dce/dce_hwseq.h"
>> #include "clk_mgr.h"
>> #include "dio/virtual/virtual_stream_encoder.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "dce110/dce110_resource.h"
>> #include "dml/display_mode_vba.h"
>> #include "dcn35/dcn35_dccg.h"
>> @@ -664,6 +665,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
>> DCN20_VMID_MASK_SH_LIST(_MASK)
>> };
>>
>> +static struct dcn_dio_registers dio_regs;
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> static const struct resource_caps res_cap_dcn35 = {
>> .num_timing_generator = 4,
>> .num_opp = 4,
>> @@ -973,6 +987,22 @@ static struct mpc *dcn35_mpc_create(
>> return &mpc30->base;
>> }
>>
>> +static struct dio *dcn35_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> +#undef REG_STRUCT
>> +#define REG_STRUCT dio_regs
>> + DIO_REG_LIST_DCN10();
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
>> {
>> int i;
>> @@ -1563,6 +1593,11 @@ static void dcn35_resource_destruct(struct dcn35_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;
>> + }
>> }
>>
>> static struct hubp *dcn35_hubp_create(
>> @@ -2033,6 +2068,14 @@ static bool dcn35_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn35_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 and TGs */
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
>> diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
>> index 080bc7f24ffaa..7e15d07df7a33 100644
>> --- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
>> +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
>> @@ -50,6 +50,7 @@
>> #include "dce/dce_hwseq.h"
>> #include "clk_mgr.h"
>> #include "dio/virtual/virtual_stream_encoder.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "dce110/dce110_resource.h"
>> #include "dml/display_mode_vba.h"
>> #include "dcn35/dcn35_dccg.h"
>> @@ -644,6 +645,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
>> DCN20_VMID_MASK_SH_LIST(_MASK)
>> };
>>
>> +static struct dcn_dio_registers dio_regs;
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> static const struct resource_caps res_cap_dcn351 = {
>> .num_timing_generator = 4,
>> .num_opp = 4,
>> @@ -953,6 +967,22 @@ static struct mpc *dcn35_mpc_create(
>> return &mpc30->base;
>> }
>>
>> +static struct dio *dcn351_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> +#undef REG_STRUCT
>> +#define REG_STRUCT dio_regs
>> + DIO_REG_LIST_DCN10();
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
>> {
>> int i;
>> @@ -1543,6 +1573,11 @@ static void dcn351_resource_destruct(struct dcn351_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;
>> + }
>> }
>>
>> static struct hubp *dcn35_hubp_create(
>> @@ -2005,6 +2040,14 @@ static bool dcn351_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn351_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 and TGs */
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
>> 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 af51ac4ea59e2..83fee2ca61bff 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
>> @@ -50,6 +50,7 @@
>> #include "dce/dce_hwseq.h"
>> #include "clk_mgr.h"
>> #include "dio/virtual/virtual_stream_encoder.h"
>> +#include "dio/dcn10/dcn10_dio.h"
>> #include "dce110/dce110_resource.h"
>> #include "dml/display_mode_vba.h"
>> #include "dcn35/dcn35_dccg.h"
>> @@ -651,6 +652,19 @@ static const struct dcn20_vmid_mask vmid_masks = {
>> DCN20_VMID_MASK_SH_LIST(_MASK)
>> };
>>
>> +static struct dcn_dio_registers dio_regs;
>> +
>> +#define DIO_MASK_SH_LIST(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(__SHIFT)
>> +};
>> +
>> +static const struct dcn_dio_mask dio_mask = {
>> + DIO_MASK_SH_LIST(_MASK)
>> +};
>> +
>> static const struct resource_caps res_cap_dcn36 = {
>> .num_timing_generator = 4,
>> .num_opp = 4,
>> @@ -960,6 +974,22 @@ static struct mpc *dcn35_mpc_create(
>> return &mpc30->base;
>> }
>>
>> +static struct dio *dcn36_dio_create(struct dc_context *ctx)
>> +{
>> + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio);
>> +
>> + if (!dio10)
>> + return NULL;
>> +
>> +#undef REG_STRUCT
>> +#define REG_STRUCT dio_regs
>> + DIO_REG_LIST_DCN10();
>> +
>> + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask);
>> +
>> + return &dio10->base;
>> +}
>> +
>> static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx)
>> {
>> int i;
>> @@ -1550,6 +1580,11 @@ static void dcn36_resource_destruct(struct dcn36_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;
>> + }
>> }
>>
>> static struct hubp *dcn35_hubp_create(
>> @@ -2012,6 +2047,14 @@ static bool dcn36_resource_construct(
>> goto create_fail;
>> }
>>
>> + /* DIO */
>> + pool->base.dio = dcn36_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 and TGs */
>> for (i = 0; i < pool->base.pipe_count; i++) {
>> pool->base.hubps[i] = dcn35_hubp_create(ctx, i);
>> --
>> 2.53.0
>>
--
Thanks,
Ivan Lipski
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations
2026-03-24 16:42 ` LIPSKI, IVAN
@ 2026-04-01 7:14 ` Ionut Nechita (Sunlight Linux)
2026-04-02 19:10 ` LIPSKI, IVAN
0 siblings, 1 reply; 5+ messages in thread
From: Ionut Nechita (Sunlight Linux) @ 2026-04-01 7:14 UTC (permalink / raw)
To: ivlipski
Cc: IVAN.LIPSKI, airlied, alexander.deucher, alexdeucher, amd-gfx,
christian.koenig, dri-devel, harry.wentland, ionut_n2001, simona,
siqueira, sunlightlinux, sunpeng.li
From: Ionut Nechita <ionut_n2001@yahoo.com>
Thank you, Ivan, for picking up this patch and for the review.
If any issues come up during the promotion cycle testing, I'll be
around to address them.
Best regards,
Ionut
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations
2026-04-01 7:14 ` Ionut Nechita (Sunlight Linux)
@ 2026-04-02 19:10 ` LIPSKI, IVAN
0 siblings, 0 replies; 5+ messages in thread
From: LIPSKI, IVAN @ 2026-04-02 19:10 UTC (permalink / raw)
To: Ionut Nechita (Sunlight Linux)
Cc: IVAN.LIPSKI, airlied, alexander.deucher, alexdeucher, amd-gfx,
christian.koenig, dri-devel, harry.wentland, ionut_n2001, simona,
siqueira, sunpeng.li
Hey Ionut,
There was a compilation error, so we changed kzalloc_obj instead of
kzalloc for dio_create() in dcn10-36_resource.c, same as dcn401, ie
struct dcn10_dio *dio10 = kzalloc(sizeof(struct dcn10_dio), GFP_KERNEL);
With this fix, the patch passed the promotion testing.
Thank you again
On 4/1/2026 3:14 AM, Ionut Nechita (Sunlight Linux) wrote:
> [You don't often get email from sunlightlinux@gmail.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Ionut Nechita <ionut_n2001@yahoo.com>
>
> Thank you, Ivan, for picking up this patch and for the review.
>
> If any issues come up during the promotion cycle testing, I'll be
> around to address them.
>
> Best regards,
> Ionut
--
Thanks,
Ivan Lipski
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-04-02 19:10 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-23 21:13 [PATCH] drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations Ionut Nechita (Sunlight Linux)
2026-03-24 14:37 ` Alex Deucher
2026-03-24 16:42 ` LIPSKI, IVAN
2026-04-01 7:14 ` Ionut Nechita (Sunlight Linux)
2026-04-02 19:10 ` LIPSKI, IVAN
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox