From fc0ed906f1eaf189eff76f586bb898eaa4193ba9 Mon Sep 17 00:00:00 2001 From: Ionut Nechita Date: Mon, 23 Mar 2026 23:13:43 +0200 Subject: [PATCH] drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations 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 Signed-off-by: Ionut Nechita Signed-off-by: Alex Deucher (cherry picked from commit a4983968fa5b3179ab090407d325a71cdc96874e) --- .../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 250c3975b9e98..0fdebe63d3554 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) { @@ -918,6 +946,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]); @@ -1663,6 +1696,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 bd5c18ee35e76..a99829f239659 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)\ @@ -1105,6 +1133,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]); @@ -2709,6 +2743,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 491d8d3b1b68b..02b7dc07ad53b 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]); @@ -1277,6 +1310,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 bd19168a3f773..54ebf8cf607f2 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]); @@ -1662,6 +1688,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 5742effef7ae2..4a864689c44f3 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) @@ -1096,6 +1124,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]); @@ -2468,6 +2502,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 9773896e08018..a74b150cbe9c4 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) { @@ -1067,6 +1095,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]); @@ -1584,6 +1618,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 d9f12a6f225fd..539c5aa6bffaa 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; @@ -1023,6 +1051,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])); @@ -1374,6 +1407,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 f0c75db81b2c9..529eccb4ed3bf 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; @@ -967,6 +995,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])); @@ -1306,6 +1339,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 afcc4dff6abcf..ee4bc2c2e73a3 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; @@ -1397,6 +1425,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]); @@ -2065,6 +2097,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 654b4e97807e9..5acc545bbe7f3 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; @@ -1456,6 +1484,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]); @@ -1992,6 +2024,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 f424fd4d5a457..2ca6731148417 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; @@ -1398,6 +1426,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]); @@ -2015,6 +2047,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 e0dc8aaaaaa1d..2242df112a3f0 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; @@ -1393,6 +1421,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]); @@ -1891,6 +1923,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 3c0d046ab7476..82f81b5869866 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; @@ -2374,6 +2409,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 b8ae6e8397ef8..c8c81870d50ed 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; @@ -1873,6 +1908,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 825ecaf9c5804..2a1b0b152501c 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( @@ -2045,6 +2080,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 00286cba5742e..bfd1016aa7803 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( @@ -2017,6 +2052,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 7c4519d57e4d9..07a6675a73294 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( @@ -2015,6 +2050,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.47.3