diff mbox series

[RFC,3/7] drm/i915/dsi: Add vblank calculation for command mode

Message ID 20191014110122.31923-4-vandita.kulkarni@intel.com (mailing list archive)
State New, archived
Headers show
Series Add mipi dsi command mode support. | expand

Commit Message

Kulkarni, Vandita Oct. 14, 2019, 11:01 a.m. UTC
Transcoder timing calculation differ for command mode.

Signed-off-by: Vandita Kulkarni <vandita.kulkarni@intel.com>
---
 drivers/gpu/drm/i915/display/icl_dsi.c | 56 +++++++++++++++++---------
 1 file changed, 37 insertions(+), 19 deletions(-)

Comments

Jani Nikula Oct. 15, 2019, 6:45 p.m. UTC | #1
On Mon, 14 Oct 2019, Vandita Kulkarni <vandita.kulkarni@intel.com> wrote:
> Transcoder timing calculation differ for command mode.
>
> Signed-off-by: Vandita Kulkarni <vandita.kulkarni@intel.com>
> ---
>  drivers/gpu/drm/i915/display/icl_dsi.c | 56 +++++++++++++++++---------
>  1 file changed, 37 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> index 8e6c09a1db78..5dd9eebab6b1 100644
> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> @@ -780,6 +780,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
>  	u16 hback_porch;
>  	/* vertical timings */
>  	u16 vtotal, vactive, vsync_start, vsync_end, vsync_shift;
> +	int bpp, line_time_us, byte_clk_period_ns;
>  
>  	hactive = adjusted_mode->crtc_hdisplay;
>  	htotal = adjusted_mode->crtc_htotal;
> @@ -841,40 +842,57 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
>  	}
>  
>  	/* program TRANS_VTOTAL register */
> -	for_each_dsi_port(port, intel_dsi->ports) {
> -		dsi_trans = dsi_port_to_transcoder(port);
> -		/*
> -		 * FIXME: Programing this by assuming progressive mode, since
> -		 * non-interlaced info from VBT is not saved inside
> -		 * struct drm_display_mode.
> -		 * For interlace mode: program required pixel minus 2
> -		 */
> -		I915_WRITE(VTOTAL(dsi_trans),
> -			   (vactive - 1) | ((vtotal - 1) << 16));
> +	if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) {

There's is_vid_mode() and is_cmd_mode(). Use them throughout the series
instead of the above.

> +		for_each_dsi_port(port, intel_dsi->ports) {
> +			dsi_trans = dsi_port_to_transcoder(port);
> +			/*
> +			 * FIXME: Programing this by assuming progressive mode,
> +			 * since non-interlaced info from VBT is not saved
> +			 * inside struct drm_display_mode.
> +			 * For interlace mode: program required pixel minus 2
> +			 */
> +			I915_WRITE(VTOTAL(dsi_trans),
> +				   (vactive - 1) | ((vtotal - 1) << 16));
> +		}
> +	} else {
> +		for_each_dsi_port(port, intel_dsi->ports) {
> +			bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
> +			byte_clk_period_ns = 8 * 1000000 / intel_dsi->pclk;
> +			htotal = hactive + 160;
> +			line_time_us = (htotal * (bpp / 8) * byte_clk_period_ns) / (1000 * intel_dsi->lane_count);
> +			vtotal = vactive + DIV_ROUND_UP(460, line_time_us);

This is a bit hand-wavy, but some of these seem suspicious. Someone(tm)
needs to go through these in detail.

> +			I915_WRITE(VTOTAL(dsi_trans),
> +				   (vactive - 1) | ((vtotal - 1) << 16));
> +		}
>  	}

As the I915_WRITE() is the same for both, albeit with changed values for
cmd mode, I think it would be better to have the mode check within the
for_each_dsi_port() block.

>  
> +
>  	if (vsync_end < vsync_start || vsync_end > vtotal)
>  		DRM_ERROR("Invalid vsync_end value\n");
>  
>  	if (vsync_start < vactive)
>  		DRM_ERROR("vsync_start less than vactive\n");
>  
> -	/* program TRANS_VSYNC register */
> -	for_each_dsi_port(port, intel_dsi->ports) {
> -		dsi_trans = dsi_port_to_transcoder(port);
> -		I915_WRITE(VSYNC(dsi_trans),
> -			   (vsync_start - 1) | ((vsync_end - 1) << 16));
> +	/* program TRANS_VSYNC register for video mode only */
> +	if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) {
> +		for_each_dsi_port(port, intel_dsi->ports) {
> +			dsi_trans = dsi_port_to_transcoder(port);
> +			I915_WRITE(VSYNC(dsi_trans),
> +				   (vsync_start - 1) | ((vsync_end - 1) << 16));
> +		}
>  	}
>  
>  	/*
> -	 * FIXME: It has to be programmed only for interlaced
> +	 * FIXME: It has to be programmed only for video modes and interlaced
>  	 * modes. Put the check condition here once interlaced
>  	 * info available as described above.
>  	 * program TRANS_VSYNCSHIFT register
>  	 */
> -	for_each_dsi_port(port, intel_dsi->ports) {
> -		dsi_trans = dsi_port_to_transcoder(port);
> -		I915_WRITE(VSYNCSHIFT(dsi_trans), vsync_shift);
> +	if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) {
> +		for_each_dsi_port(port, intel_dsi->ports) {
> +			dsi_trans = dsi_port_to_transcoder(port);
> +			I915_WRITE(VSYNCSHIFT(dsi_trans), vsync_shift);
> +		}
>  	}
>  
>  	/* program TRANS_VBLANK register, should be same as vtotal programmed */
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 8e6c09a1db78..5dd9eebab6b1 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -780,6 +780,7 @@  gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
 	u16 hback_porch;
 	/* vertical timings */
 	u16 vtotal, vactive, vsync_start, vsync_end, vsync_shift;
+	int bpp, line_time_us, byte_clk_period_ns;
 
 	hactive = adjusted_mode->crtc_hdisplay;
 	htotal = adjusted_mode->crtc_htotal;
@@ -841,40 +842,57 @@  gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
 	}
 
 	/* program TRANS_VTOTAL register */
-	for_each_dsi_port(port, intel_dsi->ports) {
-		dsi_trans = dsi_port_to_transcoder(port);
-		/*
-		 * FIXME: Programing this by assuming progressive mode, since
-		 * non-interlaced info from VBT is not saved inside
-		 * struct drm_display_mode.
-		 * For interlace mode: program required pixel minus 2
-		 */
-		I915_WRITE(VTOTAL(dsi_trans),
-			   (vactive - 1) | ((vtotal - 1) << 16));
+	if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) {
+		for_each_dsi_port(port, intel_dsi->ports) {
+			dsi_trans = dsi_port_to_transcoder(port);
+			/*
+			 * FIXME: Programing this by assuming progressive mode,
+			 * since non-interlaced info from VBT is not saved
+			 * inside struct drm_display_mode.
+			 * For interlace mode: program required pixel minus 2
+			 */
+			I915_WRITE(VTOTAL(dsi_trans),
+				   (vactive - 1) | ((vtotal - 1) << 16));
+		}
+	} else {
+		for_each_dsi_port(port, intel_dsi->ports) {
+			bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
+			byte_clk_period_ns = 8 * 1000000 / intel_dsi->pclk;
+			htotal = hactive + 160;
+			line_time_us = (htotal * (bpp / 8) * byte_clk_period_ns) / (1000 * intel_dsi->lane_count);
+			vtotal = vactive + DIV_ROUND_UP(460, line_time_us);
+			I915_WRITE(VTOTAL(dsi_trans),
+				   (vactive - 1) | ((vtotal - 1) << 16));
+		}
 	}
 
+
 	if (vsync_end < vsync_start || vsync_end > vtotal)
 		DRM_ERROR("Invalid vsync_end value\n");
 
 	if (vsync_start < vactive)
 		DRM_ERROR("vsync_start less than vactive\n");
 
-	/* program TRANS_VSYNC register */
-	for_each_dsi_port(port, intel_dsi->ports) {
-		dsi_trans = dsi_port_to_transcoder(port);
-		I915_WRITE(VSYNC(dsi_trans),
-			   (vsync_start - 1) | ((vsync_end - 1) << 16));
+	/* program TRANS_VSYNC register for video mode only */
+	if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) {
+		for_each_dsi_port(port, intel_dsi->ports) {
+			dsi_trans = dsi_port_to_transcoder(port);
+			I915_WRITE(VSYNC(dsi_trans),
+				   (vsync_start - 1) | ((vsync_end - 1) << 16));
+		}
 	}
 
 	/*
-	 * FIXME: It has to be programmed only for interlaced
+	 * FIXME: It has to be programmed only for video modes and interlaced
 	 * modes. Put the check condition here once interlaced
 	 * info available as described above.
 	 * program TRANS_VSYNCSHIFT register
 	 */
-	for_each_dsi_port(port, intel_dsi->ports) {
-		dsi_trans = dsi_port_to_transcoder(port);
-		I915_WRITE(VSYNCSHIFT(dsi_trans), vsync_shift);
+	if (intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE) {
+		for_each_dsi_port(port, intel_dsi->ports) {
+			dsi_trans = dsi_port_to_transcoder(port);
+			I915_WRITE(VSYNCSHIFT(dsi_trans), vsync_shift);
+		}
 	}
 
 	/* program TRANS_VBLANK register, should be same as vtotal programmed */