Commit a28acf70 authored by Taimur Hassan's avatar Taimur Hassan Committed by Alex Deucher
Browse files

drm/amd/display: Avoid unnecessary pixel rate divider programming



[Why]
Programming pixel rate divider when FIFO is enabled can cause FIFO error.

[How]
Skip divider programming when divider values are the same to prevent FIFO
error.

Reviewed-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Acked-by: default avatarJasdeep Dhillon <jdhillon@amd.com>
Signed-off-by: default avatarTaimur Hassan <Syed.Hassan@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 8dd2e87d
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -42,6 +42,48 @@
#define DC_LOGGER \
	dccg->ctx->logger

static void dccg32_get_pixel_rate_div(
		struct dccg *dccg,
		uint32_t otg_inst,
		enum pixel_rate_div *k1,
		enum pixel_rate_div *k2)
{
	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
	uint32_t val_k1 = PIXEL_RATE_DIV_NA, val_k2 = PIXEL_RATE_DIV_NA;

	*k1 = PIXEL_RATE_DIV_NA;
	*k2 = PIXEL_RATE_DIV_NA;

	switch (otg_inst) {
	case 0:
		REG_GET_2(OTG_PIXEL_RATE_DIV,
			OTG0_PIXEL_RATE_DIVK1, &val_k1,
			OTG0_PIXEL_RATE_DIVK2, &val_k2);
		break;
	case 1:
		REG_GET_2(OTG_PIXEL_RATE_DIV,
			OTG1_PIXEL_RATE_DIVK1, &val_k1,
			OTG1_PIXEL_RATE_DIVK2, &val_k2);
		break;
	case 2:
		REG_GET_2(OTG_PIXEL_RATE_DIV,
			OTG2_PIXEL_RATE_DIVK1, &val_k1,
			OTG2_PIXEL_RATE_DIVK2, &val_k2);
		break;
	case 3:
		REG_GET_2(OTG_PIXEL_RATE_DIV,
			OTG3_PIXEL_RATE_DIVK1, &val_k1,
			OTG3_PIXEL_RATE_DIVK2, &val_k2);
		break;
	default:
		BREAK_TO_DEBUGGER();
		return;
	}

	*k1 = (enum pixel_rate_div)val_k1;
	*k2 = (enum pixel_rate_div)val_k2;
}

static void dccg32_set_pixel_rate_div(
		struct dccg *dccg,
		uint32_t otg_inst,
@@ -50,6 +92,17 @@ static void dccg32_set_pixel_rate_div(
{
	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);

	enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = PIXEL_RATE_DIV_NA;

	// Don't program 0xF into the register field. Not valid since
	// K1 / K2 field is only 1 / 2 bits wide
	if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA)
		return;

	dccg32_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
	if (k1 == cur_k1 && k2 == cur_k2)
		return;

	switch (otg_inst) {
	case 0:
		REG_UPDATE_2(OTG_PIXEL_RATE_DIV,