Commit 18b4f1a0 authored by Michael Strauss's avatar Michael Strauss Committed by Alex Deucher
Browse files

drm/amd/display: Add VPG and AFMT low power support for DCN3.1



[WHY]
Power down VPG and AFMT blocks when not in use

[HOW]
Create afmt31 and vpg31 structs and add necessary fields to reg list

Reviewed-by: default avatarEric Yang <eric.yang2@amd.com>
Acked-by: default avatarMikita Lipski <mikita.lipski@amd.com>
Signed-off-by: default avatarMichael Strauss <michael.strauss@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9b3d7652
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -71,6 +71,8 @@

#include "dmub/dmub_srv.h"

#include "dcn30/dcn30_vpg.h"

#include "i2caux_interface.h"
#include "dce/dmub_hw_lock_mgr.h"

@@ -2555,6 +2557,9 @@ static void commit_planes_do_stream_update(struct dc *dc,
		enum surface_update_type update_type,
		struct dc_state *context)
{
#if defined(CONFIG_DRM_AMD_DC_DCN)
	struct vpg *vpg;
#endif
	int j;

	// Stream updates
@@ -2575,6 +2580,11 @@ static void commit_planes_do_stream_update(struct dc *dc,
					stream_update->vrr_infopacket ||
					stream_update->vsc_infopacket ||
					stream_update->vsp_infopacket) {
#if defined(CONFIG_DRM_AMD_DC_DCN)
				vpg = pipe_ctx->stream_res.stream_enc->vpg;
				if (vpg && vpg->funcs->vpg_poweron)
					vpg->funcs->vpg_poweron(vpg);
#endif
				resource_build_info_frame(pipe_ctx);
				dc->hwss.update_info_frame(pipe_ctx);
			}
+17 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@
#include "inc/link_enc_cfg.h"
#include "inc/link_dpcd.h"

#include "dc/dcn30/dcn30_vpg.h"

#define DC_LOGGER_INIT(logger)

#define LINK_INFO(...) \
@@ -3608,6 +3610,7 @@ void core_link_enable_stream(
	struct link_encoder *link_enc;
#if defined(CONFIG_DRM_AMD_DC_DCN)
	enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO;
	struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
#endif
	DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);

@@ -3699,6 +3702,12 @@ void core_link_enable_stream(

		pipe_ctx->stream->apply_edp_fast_boot_optimization = false;

#if defined(CONFIG_DRM_AMD_DC_DCN)
		// Enable VPG before building infoframe
		if (vpg && vpg->funcs->vpg_poweron)
			vpg->funcs->vpg_poweron(vpg);
#endif

		resource_build_info_frame(pipe_ctx);
		dc->hwss.update_info_frame(pipe_ctx);

@@ -3845,6 +3854,9 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
	struct dc  *dc = pipe_ctx->stream->ctx->dc;
	struct dc_stream_state *stream = pipe_ctx->stream;
	struct dc_link *link = stream->sink->link;
#if defined(CONFIG_DRM_AMD_DC_DCN)
	struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg;
#endif

	if (!IS_DIAG_DC(dc->ctx->dce_environment) &&
			dc_is_virtual_signal(pipe_ctx->stream->signal))
@@ -3928,6 +3940,11 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
			pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, OUT_MUX_DIO);
	}
#endif

#if defined(CONFIG_DRM_AMD_DC_DCN)
	if (vpg && vpg->funcs->vpg_powerdown)
		vpg->funcs->vpg_powerdown(vpg);
#endif
}

void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
+2 −0
Original line number Diff line number Diff line
@@ -471,6 +471,8 @@ union mem_low_power_enable_options {
		bool cm: 1;
		bool mpc: 1;
		bool optc: 1;
		bool vpg: 1;
		bool afmt: 1;
	} bits;
	uint32_t u32All;
};
+10 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include "hw_shared.h"
#include "inc/link_dpcd.h"
#include "dpcd_defs.h"
#include "dcn30/dcn30_afmt.h"

#define DC_LOGGER \
		enc1->base.ctx->logger
@@ -1401,6 +1402,11 @@ static void enc1_se_disable_dp_audio(
	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
	uint32_t value = 0;

#if defined(CONFIG_DRM_AMD_DC_DCN)
	if (enc->afmt && enc->afmt->funcs->afmt_powerdown)
		enc->afmt->funcs->afmt_powerdown(enc->afmt);
#endif

	/* Disable Audio packets */
	REG_UPDATE_5(DP_SEC_CNTL,
			DP_SEC_ASP_ENABLE, 0,
@@ -1464,6 +1470,10 @@ void enc1_se_hdmi_audio_setup(
void enc1_se_hdmi_audio_disable(
	struct stream_encoder *enc)
{
#if defined(CONFIG_DRM_AMD_DC_DCN)
	if (enc->afmt && enc->afmt->funcs->afmt_powerdown)
		enc->afmt->funcs->afmt_powerdown(enc->afmt);
#endif
	enc1_se_enable_audio_clock(enc, false);
}

+17 −7
Original line number Diff line number Diff line
@@ -44,11 +44,14 @@
	afmt3->base.ctx


static void afmt3_setup_hdmi_audio(
void afmt3_setup_hdmi_audio(
	struct afmt *afmt)
{
	struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);

	if (afmt->funcs->afmt_poweron)
		afmt->funcs->afmt_poweron(afmt);

	/* AFMT_AUDIO_PACKET_CONTROL */
	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);

@@ -113,7 +116,7 @@ static union audio_cea_channels speakers_to_channels(
	return cea_channels;
}

static void afmt3_se_audio_setup(
void afmt3_se_audio_setup(
	struct afmt *afmt,
	unsigned int az_inst,
	struct audio_info *audio_info)
@@ -138,20 +141,24 @@ static void afmt3_se_audio_setup(
	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, channels);

	/* Disable forced mem power off */
	if (afmt->funcs->afmt_poweron == NULL)
		REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0);
}

static void afmt3_audio_mute_control(
void afmt3_audio_mute_control(
	struct afmt *afmt,
	bool mute)
{
	struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);

	if (mute && afmt->funcs->afmt_powerdown)
		afmt->funcs->afmt_powerdown(afmt);
	if (!mute && afmt->funcs->afmt_poweron)
		afmt->funcs->afmt_poweron(afmt);
	/* enable/disable transmission of audio packets */
	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, !mute);
}

static void afmt3_audio_info_immediate_update(
void afmt3_audio_info_immediate_update(
	struct afmt *afmt)
{
	struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
@@ -160,11 +167,14 @@ static void afmt3_audio_info_immediate_update(
	REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);
}

static void afmt3_setup_dp_audio(
void afmt3_setup_dp_audio(
		struct afmt *afmt)
{
	struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);

	if (afmt->funcs->afmt_poweron)
		afmt->funcs->afmt_poweron(afmt);

	/* AFMT_AUDIO_PACKET_CONTROL */
	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);

Loading