[RFC 4/8] drm/i915/bxt: MIPI DSI Register Programming for DSC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: vkorjani <vikas.korjani@xxxxxxxxx>

For compression enabled, the number of bytes in active
region cannot be calculated just by multiplying number
of pixels and bits per pixel, formula in HLD is

ceil((ceil(pixels/num_slice) * bpp) / 8) * num_slice

hence modifying txbyteclkhs() to accommodate calculation
for DSC Enable/Disable  and created a separate
function pixel_to_bytes().

Using modified txbyteclkhs to calculate MIPI_HS_TX_TIMEOUT
As per HLD for computing MIPI_HS_TX_TIMEOUT per line,
1) calculate number of bytes in active region
2) calculate number of bytes in blanking region
Add above two and compute byteclkhs.
similarly for MIPI_HX_TX_TIMEOUT per frame, Add bytes in
active and blanking region should be calculated separately.

Signed-off-by: vkorjani <vikas.korjani@xxxxxxxxx>
Signed-off-by: Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu@xxxxxxxxx>
---
 drivers/gpu/drm/i915/intel_dsi.c |   74 ++++++++++++++++++++++++++++++--------
 1 file changed, 59 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 36fcb86..e566750 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -760,12 +760,48 @@ static u16 txclkesc(u32 divider, unsigned int us)
 	}
 }
 
+static int compute_num_slice(struct drm_encoder *encoder)
+{
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+
+	return DIV_ROUND_UP(intel_dsi->pps_data.pic_height*
+			intel_dsi->pps_data.pic_width,
+			intel_dsi->pps_data.slice_height*
+			intel_dsi->pps_data.slice_width);
+}
+
+static u32 pixel_to_bytes(struct drm_encoder *encoder, u16 pixels, int bpp)
+{
+
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+	int num_slice;
+
+	if (intel_dsi->dsc_enable) {
+		num_slice = compute_num_slice(encoder);
+		if (num_slice <= 0)
+			num_slice = 1;
+		bpp =  intel_dsi->pps_data.bits_per_pixel / 16;
+		return DIV_ROUND_UP((DIV_ROUND_UP(pixels, num_slice)) * bpp, 8)
+			* num_slice;
+	} else
+		return DIV_ROUND_UP((pixels * bpp), 8);
+}
+
+
 /* return pixels in terms of txbyteclkhs */
-static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count,
-		       u16 burst_mode_ratio)
+static u16 txbyteclkhs(struct drm_encoder *encoder, u16 pixels, int bpp,
+		int lane_count, u16 burst_mode_ratio, bool dsc_calc)
 {
-	return DIV_ROUND_UP(DIV_ROUND_UP(pixels * bpp * burst_mode_ratio,
-					 8 * 100), lane_count);
+	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+	u32 pixel_bytes;
+
+	if (intel_dsi->dsc_enable && dsc_calc) {
+		pixel_bytes = pixel_to_bytes(encoder, pixels, bpp);
+		return DIV_ROUND_UP(DIV_ROUND_UP(pixel_bytes *
+					burst_mode_ratio, 100), lane_count);
+	} else
+		return DIV_ROUND_UP(DIV_ROUND_UP(pixels * bpp *
+			burst_mode_ratio, 8 * 100), lane_count);
 }
 
 static void set_dsi_timings(struct drm_encoder *encoder,
@@ -800,12 +836,14 @@ static void set_dsi_timings(struct drm_encoder *encoder,
 	vbp = mode->vtotal - mode->vsync_end;
 
 	/* horizontal values are in terms of high speed byte clock */
-	hactive = txbyteclkhs(hactive, bpp, lane_count,
-			      intel_dsi->burst_mode_ratio);
-	hfp = txbyteclkhs(hfp, bpp, lane_count, intel_dsi->burst_mode_ratio);
-	hsync = txbyteclkhs(hsync, bpp, lane_count,
-			    intel_dsi->burst_mode_ratio);
-	hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio);
+	hactive = txbyteclkhs(encoder, hactive, bpp, lane_count,
+			      intel_dsi->burst_mode_ratio, true);
+	hfp = txbyteclkhs(encoder, hfp, bpp, lane_count,
+				intel_dsi->burst_mode_ratio, true);
+	hsync = txbyteclkhs(encoder, hsync, bpp, lane_count,
+			    intel_dsi->burst_mode_ratio, true);
+	hbp = txbyteclkhs(encoder, hbp, bpp, lane_count,
+				intel_dsi->burst_mode_ratio, true);
 
 	for_each_dsi_port(port, intel_dsi->ports) {
 		if (IS_BROXTON(dev)) {
@@ -851,6 +889,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
 	unsigned int bpp = intel_crtc->config->pipe_bpp;
 	u32 val, tmp;
 	u16 mode_hdisplay;
+	u32 hactive, hblank;
 
 	DRM_DEBUG_KMS("pipe %c\n", pipe_name(intel_crtc->pipe));
 
@@ -943,18 +982,23 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
 		 * said value is recommended.
 		 */
 
+		hactive = pixel_to_bytes(encoder, adjusted_mode->hdisplay, bpp);
+		hblank = pixel_to_bytes(encoder, (adjusted_mode->htotal -
+					adjusted_mode->hsync_end), bpp);
+
 		if (is_vid_mode(intel_dsi) &&
 			intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
 			I915_WRITE(MIPI_HS_TX_TIMEOUT(port),
-				txbyteclkhs(adjusted_mode->htotal, bpp,
+				txbyteclkhs(encoder, (hactive + hblank), bpp,
 					intel_dsi->lane_count,
-					intel_dsi->burst_mode_ratio) + 1);
+					intel_dsi->burst_mode_ratio, true) + 1);
 		} else {
 			I915_WRITE(MIPI_HS_TX_TIMEOUT(port),
-				txbyteclkhs(adjusted_mode->vtotal *
-					adjusted_mode->htotal,
+				txbyteclkhs(encoder, adjusted_mode->vtotal *
+					(hactive + hblank),
 					bpp, intel_dsi->lane_count,
-					intel_dsi->burst_mode_ratio) + 1);
+					intel_dsi->burst_mode_ratio, false) +
+					1);
 		}
 		I915_WRITE(MIPI_LP_RX_TIMEOUT(port), intel_dsi->lp_rx_timeout);
 		I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(port),
-- 
1.7.9.5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux