Commit a4983968 authored by Ionut Nechita's avatar Ionut Nechita Committed by Alex Deucher
Browse files

drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations



Description:
 - Commit b82f0759 ("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: b82f0759 ("drm/amd/display: Migrate DIO registers access from hwseq to dio component.")
Reviewed-by: default avatarIvan Lipski <ivan.lipski@amd.com>
Signed-off-by: default avatarIonut Nechita <ionut_n2001@yahoo.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 78746a47
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -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;
+42 −0
Original line number Diff line number Diff line
@@ -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) {
+41 −0
Original line number Diff line number Diff line
@@ -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;
+34 −0
Original line number Diff line number Diff line
@@ -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) {
+42 −0
Original line number Diff line number Diff line
@@ -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);
Loading