drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
Extension
.c
Size
27606 bytes
Lines
1008
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

if (phase > 0xff) {
			ASSERT(false);
			phase = 0xff;
		}

		REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
				DPPCLK0_DTO_PHASE, phase,
				DPPCLK0_DTO_MODULO, modulo);
		dcn401_set_dppclk_enable(dccg, dpp_inst, true);
	} else {
		dcn401_set_dppclk_enable(dccg, dpp_inst, false);
	}

	dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
}

/* This function is a workaround for writing to OTG_PIXEL_RATE_DIV
 * without the probability of causing a DIG FIFO error.
 */
static void dccg401_wait_for_dentist_change_done(
	struct dccg *dccg)
{
	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);

	uint32_t dentist_dispclk_value = REG_READ(DENTIST_DISPCLK_CNTL);

	REG_WRITE(DENTIST_DISPCLK_CNTL, dentist_dispclk_value);
	REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000);
}

void dccg401_get_pixel_rate_div(
		struct dccg *dccg,
		uint32_t otg_inst,
		uint32_t *tmds_div,
		uint32_t *dp_dto_int)
{
	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
	uint32_t val_tmds_div = PIXEL_RATE_DIV_NA;

	switch (otg_inst) {
	case 0:
		REG_GET_2(OTG_PIXEL_RATE_DIV,
			OTG0_TMDS_PIXEL_RATE_DIV, &val_tmds_div,
			DPDTO0_INT, dp_dto_int);
		break;
	case 1:
		REG_GET_2(OTG_PIXEL_RATE_DIV,
			OTG1_TMDS_PIXEL_RATE_DIV, &val_tmds_div,
			DPDTO1_INT, dp_dto_int);
		break;
	case 2:
		REG_GET_2(OTG_PIXEL_RATE_DIV,
			OTG2_TMDS_PIXEL_RATE_DIV, &val_tmds_div,
			DPDTO2_INT, dp_dto_int);
		break;
	case 3:
		REG_GET_2(OTG_PIXEL_RATE_DIV,
			OTG3_TMDS_PIXEL_RATE_DIV, &val_tmds_div,
			DPDTO3_INT, dp_dto_int);
		break;
	default:
		BREAK_TO_DEBUGGER();
		return;
	}

	*tmds_div = val_tmds_div == 0 ? PIXEL_RATE_DIV_BY_2 : PIXEL_RATE_DIV_BY_4;
}

void dccg401_set_pixel_rate_div(
		struct dccg *dccg,
		uint32_t otg_inst,
		enum pixel_rate_div tmds_div,
		enum pixel_rate_div unused)
{
	(void)unused;
	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
	uint32_t cur_tmds_div = PIXEL_RATE_DIV_NA;
	uint32_t dp_dto_int;
	uint32_t reg_val;

	// only 2 and 4 are valid on dcn401
	if (tmds_div != PIXEL_RATE_DIV_BY_2 && tmds_div != PIXEL_RATE_DIV_BY_4) {
		return;
	}

	dccg401_get_pixel_rate_div(dccg, otg_inst, &cur_tmds_div, &dp_dto_int);
	if (tmds_div == cur_tmds_div)
		return;

	// encode enum to register value

Annotation

Implementation Notes