Commit bd870cfd authored by Nicholas Kazlauskas's avatar Nicholas Kazlauskas Committed by Alex Deucher
Browse files

drm/amd/display: Add seamless boot support for more DIG operation modes



[Why]
When pre-OS firmware enables display support for displays that operate
the DIG in 2 pixels per cycle processing modes the inferred pixel rate
from get_pixel_clk_frequency_100hz does not account for the true pixel
rate since we're outputting 2 per cycle past the stream encoder.

This causes seamless boot validation to abort early.

[How]
Add a new stream encoder function for getting pixels per cycle from the
stream encoder. If the pixels per cycle is greater than 1 and the driver
policy is to enable 2 pixels per cycle for post-OS then allow seamless
boot to continue.

Signed-off-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: default avatarDuncan Ma <duncan.ma@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarRodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent df18a4de
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -1823,10 +1823,18 @@ bool dc_validate_boot_timing(const struct dc *dc,
			tg->funcs->get_optc_source(tg,
						&numOdmPipes, &id_src[0], &id_src[1]);

		if (numOdmPipes == 2)
		if (numOdmPipes == 2) {
			pix_clk_100hz *= 2;
		if (numOdmPipes == 4)
		} else if (numOdmPipes == 4) {
			pix_clk_100hz *= 4;
		} else if (se && se->funcs->get_pixels_per_cycle) {
			uint32_t pixels_per_cycle = se->funcs->get_pixels_per_cycle(se);

			if (pixels_per_cycle != 1 && !dc->debug.enable_dp_dig_pixel_rate_div_policy)
				return false;

			pix_clk_100hz *= pixels_per_cycle;
		}

		// Note: In rare cases, HW pixclk may differ from crtc's pixclk
		// slightly due to rounding issues in 10 kHz units.
+19 −0
Original line number Diff line number Diff line
@@ -422,6 +422,24 @@ void enc35_enable_fifo(struct stream_encoder *enc)
	REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1);
}

static uint32_t enc35_get_pixels_per_cycle(struct stream_encoder *enc)
{
	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
	uint32_t value;

	REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_OUTPUT_PIXEL_MODE, &value);

	switch (value) {
	case 0:
		return 1;
	case 1:
		return 2;
	default:
		ASSERT_CRITICAL(false);
		return 1;
	}
}

static const struct stream_encoder_funcs dcn35_str_enc_funcs = {
	.dp_set_odm_combine =
		enc314_dp_set_odm_combine,
@@ -474,6 +492,7 @@ static const struct stream_encoder_funcs dcn35_str_enc_funcs = {
	.disable_fifo = enc35_disable_fifo,
	.is_fifo_enabled = enc35_is_fifo_enabled,
	.map_stream_to_link = enc35_stream_encoder_map_to_link,
	.get_pixels_per_cycle = enc35_get_pixels_per_cycle,
};

void dcn35_dio_stream_encoder_construct(
+1 −0
Original line number Diff line number Diff line
@@ -273,6 +273,7 @@ struct stream_encoder_funcs {
	void (*disable_fifo)(struct stream_encoder *enc);
	bool (*is_fifo_enabled)(struct stream_encoder *enc);
	void (*map_stream_to_link)(struct stream_encoder *enc, uint32_t stream_enc_inst, uint32_t link_enc_inst);
	uint32_t (*get_pixels_per_cycle)(struct stream_encoder *enc);
};

struct hpo_dp_stream_encoder_state {