]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations
authorIonut Nechita <ionut_n2001@yahoo.com>
Mon, 23 Mar 2026 21:13:43 +0000 (23:13 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 2 Apr 2026 19:24:13 +0000 (15:24 -0400)
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: b82f07593466 ("drm/amd/display: Migrate DIO registers access from hwseq to dio component.")
Reviewed-by: Ivan Lipski <ivan.lipski@amd.com>
Signed-off-by: Ionut Nechita <ionut_n2001@yahoo.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
17 files changed:
drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c

index bbe185e15eb679d017f8601a43d51309d199d2cb..4663456a736a2fd720d973bc1ff29968d30830b1 100644 (file)
@@ -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;
index 8b555187ac75374baa4b92ab2d2421b70dc6b5cc..74e8d229c9dd3c2782dd14819bf8d60ad0351170 100644 (file)
@@ -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) {
index 4ea76e46ab15de2036f22ff58465547ea111522c..e289be70efb54c52e0826f921f40d67f57cc5057 100644 (file)
@@ -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;
index 0f4307f8f3dd595d95cdb45dfeaecc3a87bc67bf..4333baac96ad7d9cef1d2070423b56b34d710b15 100644 (file)
@@ -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) {
index 2fa86b9587ed00638cb96dd66b026e5b5eeaf08f..87b7b4ee04c647fbf3d968ee7df9b23338403458 100644 (file)
@@ -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);
index 7842bee57e636cd4cd34a0bb23cd5b96a6b863cb..6bb1c62124bb46de41853450d64796b0fee4acbc 100644 (file)
@@ -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++) {
index 1874d5d6b782002557f8ac752c4dcf9b5e112be3..d02aafd06fd4552247c69ce063c8f86350421175 100644 (file)
@@ -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);
index d52201cb359fd5ab74881eb23842b32cb4884c50..30b1403112c6c18f133f620d05156c5e48305620 100644 (file)
@@ -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);
index 2055f1f8af6521fa47ad9968a1bce9464182f474..4e9c041c707a612b0a159b5e318fa8387afdeaa1 100644 (file)
@@ -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);
index 1939f720ba29573fa2cdd1a82c1abcca4520f20a..e26a6427916a0b8089a46b7645c33b8cbc4365da 100644 (file)
@@ -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);
index e8377c190f635e30518ac9c1f644e8d54a19a2ba..131a6cd4c7352877838cbbe4326d4aa9423cf6ce 100644 (file)
@@ -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);
index 045ce01bd74eb1ebcce9a174544b64c99d11ddb2..c8c0ce6efcfdcf9640a9feaccdc706b6e5f98c9b 100644 (file)
@@ -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);
index c7fd604024d6452d2b6daef5dc86d7427c923de7..c3a6ae14de18bfb5c0ea17e2bc400d33bdb6e156 100644 (file)
@@ -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++) {
 
index c1582c27ac872b4a5a2fb5cf1833de366cc6903b..990aec7eb3d071355fd845fadd32016510639504 100644 (file)
@@ -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++) {
 
index 3494a40cea99f7047ecbd995ea3dfd1805f1d7ae..598b2f25881da2d6bbd202f9bea69855c78e03b2 100644 (file)
@@ -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);
index 080bc7f24ffaacd1a5af2d9ced1eb8d682fd316b..7e15d07df7a33de38f6e37ff630afb3027d790d5 100644 (file)
@@ -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);
index af51ac4ea59e20e4b1c6c809ae9223653ecb49a0..83fee2ca61bffa64e6dbbd724574a2b4cec1ffc8 100644 (file)
@@ -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);