Commit 380604e2 authored by Ken Chalmers's avatar Ken Chalmers Committed by Alex Deucher
Browse files

drm/amd/display: Use 100 Hz precision for pipe pixel clocks



[Why]
Users would like more accurate pixel clocks, especially for fractional
"TV" frame rates like 59.94 Hz.

[How]
Store and communicate pixel clocks with 100 Hz accuracy from
dc_crtc_timing through to BIOS command table setpixelclock call.

Signed-off-by: default avatarKen Chalmers <ken.chalmers@amd.com>
Reviewed-by: default avatarCharlene Liu <Charlene.Liu@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 43995f8f
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -2580,7 +2580,7 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing)
		 * according to HDMI spec, we use YCbCr709 and YCbCr601
		 * respectively
		 */
		if (dc_crtc_timing->pix_clk_khz > 27030) {
		if (dc_crtc_timing->pix_clk_100hz > 270300) {
			if (dc_crtc_timing->flags.Y_ONLY)
				color_space =
					COLOR_SPACE_YCBCR709_LIMITED;
@@ -2623,7 +2623,7 @@ static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_
	if (timing_out->display_color_depth <= COLOR_DEPTH_888)
		return;
	do {
		normalized_clk = timing_out->pix_clk_khz;
		normalized_clk = timing_out->pix_clk_100hz / 10;
		/* YCbCr 4:2:0 requires additional adjustment of 1/2 */
		if (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420)
			normalized_clk /= 2;
@@ -2704,7 +2704,7 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
		mode_in->crtc_vsync_start - mode_in->crtc_vdisplay;
	timing_out->v_sync_width =
		mode_in->crtc_vsync_end - mode_in->crtc_vsync_start;
	timing_out->pix_clk_khz = mode_in->crtc_clock;
	timing_out->pix_clk_100hz = mode_in->crtc_clock * 10;
	timing_out->aspect_ratio = get_aspect_ratio(mode_in);

	stream->output_color_space = get_output_color_space(timing_out);
@@ -2832,7 +2832,7 @@ static void set_master_stream(struct dc_stream_state *stream_set[],
		if (stream_set[j] && stream_set[j]->triggered_crtc_reset.enabled) {
			int refresh_rate = 0;

			refresh_rate = (stream_set[j]->timing.pix_clk_khz*1000)/
			refresh_rate = (stream_set[j]->timing.pix_clk_100hz*100)/
				(stream_set[j]->timing.h_total*stream_set[j]->timing.v_total);
			if (refresh_rate > highest_rfr) {
				highest_rfr = refresh_rate;
+1 −1
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
	mst_port = aconnector->port;

	if (enable) {
		clock = stream->timing.pix_clk_khz;
		clock = stream->timing.pix_clk_100hz / 10;

		switch (stream->timing.display_color_depth) {

+9 −10
Original line number Diff line number Diff line
@@ -964,9 +964,9 @@ static enum bp_result set_pixel_clock_v3(
	allocation.sPCLKInput.ucPostDiv =
			(uint8_t)bp_params->pixel_clock_post_divider;

	/* We need to convert from KHz units into 10KHz units */
	/* We need to convert from 100Hz units into 10KHz units */
	allocation.sPCLKInput.usPixelClock =
			cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
			cpu_to_le16((uint16_t)(bp_params->target_pixel_clock_100hz / 100));

	params = (PIXEL_CLOCK_PARAMETERS_V3 *)&allocation.sPCLKInput;
	params->ucTransmitterId =
@@ -1042,9 +1042,9 @@ static enum bp_result set_pixel_clock_v5(
				(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
						bp_params->signal_type, false);

		/* We need to convert from KHz units into 10KHz units */
		/* We need to convert from 100Hz units into 10KHz units */
		clk.sPCLKInput.usPixelClock =
				cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
				cpu_to_le16((uint16_t)(bp_params->target_pixel_clock_100hz / 100));

		if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
			clk.sPCLKInput.ucMiscInfo |=
@@ -1118,9 +1118,9 @@ static enum bp_result set_pixel_clock_v6(
				(uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(
						bp_params->signal_type, false);

		/* We need to convert from KHz units into 10KHz units */
		/* We need to convert from 100 Hz units into 10KHz units */
		clk.sPCLKInput.ulCrtcPclkFreq.ulPixelClock =
				cpu_to_le32(bp_params->target_pixel_clock / 10);
				cpu_to_le32(bp_params->target_pixel_clock_100hz / 100);

		if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) {
			clk.sPCLKInput.ucMiscInfo |=
@@ -1182,8 +1182,7 @@ static enum bp_result set_pixel_clock_v7(
		clk.ucTransmitterID = bp->cmd_helper->encoder_id_to_atom(dal_graphics_object_id_get_encoder_id(bp_params->encoder_object_id));
		clk.ucEncoderMode = (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(bp_params->signal_type, false);

		/* We need to convert from KHz units into 10KHz units */
		clk.ulPixelClock = cpu_to_le32(bp_params->target_pixel_clock * 10);
		clk.ulPixelClock = cpu_to_le32(bp_params->target_pixel_clock_100hz);

		clk.ucDeepColorRatio = (uint8_t) bp->cmd_helper->transmitter_color_depth_to_atom(bp_params->color_depth);

@@ -2164,7 +2163,7 @@ static enum bp_result program_clock_v5(
	/* We need to convert from KHz units into 10KHz units */
	params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id;
	params.sPCLKInput.usPixelClock =
			cpu_to_le16((uint16_t) (bp_params->target_pixel_clock / 10));
			cpu_to_le16((uint16_t) (bp_params->target_pixel_clock_100hz / 100));
	params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID;

	if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
@@ -2196,7 +2195,7 @@ static enum bp_result program_clock_v6(
	/* We need to convert from KHz units into 10KHz units */
	params.sPCLKInput.ucPpll = (uint8_t)atom_pll_id;
	params.sPCLKInput.ulDispEngClkFreq =
			cpu_to_le32(bp_params->target_pixel_clock / 10);
			cpu_to_le32(bp_params->target_pixel_clock_100hz / 100);

	if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
		params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
+2 −4
Original line number Diff line number Diff line
@@ -301,9 +301,7 @@ static enum bp_result set_pixel_clock_v7(
			cmd_helper->encoder_mode_bp_to_atom(
				bp_params->signal_type, false);

		/* We need to convert from KHz units into 10KHz units */
		clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock *
				10);
		clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock_100hz);

		clk.deep_color_ratio =
			(uint8_t) bp->cmd_helper->
@@ -311,7 +309,7 @@ static enum bp_result set_pixel_clock_v7(
					bp_params->color_depth);
		DC_LOG_BIOS("%s:program display clock = %d"\
				"colorDepth = %d\n", __func__,\
				bp_params->target_pixel_clock, bp_params->color_depth);
				bp_params->target_pixel_clock_100hz, bp_params->color_depth);

		if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
+5 −5
Original line number Diff line number Diff line
@@ -2792,7 +2792,7 @@ static void populate_initial_data(
		data->lpt_en[num_displays + 4] = false;
		data->h_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.h_total);
		data->v_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.v_total);
		data->pixel_rate[num_displays + 4] = bw_frc_to_fixed(pipe[i].stream->timing.pix_clk_khz, 1000);
		data->pixel_rate[num_displays + 4] = bw_frc_to_fixed(pipe[i].stream->timing.pix_clk_100hz, 10000);
		data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.viewport.width);
		data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
		data->src_height[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.viewport.height);
@@ -2881,7 +2881,7 @@ static void populate_initial_data(

	/* Pipes without underlay after */
	for (i = 0; i < pipe_count; i++) {
		unsigned int pixel_clock_khz;
		unsigned int pixel_clock_100hz;
		if (!pipe[i].stream || pipe[i].bottom_pipe)
			continue;

@@ -2890,10 +2890,10 @@ static void populate_initial_data(
		data->lpt_en[num_displays + 4] = false;
		data->h_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.h_total);
		data->v_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.v_total);
		pixel_clock_khz = pipe[i].stream->timing.pix_clk_khz;
		pixel_clock_100hz = pipe[i].stream->timing.pix_clk_100hz;
		if (pipe[i].stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
			pixel_clock_khz *= 2;
		data->pixel_rate[num_displays + 4] = bw_frc_to_fixed(pixel_clock_khz, 1000);
			pixel_clock_100hz *= 2;
		data->pixel_rate[num_displays + 4] = bw_frc_to_fixed(pixel_clock_100hz, 10000);
		if (pipe[i].plane_state) {
			data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.viewport.width);
			data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
Loading