Commit d7b539d3 authored by Dmytro Laktyushkin's avatar Dmytro Laktyushkin Committed by Alex Deucher
Browse files

drm/amd/display: add safe_to_lower support to dcn wm programming



This will prevent watermarks from lowering when unsafe to do so.

Signed-off-by: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: default avatarCharlene Liu <Charlene.Liu@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 294c7e73
Loading
Loading
Loading
Loading
+210 −136
Original line number Diff line number Diff line
@@ -193,7 +193,8 @@ static uint32_t convert_and_clamp(
void hubbub1_program_watermarks(
		struct hubbub *hubbub,
		struct dcn_watermark_set *watermarks,
		unsigned int refclk_mhz)
		unsigned int refclk_mhz,
		bool safe_to_lower)
{
	uint32_t force_en = hubbub->ctx->dc->debug.disable_stutter ? 1 : 0;
	/*
@@ -207,6 +208,8 @@ void hubbub1_program_watermarks(

	/* Repeat for water mark set A, B, C and D. */
	/* clock state A */
	if (safe_to_lower || watermarks->a.urgent_ns > hubbub->watermarks.a.urgent_ns) {
		hubbub->watermarks.a.urgent_ns = watermarks->a.urgent_ns;
		prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
				refclk_mhz, 0x1fffff);
		REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
@@ -214,15 +217,23 @@ void hubbub1_program_watermarks(
		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
			"HW register value = 0x%x\n",
			watermarks->a.urgent_ns, prog_wm_value);
	}

	if (safe_to_lower || watermarks->a.pte_meta_urgent_ns > hubbub->watermarks.a.pte_meta_urgent_ns) {
		hubbub->watermarks.a.pte_meta_urgent_ns = watermarks->a.pte_meta_urgent_ns;
		prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
				refclk_mhz, 0x1fffff);
		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
			"HW register value = 0x%x\n",
			watermarks->a.pte_meta_urgent_ns, prog_wm_value);
	}

	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
		if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
				> hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) {
			hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
					watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns;
			prog_wm_value = convert_and_clamp(
					watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
					refclk_mhz, 0x1fffff);
@@ -230,8 +241,12 @@ void hubbub1_program_watermarks(
			DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
				"HW register value = 0x%x\n",
				watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
		}


		if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns
				> hubbub->watermarks.a.cstate_pstate.cstate_exit_ns) {
			hubbub->watermarks.a.cstate_pstate.cstate_exit_ns =
					watermarks->a.cstate_pstate.cstate_exit_ns;
			prog_wm_value = convert_and_clamp(
					watermarks->a.cstate_pstate.cstate_exit_ns,
					refclk_mhz, 0x1fffff);
@@ -240,7 +255,12 @@ void hubbub1_program_watermarks(
				"HW register value = 0x%x\n",
				watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
		}
	}

	if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns
			> hubbub->watermarks.a.cstate_pstate.pstate_change_ns) {
		hubbub->watermarks.a.cstate_pstate.pstate_change_ns =
				watermarks->a.cstate_pstate.pstate_change_ns;
		prog_wm_value = convert_and_clamp(
				watermarks->a.cstate_pstate.pstate_change_ns,
				refclk_mhz, 0x1fffff);
@@ -248,36 +268,48 @@ void hubbub1_program_watermarks(
		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
			"HW register value = 0x%x\n\n",
			watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);

	}

	/* clock state B */
	prog_wm_value = convert_and_clamp(
			watermarks->b.urgent_ns, refclk_mhz, 0x1fffff);
	if (safe_to_lower || watermarks->b.urgent_ns > hubbub->watermarks.b.urgent_ns) {
		hubbub->watermarks.b.urgent_ns = watermarks->b.urgent_ns;
		prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns,
				refclk_mhz, 0x1fffff);
		REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);

		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
			"HW register value = 0x%x\n",
			watermarks->b.urgent_ns, prog_wm_value);
	}


	prog_wm_value = convert_and_clamp(
			watermarks->b.pte_meta_urgent_ns,
	if (safe_to_lower || watermarks->b.pte_meta_urgent_ns > hubbub->watermarks.b.pte_meta_urgent_ns) {
		hubbub->watermarks.b.pte_meta_urgent_ns = watermarks->b.pte_meta_urgent_ns;
		prog_wm_value = convert_and_clamp(watermarks->b.pte_meta_urgent_ns,
				refclk_mhz, 0x1fffff);
		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
			"HW register value = 0x%x\n",
			watermarks->b.pte_meta_urgent_ns, prog_wm_value);

	}

	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
		if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
				> hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) {
			hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns =
					watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns;
			prog_wm_value = convert_and_clamp(
					watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
					refclk_mhz, 0x1fffff);
			REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
		DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_B calculated =%d\n"
			DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
				"HW register value = 0x%x\n",
				watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
		}


		if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns
				> hubbub->watermarks.b.cstate_pstate.cstate_exit_ns) {
			hubbub->watermarks.b.cstate_pstate.cstate_exit_ns =
					watermarks->b.cstate_pstate.cstate_exit_ns;
			prog_wm_value = convert_and_clamp(
					watermarks->b.cstate_pstate.cstate_exit_ns,
					refclk_mhz, 0x1fffff);
@@ -286,43 +318,61 @@ void hubbub1_program_watermarks(
				"HW register value = 0x%x\n",
				watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
		}
	}

	if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns
			> hubbub->watermarks.b.cstate_pstate.pstate_change_ns) {
		hubbub->watermarks.b.cstate_pstate.pstate_change_ns =
				watermarks->b.cstate_pstate.pstate_change_ns;
		prog_wm_value = convert_and_clamp(
				watermarks->b.cstate_pstate.pstate_change_ns,
				refclk_mhz, 0x1fffff);
		REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
	DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n"
		"HW register value = 0x%x\n",
		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
			"HW register value = 0x%x\n\n",
			watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
	}

	/* clock state C */
	prog_wm_value = convert_and_clamp(
			watermarks->c.urgent_ns, refclk_mhz, 0x1fffff);
	if (safe_to_lower || watermarks->c.urgent_ns > hubbub->watermarks.c.urgent_ns) {
		hubbub->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
		prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns,
				refclk_mhz, 0x1fffff);
		REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);

		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
			"HW register value = 0x%x\n",
			watermarks->c.urgent_ns, prog_wm_value);
	}


	prog_wm_value = convert_and_clamp(
			watermarks->c.pte_meta_urgent_ns,
	if (safe_to_lower || watermarks->c.pte_meta_urgent_ns > hubbub->watermarks.c.pte_meta_urgent_ns) {
		hubbub->watermarks.c.pte_meta_urgent_ns = watermarks->c.pte_meta_urgent_ns;
		prog_wm_value = convert_and_clamp(watermarks->c.pte_meta_urgent_ns,
				refclk_mhz, 0x1fffff);
		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
			"HW register value = 0x%x\n",
			watermarks->c.pte_meta_urgent_ns, prog_wm_value);

	}

	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
		if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
				> hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) {
			hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns =
					watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns;
			prog_wm_value = convert_and_clamp(
					watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
					refclk_mhz, 0x1fffff);
			REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
		DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_C calculated =%d\n"
			DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
				"HW register value = 0x%x\n",
				watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
		}


		if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns
				> hubbub->watermarks.c.cstate_pstate.cstate_exit_ns) {
			hubbub->watermarks.c.cstate_pstate.cstate_exit_ns =
					watermarks->c.cstate_pstate.cstate_exit_ns;
			prog_wm_value = convert_and_clamp(
					watermarks->c.cstate_pstate.cstate_exit_ns,
					refclk_mhz, 0x1fffff);
@@ -331,42 +381,61 @@ void hubbub1_program_watermarks(
				"HW register value = 0x%x\n",
				watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
		}
	}

	if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns
			> hubbub->watermarks.c.cstate_pstate.pstate_change_ns) {
		hubbub->watermarks.c.cstate_pstate.pstate_change_ns =
				watermarks->c.cstate_pstate.pstate_change_ns;
		prog_wm_value = convert_and_clamp(
				watermarks->c.cstate_pstate.pstate_change_ns,
				refclk_mhz, 0x1fffff);
		REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
	DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n"
		"HW register value = 0x%x\n",
		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
			"HW register value = 0x%x\n\n",
			watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
	}

	/* clock state D */
	prog_wm_value = convert_and_clamp(
			watermarks->d.urgent_ns, refclk_mhz, 0x1fffff);
	if (safe_to_lower || watermarks->d.urgent_ns > hubbub->watermarks.d.urgent_ns) {
		hubbub->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
		prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns,
				refclk_mhz, 0x1fffff);
		REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);

		DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
			"HW register value = 0x%x\n",
			watermarks->d.urgent_ns, prog_wm_value);
	}

	prog_wm_value = convert_and_clamp(
			watermarks->d.pte_meta_urgent_ns,
	if (safe_to_lower || watermarks->d.pte_meta_urgent_ns > hubbub->watermarks.d.pte_meta_urgent_ns) {
		hubbub->watermarks.d.pte_meta_urgent_ns = watermarks->d.pte_meta_urgent_ns;
		prog_wm_value = convert_and_clamp(watermarks->d.pte_meta_urgent_ns,
				refclk_mhz, 0x1fffff);
		REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
		DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
			"HW register value = 0x%x\n",
			watermarks->d.pte_meta_urgent_ns, prog_wm_value);

	}

	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
		if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
				> hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) {
			hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns =
					watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns;
			prog_wm_value = convert_and_clamp(
					watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
					refclk_mhz, 0x1fffff);
			REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
		DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_D calculated =%d\n"
			DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
				"HW register value = 0x%x\n",
				watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
		}


		if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns
				> hubbub->watermarks.d.cstate_pstate.cstate_exit_ns) {
			hubbub->watermarks.d.cstate_pstate.cstate_exit_ns =
					watermarks->d.cstate_pstate.cstate_exit_ns;
			prog_wm_value = convert_and_clamp(
					watermarks->d.cstate_pstate.cstate_exit_ns,
					refclk_mhz, 0x1fffff);
@@ -375,8 +444,12 @@ void hubbub1_program_watermarks(
				"HW register value = 0x%x\n",
				watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
		}
	}


	if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns
			> hubbub->watermarks.d.cstate_pstate.pstate_change_ns) {
		hubbub->watermarks.d.cstate_pstate.pstate_change_ns =
				watermarks->d.cstate_pstate.pstate_change_ns;
		prog_wm_value = convert_and_clamp(
				watermarks->d.cstate_pstate.pstate_change_ns,
				refclk_mhz, 0x1fffff);
@@ -384,6 +457,7 @@ void hubbub1_program_watermarks(
		DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
			"HW register value = 0x%x\n\n",
			watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
	}

	REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL,
			DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
+3 −1
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@ struct hubbub {
	const struct dcn_hubbub_shift *shifts;
	const struct dcn_hubbub_mask *masks;
	unsigned int debug_test_index_pstate;
	struct dcn_watermark_set watermarks;
};

void hubbub1_update_dchub(
@@ -197,7 +198,8 @@ bool hubbub1_verify_allow_pstate_change_high(
void hubbub1_program_watermarks(
		struct hubbub *hubbub,
		struct dcn_watermark_set *watermarks,
		unsigned int refclk_mhz);
		unsigned int refclk_mhz,
		bool safe_to_lower);

void hubbub1_toggle_watermark_change_req(
		struct hubbub *hubbub);
+1 −1
Original line number Diff line number Diff line
@@ -2299,7 +2299,7 @@ static void dcn10_apply_ctx_for_surface(

		/* watermark is for all pipes */
		hubbub1_program_watermarks(dc->res_pool->hubbub,
				&context->bw.dcn.watermarks, ref_clk_mhz);
				&context->bw.dcn.watermarks, ref_clk_mhz, true);

		if (dc->debug.sanity_checks) {
			/* pstate stuck check after watermark update */