drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.c
Extension
.c
Size
20052 bytes
Lines
629
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

#include "dc_bios_types.h"
#include "dcn31_hpo_dp_link_encoder.h"
#include "reg_helper.h"
#include "stream_encoder.h"

#define DC_LOGGER \
		enc3->base.ctx->logger

#define REG(reg)\
	(enc3->regs->reg)

#undef FN
#define FN(reg_name, field_name) \
	enc3->hpo_le_shift->field_name, enc3->hpo_le_mask->field_name


#define CTX \
	enc3->base.ctx

enum {
	DP_SAT_UPDATE_MAX_RETRY = 200
};

void dcn31_hpo_dp_link_enc_enable(
		struct hpo_dp_link_encoder *enc,
		enum dc_lane_count num_lanes)
{
	struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
	uint32_t dp_link_enabled;

	/* get current status of link enabled */
	REG_GET(DP_DPHY_SYM32_STATUS,
			STATUS, &dp_link_enabled);

	/* Enable clocks first */
	REG_UPDATE(DP_LINK_ENC_CLOCK_CONTROL, DP_LINK_ENC_CLOCK_EN, 1);

	/* Reset DPHY.  Only reset if going from disable to enable */
	if (!dp_link_enabled) {
		REG_UPDATE(DP_DPHY_SYM32_CONTROL, DPHY_RESET, 1);
		REG_UPDATE(DP_DPHY_SYM32_CONTROL, DPHY_RESET, 0);
	}

	/* Configure DPHY settings */
	REG_UPDATE_3(DP_DPHY_SYM32_CONTROL,
			DPHY_ENABLE, 1,
			PRECODER_ENABLE, 1,
			NUM_LANES, num_lanes == LANE_COUNT_ONE ? 0 : num_lanes == LANE_COUNT_TWO ? 1 : 3);
}

void dcn31_hpo_dp_link_enc_disable(
		struct hpo_dp_link_encoder *enc)
{
	struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);

	/* Configure DPHY settings */
	REG_UPDATE(DP_DPHY_SYM32_CONTROL,
			DPHY_ENABLE, 0);

	/* Shut down clock last */
	REG_UPDATE(DP_LINK_ENC_CLOCK_CONTROL, DP_LINK_ENC_CLOCK_EN, 0);
}

void dcn31_hpo_dp_link_enc_set_link_test_pattern(
		struct hpo_dp_link_encoder *enc,
		struct encoder_set_dp_phy_pattern_param *tp_params)
{
	struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc);
	uint32_t tp_custom;

	switch (tp_params->dp_phy_pattern) {
	case DP_TEST_PATTERN_VIDEO_MODE:
		REG_UPDATE(DP_DPHY_SYM32_CONTROL,
				MODE, DP2_LINK_ACTIVE);
		break;
	case DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE:
		REG_UPDATE(DP_DPHY_SYM32_CONTROL,
				MODE, DP2_LINK_TRAINING_TPS1);
		break;
	case DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE:
		REG_UPDATE(DP_DPHY_SYM32_CONTROL,
				MODE, DP2_LINK_TRAINING_TPS2);
		break;
	case DP_TEST_PATTERN_128b_132b_TPS1:
		REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG,
				TP_SELECT0, DP_DPHY_TP_SELECT_TPS1,
				TP_SELECT1, DP_DPHY_TP_SELECT_TPS1,
				TP_SELECT2, DP_DPHY_TP_SELECT_TPS1,
				TP_SELECT3, DP_DPHY_TP_SELECT_TPS1);
		REG_UPDATE(DP_DPHY_SYM32_CONTROL,

Annotation

Implementation Notes