Commit 00c39110 authored by Aurabindo Pillai's avatar Aurabindo Pillai Committed by Alex Deucher
Browse files

drm/amd/display: Add misc DC changes for DCN401



Add miscellaneous changes to enable DCN401 init

Signed-off-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Acked-by: default avatarRodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent da87132f
Loading
Loading
Loading
Loading
+29 −4
Original line number Diff line number Diff line
@@ -151,6 +151,9 @@ MODULE_FIRMWARE(FIRMWARE_DCN_35_DMUB);
#define FIRMWARE_DCN_351_DMUB "amdgpu/dcn_3_5_1_dmcub.bin"
MODULE_FIRMWARE(FIRMWARE_DCN_351_DMUB);

#define FIRMWARE_DCN_401_DMUB "amdgpu/dcn_4_0_1_dmcub.bin"
MODULE_FIRMWARE(FIRMWARE_DCN_401_DMUB);

/* Number of bytes in PSP header for firmware. */
#define PSP_HEADER_BYTES 0x100

@@ -1223,6 +1226,7 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
	case IP_VERSION(3, 1, 4):
	case IP_VERSION(3, 5, 0):
	case IP_VERSION(3, 5, 1):
	case IP_VERSION(4, 0, 1):
		hw_params.dpia_supported = true;
		hw_params.disable_dpia = adev->dm.dc->debug.dpia_debug.bits.disable_dpia;
		break;
@@ -1781,8 +1785,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
	if (amdgpu_dc_debug_mask & DC_FORCE_SUBVP_MCLK_SWITCH)
		adev->dm.dc->debug.force_subvp_mclk_switch = true;

	if (amdgpu_dc_debug_mask & DC_ENABLE_DML2)
	if (amdgpu_dc_debug_mask & DC_ENABLE_DML2) {
		adev->dm.dc->debug.using_dml2 = true;
		adev->dm.dc->debug.using_dml21 = true;
	}

	adev->dm.dc->debug.visual_confirm = amdgpu_dc_visual_confirm;

@@ -2059,6 +2065,7 @@ static int load_dmcu_fw(struct amdgpu_device *adev)
		case IP_VERSION(3, 2, 1):
		case IP_VERSION(3, 5, 0):
		case IP_VERSION(3, 5, 1):
		case IP_VERSION(4, 0, 1):
			return 0;
		default:
			break;
@@ -2182,6 +2189,10 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
	case IP_VERSION(3, 5, 1):
		dmub_asic = DMUB_ASIC_DCN35;
		break;
	case IP_VERSION(4, 0, 1):
		dmub_asic = DMUB_ASIC_DCN401;
		break;

	default:
		/* ASIC doesn't support DMUB. */
		return 0;
@@ -4523,6 +4534,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
	case IP_VERSION(2, 1, 0):
	case IP_VERSION(3, 5, 0):
	case IP_VERSION(3, 5, 1):
	case IP_VERSION(4, 0, 1):
		if (register_outbox_irq_handlers(dm->adev)) {
			DRM_ERROR("DM: Failed to initialize IRQ\n");
			goto fail;
@@ -4545,6 +4557,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
		case IP_VERSION(3, 2, 1):
		case IP_VERSION(3, 5, 0):
		case IP_VERSION(3, 5, 1):
		case IP_VERSION(4, 0, 1):
			psr_feature_enabled = true;
			break;
		default:
@@ -4716,6 +4729,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
		case IP_VERSION(3, 2, 1):
		case IP_VERSION(3, 5, 0):
		case IP_VERSION(3, 5, 1):
		case IP_VERSION(4, 0, 1):
			if (dcn10_register_irq_handlers(dm->adev)) {
				DRM_ERROR("DM: Failed to initialize IRQ\n");
				goto fail;
@@ -4852,6 +4866,9 @@ static int dm_init_microcode(struct amdgpu_device *adev)
	case IP_VERSION(3, 5, 1):
		fw_name_dmub = FIRMWARE_DCN_351_DMUB;
		break;
	case IP_VERSION(4, 0, 1):
		fw_name_dmub = FIRMWARE_DCN_401_DMUB;
		break;
	default:
		/* ASIC doesn't support DMUB. */
		return 0;
@@ -4976,6 +4993,7 @@ static int dm_early_init(void *handle)
		case IP_VERSION(3, 2, 1):
		case IP_VERSION(3, 5, 0):
		case IP_VERSION(3, 5, 1):
		case IP_VERSION(4, 0, 1):
			adev->mode_info.num_crtc = 4;
			adev->mode_info.num_hpd = 4;
			adev->mode_info.num_dig = 4;
@@ -6023,6 +6041,7 @@ static bool is_freesync_video_mode(const struct drm_display_mode *mode,
		return true;
}

#if defined(CONFIG_DRM_AMD_DC_FP)
static void update_dsc_caps(struct amdgpu_dm_connector *aconnector,
			    struct dc_sink *sink, struct dc_stream_state *stream,
			    struct dsc_dec_dpcd_caps *dsc_caps)
@@ -6041,7 +6060,6 @@ static void update_dsc_caps(struct amdgpu_dm_connector *aconnector,
	}
}


static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
				    struct dc_sink *sink, struct dc_stream_state *stream,
				    struct dsc_dec_dpcd_caps *dsc_caps,
@@ -6105,7 +6123,6 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
	}
}


static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
					struct dc_sink *sink, struct dc_stream_state *stream,
					struct dsc_dec_dpcd_caps *dsc_caps)
@@ -6183,6 +6200,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
	if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_bits_per_pixel)
		stream->timing.dsc_cfg.bits_per_pixel = aconnector->dsc_settings.dsc_bits_per_pixel;
}
#endif

static struct dc_stream_state *
create_stream_for_sink(struct drm_connector *connector,
@@ -6204,8 +6222,9 @@ create_stream_for_sink(struct drm_connector *connector,
	int mode_refresh;
	int preferred_refresh = 0;
	enum color_transfer_func tf = TRANSFER_FUNC_UNKNOWN;
#if defined(CONFIG_DRM_AMD_DC_FP)
	struct dsc_dec_dpcd_caps dsc_caps;

#endif
	struct dc_link *link = NULL;
	struct dc_sink *sink = NULL;

@@ -6321,10 +6340,12 @@ create_stream_for_sink(struct drm_connector *connector,
		stream->timing = *aconnector->timing_requested;
	}

#if defined(CONFIG_DRM_AMD_DC_FP)
	/* SST DSC determination policy */
	update_dsc_caps(aconnector, sink, stream, &dsc_caps);
	if (aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE && dsc_caps.is_dsc_supported)
		apply_dsc_policy_for_stream(aconnector, sink, stream, &dsc_caps);
#endif

	update_stream_scaling_settings(&mode, dm_state, stream);

@@ -10799,11 +10820,13 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
		}
	}

#if defined(CONFIG_DRM_AMD_DC_FP)
	if (dc_resource_is_dsc_encoding_supported(dc)) {
		ret = pre_validate_dsc(state, &dm_state, vars);
		if (ret != 0)
			goto fail;
	}
#endif

	/* Run this here since we want to validate the streams we created */
	ret = drm_atomic_helper_check_planes(dev, state);
@@ -10915,6 +10938,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
			goto fail;
		}

#if defined(CONFIG_DRM_AMD_DC_FP)
		if (dc_resource_is_dsc_encoding_supported(dc)) {
			ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars);
			if (ret) {
@@ -10923,6 +10947,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
				goto fail;
			}
		}
#endif

		ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context, vars);
		if (ret) {
+10 −2
Original line number Diff line number Diff line
@@ -210,6 +210,7 @@ bool needs_dsc_aux_workaround(struct dc_link *link)
	return false;
}

#if defined(CONFIG_DRM_AMD_DC_FP)
static bool is_synaptics_cascaded_panamera(struct dc_link *link, struct drm_dp_mst_port *port)
{
	u8 branch_vendor_data[4] = { 0 }; // Vendor data 0x50C ~ 0x50F
@@ -269,6 +270,7 @@ static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnecto

	return true;
}
#endif

static bool retrieve_downstream_port_device(struct amdgpu_dm_connector *aconnector)
{
@@ -402,9 +404,11 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
			amdgpu_dm_update_freesync_caps(
					connector, aconnector->edid);

#if defined(CONFIG_DRM_AMD_DC_FP)
			if (!validate_dsc_caps_on_connector(aconnector))
				memset(&aconnector->dc_sink->dsc_caps,
				       0, sizeof(aconnector->dc_sink->dsc_caps));
#endif

			if (!retrieve_downstream_port_device(aconnector))
				memset(&aconnector->mst_downstream_port_present,
@@ -791,6 +795,7 @@ struct dsc_mst_fairness_params {
	struct amdgpu_dm_connector *aconnector;
};

#if defined(CONFIG_DRM_AMD_DC_FP)
static int kbps_to_peak_pbn(int kbps)
{
	u64 peak_kbps = kbps;
@@ -1581,13 +1586,16 @@ static bool is_dsc_common_config_possible(struct dc_stream_state *stream,

	return bw_range->max_target_bpp_x16 && bw_range->min_target_bpp_x16;
}
#endif

enum dc_status dm_dp_mst_is_port_support_mode(
	struct amdgpu_dm_connector *aconnector,
	struct dc_stream_state *stream)
{
	int pbn, branch_max_throughput_mps = 0;
	int branch_max_throughput_mps = 0;
#if defined(CONFIG_DRM_AMD_DC_FP)
	struct dc_link_settings cur_link_settings;
	int pbn;
	unsigned int end_to_end_bw_in_kbps = 0;
	unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0;
	struct dc_dsc_bw_range bw_range = {0};
@@ -1665,7 +1673,6 @@ enum dc_status dm_dp_mst_is_port_support_mode(
			return DC_FAIL_BANDWIDTH_VALIDATE;
		}
	}

	/* check is mst dsc output bandwidth branch_overall_throughput_0_mps */
	switch (stream->timing.pixel_encoding) {
	case PIXEL_ENCODING_RGB:
@@ -1681,6 +1688,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
	default:
		break;
	}
#endif

	if (branch_max_throughput_mps != 0 &&
		((stream->timing.pix_clk_100hz / 10) >  branch_max_throughput_mps * 1000))
+9 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ DC_LIBS += dcn314
DC_LIBS += dcn32
DC_LIBS += dcn321
DC_LIBS += dcn35
DC_LIBS += dcn401
DC_LIBS += dml
DC_LIBS += dml2
endif
@@ -55,6 +56,11 @@ endif

DC_LIBS += hdcp

ifdef CONFIG_DRM_AMD_DC_FP
DC_LIBS += spl
DC_SPL_TRANS += dc_spl_translate.o
endif

AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LIBS)))

include $(AMD_DC)
@@ -68,6 +74,8 @@ AMD_DISPLAY_CORE = $(addprefix $(AMDDALPATH)/dc/core/,$(DISPLAY_CORE))

AMD_DM_REG_UPDATE = $(addprefix $(AMDDALPATH)/dc/,dc_helper.o)

AMD_DC_SPL_TRANS = $(addprefix $(AMDDALPATH)/dc/,$(DC_SPL_TRANS))

AMD_DISPLAY_FILES += $(AMD_DISPLAY_CORE)
AMD_DISPLAY_FILES += $(AMD_DM_REG_UPDATE)

@@ -77,3 +85,4 @@ AMD_DISPLAY_DMUB = $(addprefix $(AMDDALPATH)/dc/,$(DC_DMUB))
AMD_DISPLAY_EDID = $(addprefix $(AMDDALPATH)/dc/,$(DC_EDID))
AMD_DISPLAY_FILES += $(AMD_DISPLAY_DMUB) $(AMD_DISPLAY_EDID)

AMD_DISPLAY_FILES += $(AMD_DC_SPL_TRANS)
+107 −2
Original line number Diff line number Diff line
@@ -75,6 +75,10 @@ static enum bp_result get_firmware_info_v3_4(
	struct bios_parser *bp,
	struct dc_firmware_info *info);

static enum bp_result get_firmware_info_v3_5(
	struct bios_parser *bp,
	struct dc_firmware_info *info);

static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp,
		struct atom_display_object_path_v2 *object);

@@ -1754,6 +1758,9 @@ static enum bp_result bios_parser_get_firmware_info(
			case 4:
				result = get_firmware_info_v3_4(bp, info);
				break;
			case 5:
				result = get_firmware_info_v3_5(bp, info);
				break;
			default:
				break;
			}
@@ -2044,6 +2051,63 @@ static enum bp_result get_firmware_info_v3_4(
	return BP_RESULT_OK;
}

static enum bp_result get_firmware_info_v3_5(
	struct bios_parser *bp,
	struct dc_firmware_info *info)
{
	struct atom_firmware_info_v3_5 *firmware_info;
	struct atom_common_table_header *header;
	struct atom_data_revision revision;
	struct atom_display_controller_info_v4_5 *dce_info_v4_5 = NULL;

	if (!info)
		return BP_RESULT_BADINPUT;

	firmware_info = GET_IMAGE(struct atom_firmware_info_v3_5,
			DATA_TABLES(firmwareinfo));

	if (!firmware_info)
		return BP_RESULT_BADBIOSTABLE;

	memset(info, 0, sizeof(*info));

	if (firmware_info->board_i2c_feature_id == 0x2) {
		info->oem_i2c_present = true;
		info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id;
	} else {
		info->oem_i2c_present = false;
	}

	header = GET_IMAGE(struct atom_common_table_header,
					DATA_TABLES(dce_info));

	get_atom_data_table_revision(header, &revision);

	switch (revision.major) {
	case 4:
		switch (revision.minor) {
		case 5:
			dce_info_v4_5 = GET_IMAGE(struct atom_display_controller_info_v4_5,
							DATA_TABLES(dce_info));

			if (!dce_info_v4_5)
				return BP_RESULT_BADBIOSTABLE;

			 /* 100MHz expected */
			info->pll_info.crystal_frequency = dce_info_v4_5->dce_refclk_10khz * 10;
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}


	return BP_RESULT_OK;
}

static enum bp_result bios_parser_get_encoder_cap_info(
	struct dc_bios *dcb,
	struct graphics_object_id object_id,
@@ -2398,6 +2462,25 @@ static enum bp_result get_vram_info_v30(
	return result;
}

static enum bp_result get_vram_info_from_umc_info_v40(
		struct bios_parser *bp,
		struct dc_vram_info *info)
{
	struct atom_umc_info_v4_0 *info_v40;
	enum bp_result result = BP_RESULT_OK;

	info_v40 = GET_IMAGE(struct atom_umc_info_v4_0,
						DATA_TABLES(umc_info));

	if (info_v40 == NULL)
		return BP_RESULT_BADBIOSTABLE;

	info->num_chans = info_v40->channel_num;
	info->dram_channel_width_bytes = (1 << info_v40->channel_width) / 8;

	return result;
}

/*
 * get_integrated_info_v11
 *
@@ -3039,7 +3122,29 @@ static enum bp_result bios_parser_get_vram_info(
	struct atom_common_table_header *header;
	struct atom_data_revision revision;

	if (info && DATA_TABLES(vram_info)) {
	// vram info moved to umc_info for DCN4x
	if (info && DATA_TABLES(umc_info)) {
		header = GET_IMAGE(struct atom_common_table_header,
					DATA_TABLES(umc_info));

		get_atom_data_table_revision(header, &revision);

		switch (revision.major) {
		case 4:
			switch (revision.minor) {
			case 0:
				result = get_vram_info_from_umc_info_v40(bp, info);
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
	}

	if (result != BP_RESULT_OK && info && DATA_TABLES(vram_info)) {
		header = GET_IMAGE(struct atom_common_table_header,
					DATA_TABLES(vram_info));

@@ -3662,7 +3767,7 @@ static bool bios_parser2_construct(
	bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
	bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK;
	bios_parser_get_vram_info(&bp->base, &bp->base.vram_info);

	bios_parser_get_soc_bb_info(&bp->base, &bp->base.bb_info);
	return true;
}

+1 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ bool dal_bios_parser_init_cmd_tbl_helper2(
	case DCN_VERSION_3_21:
	case DCN_VERSION_3_5:
	case DCN_VERSION_3_51:
	case DCN_VERSION_4_01:
		*h = dal_cmd_tbl_helper_dce112_get_table2();
		return true;

Loading