Commit 94267b3d authored by Sylvia Tsai's avatar Sylvia Tsai Committed by Alex Deucher
Browse files

drm/amd/display: PSR Refactor



- Refacotr PSR to follow correct module pattern
- fix eDP only working on sink index 0.

Signed-off-by: default avatarSylvia Tsai <sylvia.tsai@amd.com>
Acked-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent d27383a2
Loading
Loading
Loading
Loading
+29 −45
Original line number Diff line number Diff line
@@ -199,6 +199,32 @@ static bool set_gamut_remap(struct dc *dc,
	return ret;
}

static void set_static_screen_events(struct dc *dc,
		const struct dc_stream **stream,
		int num_streams,
		const struct dc_static_screen_events *events)
{
	struct core_dc *core_dc = DC_TO_CORE(dc);
	int i = 0;
	int j = 0;
	struct pipe_ctx *pipes_affected[MAX_PIPES];
	int num_pipes_affected = 0;

	for (i = 0; i < num_streams; i++) {
		struct core_stream *core_stream = DC_STREAM_TO_CORE(stream[i]);

		for (j = 0; j < MAX_PIPES; j++) {
			if (core_dc->current_context->res_ctx.pipe_ctx[j].stream
					== core_stream) {
				pipes_affected[num_pipes_affected++] =
						&core_dc->current_context->res_ctx.pipe_ctx[j];
			}
		}
	}

	core_dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, events);
}

/* This function is not expected to fail, proper implementation of
 * validation will prevent this from ever being called for unsupported
 * configurations.
@@ -240,45 +266,6 @@ static void stream_update_scaling(
	}
}

static bool set_psr_enable(struct dc *dc, bool enable)
{
	struct core_dc *core_dc = DC_TO_CORE(dc);
	int i;

	for (i = 0; i < core_dc->link_count; i++)
		dc_link_set_psr_enable(&core_dc->links[i]->public,
				enable);

	return true;
}


static bool setup_psr(struct dc *dc, const struct dc_stream *stream)
{
	struct core_dc *core_dc = DC_TO_CORE(dc);
	struct core_stream *core_stream = DC_STREAM_TO_CORE(stream);
	struct pipe_ctx *pipes;
	int i;
	unsigned int underlay_idx = core_dc->res_pool->underlay_pipe_index;

	for (i = 0; i < core_dc->link_count; i++) {
		if (core_stream->sink->link == core_dc->links[i])
			dc_link_setup_psr(&core_dc->links[i]->public,
					stream);
	}

	for (i = 0; i < MAX_PIPES; i++) {
		if (core_dc->current_context->res_ctx.pipe_ctx[i].stream
				== core_stream && i != underlay_idx) {
			pipes = &core_dc->current_context->res_ctx.pipe_ctx[i];
			core_dc->hwss.set_static_screen_control(&pipes, 1,
					0x182);
		}
	}

	return true;
}

static void set_drive_settings(struct dc *dc,
		struct link_training_settings *lt_settings,
		const struct dc_link *link)
@@ -359,15 +346,12 @@ static void allocate_dc_stream_funcs(struct core_dc *core_dc)
				stream_adjust_vmin_vmax;
	}

	core_dc->public.stream_funcs.set_static_screen_events =
			set_static_screen_events;

	core_dc->public.stream_funcs.set_gamut_remap =
			set_gamut_remap;

	core_dc->public.stream_funcs.set_psr_enable =
			set_psr_enable;

	core_dc->public.stream_funcs.setup_psr =
			setup_psr;

	core_dc->public.link_funcs.set_drive_settings =
			set_drive_settings;

+10 −12
Original line number Diff line number Diff line
@@ -1430,14 +1430,14 @@ bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable)
	struct core_dc *core_dc = DC_TO_CORE(ctx->dc);
	struct dmcu *dmcu = core_dc->res_pool->dmcu;

	if (dmcu != NULL && dc_link->psr_caps.psr_version > 0)
	if (dmcu != NULL && link->psr_enabled)
		dmcu->funcs->set_psr_enable(dmcu, enable);

	return true;
}

bool dc_link_setup_psr(const struct dc_link *dc_link,
		const struct dc_stream *stream)
		const struct dc_stream *stream, struct psr_config *psr_config)
{
	struct core_link *link = DC_LINK_TO_CORE(dc_link);
	struct dc_context *ctx = link->ctx;
@@ -1449,10 +1449,8 @@ bool dc_link_setup_psr(const struct dc_link *dc_link,

	psr_context.controllerId = CONTROLLER_ID_UNDEFINED;


	if (dc_link != NULL &&
		dmcu != NULL &&
		dc_link->psr_caps.psr_version > 0) {
		dmcu != NULL) {
		/* updateSinkPsrDpcdConfig*/
		union dpcd_psr_configuration psr_configuration;

@@ -1461,10 +1459,10 @@ bool dc_link_setup_psr(const struct dc_link *dc_link,
		psr_configuration.bits.ENABLE                    = 1;
		psr_configuration.bits.CRC_VERIFICATION          = 1;
		psr_configuration.bits.FRAME_CAPTURE_INDICATION  =
			dc_link->psr_caps.psr_frame_capture_indication_req;
				psr_config->psr_frame_capture_indication_req;

		/* Check for PSR v2*/
		if (dc_link->psr_caps.psr_version == 0x2) {
		if (psr_config->psr_version == 0x2) {
			/* For PSR v2 selective update.
			 * Indicates whether sink should start capturing
			 * immediately following active scan line,
@@ -1512,14 +1510,13 @@ bool dc_link_setup_psr(const struct dc_link *dc_link,
						stream->timing.v_total),
						stream->timing.h_total);

		psr_context.psrSupportedDisplayConfig =
			(dc_link->psr_caps.psr_version > 0) ? true : false;
		psr_context.psrSupportedDisplayConfig = true;
		psr_context.psrExitLinkTrainingRequired =
			dc_link->psr_caps.psr_exit_link_training_required;
			psr_config->psr_exit_link_training_required;
		psr_context.sdpTransmitLineNumDeadline =
			dc_link->psr_caps.psr_sdp_transmit_line_num_deadline;
			psr_config->psr_sdp_transmit_line_num_deadline;
		psr_context.psrFrameCaptureIndicationReq =
			dc_link->psr_caps.psr_frame_capture_indication_req;
			psr_config->psr_frame_capture_indication_req;

		psr_context.skipPsrWaitForPllLock = 0; /* only = 1 in KV */

@@ -1550,6 +1547,7 @@ bool dc_link_setup_psr(const struct dc_link *dc_link,
		 */
		psr_context.frame_delay = 0;

		link->psr_enabled = true;
		dmcu->funcs->setup_psr(dmcu, link, &psr_context);
		return true;
	} else
+1 −52
Original line number Diff line number Diff line
@@ -1478,7 +1478,7 @@ static bool handle_hpd_irq_psr_sink(const struct core_link *link)
{
	union dpcd_psr_configuration psr_configuration;

	if (link->public.psr_caps.psr_version == 0)
	if (!link->psr_enabled)
		return false;

	dm_helpers_dp_read_dpcd(
@@ -2060,36 +2060,6 @@ static void dp_wa_power_up_0010FA(struct core_link *link, uint8_t *dpcd_data,
		link->wa_flags.dp_keep_receiver_powered = false;
}

static void retrieve_psr_link_cap(struct core_link *link,
		enum edp_revision edp_revision)
{
	if (edp_revision >= EDP_REVISION_13) {
		core_link_read_dpcd(link,
				DP_PSR_SUPPORT,
				(uint8_t *)(&link->public.psr_caps),
				sizeof(link->public.psr_caps));
		if (link->public.psr_caps.psr_version != 0) {
			unsigned char psr_capability = 0;

			core_link_read_dpcd(link,
					    DP_PSR_CAPS,
						&psr_capability,
						sizeof(psr_capability));
			/* Bit 0 determines whether fast link training is
			 * required on PSR exit. If set to 0, link training
			 * is required. If set to 1, sink must lock within
			 * five Idle Patterns after Main Link is turned on.
			 */
			link->public.psr_caps.psr_exit_link_training_required
						= !(psr_capability & 0x1);

			psr_capability = (psr_capability >> 1) & 0x7;
			link->public.psr_caps.psr_rfb_setup_time =
					55 * (6 - psr_capability);
		}
	}
}

static void retrieve_link_cap(struct core_link *link)
{
	uint8_t dpcd_data[DP_TRAINING_AUX_RD_INTERVAL - DP_DPCD_REV + 1];
@@ -2157,38 +2127,17 @@ static void retrieve_link_cap(struct core_link *link)
	link->dpcd_caps.panel_mode_edp =
		edp_config_cap.bits.ALT_SCRAMBLER_RESET;

	link->edp_revision = EDP_REVISION_11;

	link->public.test_pattern_enabled = false;
	link->public.compliance_test_state.raw = 0;

	link->public.psr_caps.psr_exit_link_training_required = false;
	link->public.psr_caps.psr_frame_capture_indication_req = false;
	link->public.psr_caps.psr_rfb_setup_time = 0;
	link->public.psr_caps.psr_sdp_transmit_line_num_deadline = 0;
	link->public.psr_caps.psr_version = 0;

	/* read sink count */
	core_link_read_dpcd(link,
			DP_SINK_COUNT,
			&link->dpcd_caps.sink_count.raw,
			sizeof(link->dpcd_caps.sink_count.raw));

	/* Display control registers starting at DPCD 700h are only valid and
	 * enabled if this eDP config cap bit is set. */
	if (edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE) {
		/* Read the Panel's eDP revision at DPCD 700h. */
		core_link_read_dpcd(link,
			DP_EDP_DPCD_REV,
			(uint8_t *)(&link->edp_revision),
			sizeof(link->edp_revision));
	}

	/* Connectivity log: detection */
	CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: ");

	/* TODO: Confirm if need retrieve_psr_link_cap */
	retrieve_psr_link_cap(link, link->edp_revision);
}

void detect_dp_sink_caps(struct core_link *link)
+1 −1
Original line number Diff line number Diff line
@@ -2015,7 +2015,7 @@ static void set_vsc_info_packet(
	unsigned int vscPacketRevision = 0;
	unsigned int i;

	if (stream->sink->link->public.psr_caps.psr_version != 0) {
	if (stream->sink->link->psr_enabled) {
		vscPacketRevision = 2;
	}

+13 −4
Original line number Diff line number Diff line
@@ -82,6 +82,12 @@ struct dc_surface_dcc_cap {
	};
};

struct dc_static_screen_events {
	bool cursor_update;
	bool surface_update;
	bool overlay_update;
};

/* Forward declaration*/
struct dc;
struct dc_surface;
@@ -102,10 +108,14 @@ struct dc_stream_funcs {
			const struct dc_stream *dc_stream,
			const struct rect *src,
			const struct rect *dst);

	bool (*set_gamut_remap)(struct dc *dc,
			const struct dc_stream **stream, int num_streams);
	bool (*set_psr_enable)(struct dc *dc, bool enable);
	bool (*setup_psr)(struct dc *dc, const struct dc_stream *stream);

	void (*set_static_screen_events)(struct dc *dc,
			const struct dc_stream **stream,
			int num_streams,
			const struct dc_static_screen_events *events);
};

struct link_training_settings;
@@ -604,7 +614,6 @@ struct dc_link {
	uint8_t ddc_hw_inst;
	uint8_t link_enc_hw_inst;

	struct psr_caps psr_caps;
	bool test_pattern_enabled;
	union compliance_test_state compliance_test_state;

@@ -657,7 +666,7 @@ bool dc_link_set_backlight_level(const struct dc_link *dc_link, uint32_t level,
bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable);

bool dc_link_setup_psr(const struct dc_link *dc_link,
		const struct dc_stream *stream);
		const struct dc_stream *stream, struct psr_config *psr_config);

/* Request DC to detect if there is a Panel connected.
 * boot - If this call is during initial boot.
Loading