Commit f2303026 authored by Daniel Miess's avatar Daniel Miess Committed by Alex Deucher
Browse files

drm/amd/display: Enable RCO for PHYSYMCLK in DCN35



[Why & How]
Enable root clock optimization for PHYSYMCLK and only
disable it when it's actively being used

v2:  Fix array-index-out-of-bounds in dcn35_calc_blocks_to_gate

Reviewed-by: default avatarRoman Li <roman.li@amd.com>
Reviewed-by: default avatarCharlene Liu <charlene.liu@amd.com>
Acked-by: default avatarWayne Lin <wayne.lin@amd.com>
Signed-off-by: default avatarDaniel Miess <daniel.miess@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 47745acc
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -724,6 +724,7 @@ enum pg_hw_pipe_resources {
	PG_OPTC,
	PG_DPSTREAM,
	PG_HDMISTREAM,
	PG_PHYSYMCLK,
	PG_HW_PIPE_RESOURCES_NUM_ELEMENT
};

+0 −45
Original line number Diff line number Diff line
@@ -461,32 +461,22 @@ static void dccg35_set_physymclk_root_clock_gating(
	case 0:
		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
				PHYASYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
//		REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//				PHYA_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
		break;
	case 1:
		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
				PHYBSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
//		REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//				PHYB_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
		break;
	case 2:
		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
				PHYCSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
//		REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//				PHYC_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
		break;
	case 3:
		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
				PHYDSYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
//		REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//				PHYD_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
		break;
	case 4:
		REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
				PHYESYMCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
//		REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//				PHYE_REFCLK_ROOT_GATE_DISABLE, enable ? 1 : 0);
		break;
	default:
		BREAK_TO_DEBUGGER();
@@ -509,16 +499,10 @@ static void dccg35_set_physymclk(
			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
					PHYASYMCLK_EN, 1,
					PHYASYMCLK_SRC_SEL, clk_src);
//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//						PHYA_REFCLK_ROOT_GATE_DISABLE, 0);
		} else {
			REG_UPDATE_2(PHYASYMCLK_CLOCK_CNTL,
					PHYASYMCLK_EN, 0,
					PHYASYMCLK_SRC_SEL, 0);
//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//						PHYA_REFCLK_ROOT_GATE_DISABLE, 1);
		}
		break;
	case 1:
@@ -526,16 +510,10 @@ static void dccg35_set_physymclk(
			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
					PHYBSYMCLK_EN, 1,
					PHYBSYMCLK_SRC_SEL, clk_src);
//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//						PHYB_REFCLK_ROOT_GATE_DISABLE, 0);
		} else {
			REG_UPDATE_2(PHYBSYMCLK_CLOCK_CNTL,
					PHYBSYMCLK_EN, 0,
					PHYBSYMCLK_SRC_SEL, 0);
//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//						PHYB_REFCLK_ROOT_GATE_DISABLE, 1);
		}
		break;
	case 2:
@@ -543,16 +521,10 @@ static void dccg35_set_physymclk(
			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
					PHYCSYMCLK_EN, 1,
					PHYCSYMCLK_SRC_SEL, clk_src);
//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//						PHYC_REFCLK_ROOT_GATE_DISABLE, 0);
		} else {
			REG_UPDATE_2(PHYCSYMCLK_CLOCK_CNTL,
					PHYCSYMCLK_EN, 0,
					PHYCSYMCLK_SRC_SEL, 0);
//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//						PHYC_REFCLK_ROOT_GATE_DISABLE, 1);
		}
		break;
	case 3:
@@ -560,16 +532,10 @@ static void dccg35_set_physymclk(
			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
					PHYDSYMCLK_EN, 1,
					PHYDSYMCLK_SRC_SEL, clk_src);
//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//						PHYD_REFCLK_ROOT_GATE_DISABLE, 0);
		} else {
			REG_UPDATE_2(PHYDSYMCLK_CLOCK_CNTL,
					PHYDSYMCLK_EN, 0,
					PHYDSYMCLK_SRC_SEL, 0);
//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//						PHYD_REFCLK_ROOT_GATE_DISABLE, 1);
		}
		break;
	case 4:
@@ -577,16 +543,10 @@ static void dccg35_set_physymclk(
			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
					PHYESYMCLK_EN, 1,
					PHYESYMCLK_SRC_SEL, clk_src);
//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//						PHYE_REFCLK_ROOT_GATE_DISABLE, 0);
		} else {
			REG_UPDATE_2(PHYESYMCLK_CLOCK_CNTL,
					PHYESYMCLK_EN, 0,
					PHYESYMCLK_SRC_SEL, 0);
//			if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
//				REG_UPDATE(DCCG_GATE_DISABLE_CNTL4,
//						PHYE_REFCLK_ROOT_GATE_DISABLE, 1);
		}
		break;
	default:
@@ -724,11 +684,6 @@ void dccg35_init(struct dccg *dccg)
			dccg35_set_dpstreamclk_root_clock_gating(dccg, otg_inst, false);
		}

	if (dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
		for (otg_inst = 0; otg_inst < 5; otg_inst++)
			dccg35_set_physymclk_root_clock_gating(dccg, otg_inst,
					false);

	if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
		for (otg_inst = 0; otg_inst < 4; otg_inst++)
			dccg35_set_dppclk_root_clock_gating(dccg, otg_inst, 0);
+32 −0
Original line number Diff line number Diff line
@@ -506,6 +506,17 @@ void dcn35_dpstream_root_clock_control(struct dce_hwseq *hws, unsigned int dp_hp
	}
}

void dcn35_physymclk_root_clock_control(struct dce_hwseq *hws, unsigned int phy_inst, bool clock_on)
{
	if (!hws->ctx->dc->debug.root_clock_optimization.bits.physymclk)
		return;

	if (hws->ctx->dc->res_pool->dccg->funcs->set_physymclk_root_clock_gating) {
		hws->ctx->dc->res_pool->dccg->funcs->set_physymclk_root_clock_gating(
			hws->ctx->dc->res_pool->dccg, phy_inst, clock_on);
	}
}

void dcn35_dsc_pg_control(
		struct dce_hwseq *hws,
		unsigned int dsc_inst,
@@ -1020,6 +1031,13 @@ void dcn35_calc_blocks_to_gate(struct dc *dc, struct dc_state *context,
		if (pipe_ctx->stream_res.hpo_dp_stream_enc)
			update_state->pg_pipe_res_update[PG_DPSTREAM][pipe_ctx->stream_res.hpo_dp_stream_enc->inst] = false;
	}

	for (i = 0; i < dc->link_count; i++) {
		update_state->pg_pipe_res_update[PG_PHYSYMCLK][dc->links[i]->link_enc_hw_inst] = true;
		if (dc->links[i]->type != dc_connection_none)
			update_state->pg_pipe_res_update[PG_PHYSYMCLK][dc->links[i]->link_enc_hw_inst] = false;
	}

	/*domain24 controls all the otg, mpc, opp, as long as one otg is still up, avoid enabling OTG PG*/
	for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
		struct timing_generator *tg = dc->res_pool->timing_generators[i];
@@ -1117,6 +1135,10 @@ void dcn35_calc_blocks_to_ungate(struct dc *dc, struct dc_state *context,
		}
	}

	for (i = 0; i < dc->link_count; i++)
		if (dc->links[i]->type != dc_connection_none)
			update_state->pg_pipe_res_update[PG_PHYSYMCLK][dc->links[i]->link_enc_hw_inst] = true;

	for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++) {
		if (context->res_ctx.is_hpo_dp_stream_enc_acquired[i] &&
				dc->res_pool->hpo_dp_stream_enc[i]) {
@@ -1267,6 +1289,11 @@ void dcn35_root_clock_control(struct dc *dc,
					dc->hwseq->funcs.dpstream_root_clock_control(dc->hwseq, i, power_on);
		}

		for (i = 0; i < dc->res_pool->dig_link_enc_count; i++)
			if (update_state->pg_pipe_res_update[PG_PHYSYMCLK][i])
				if (dc->hwseq->funcs.physymclk_root_clock_control)
					dc->hwseq->funcs.physymclk_root_clock_control(dc->hwseq, i, power_on);

	}
	for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
		if (update_state->pg_pipe_res_update[PG_DSC][i]) {
@@ -1292,6 +1319,11 @@ void dcn35_root_clock_control(struct dc *dc,
					dc->hwseq->funcs.dpstream_root_clock_control(dc->hwseq, i, power_on);
		}

		for (i = 0; i < dc->res_pool->dig_link_enc_count; i++)
			if (update_state->pg_pipe_res_update[PG_PHYSYMCLK][i])
				if (dc->hwseq->funcs.physymclk_root_clock_control)
					dc->hwseq->funcs.physymclk_root_clock_control(dc->hwseq, i, power_on);

	}
}

+2 −0
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ void dcn35_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst,

void dcn35_dpstream_root_clock_control(struct dce_hwseq *hws, unsigned int dp_hpo_inst, bool clock_on);

void dcn35_physymclk_root_clock_control(struct dce_hwseq *hws, unsigned int phy_inst, bool clock_on);

void dcn35_enable_power_gating_plane(struct dce_hwseq *hws, bool enable);

void dcn35_set_dmu_fgcg(struct dce_hwseq *hws, bool enable);
+1 −0
Original line number Diff line number Diff line
@@ -149,6 +149,7 @@ static const struct hwseq_private_funcs dcn35_private_funcs = {
	.enable_power_gating_plane = dcn35_enable_power_gating_plane,
	.dpp_root_clock_control = dcn35_dpp_root_clock_control,
	.dpstream_root_clock_control = dcn35_dpstream_root_clock_control,
	.physymclk_root_clock_control = dcn35_physymclk_root_clock_control,
	.program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree,
	.update_odm = dcn35_update_odm,
	.set_hdr_multiplier = dcn10_set_hdr_multiplier,
Loading