diff mbox

[RFC,05/18] drm/i915: Adjusting the pclk for dual link and burst mode

Message ID 1435326722-24633-6-git-send-email-ramalingam.c@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ramalingam C June 26, 2015, 1:51 p.m. UTC
dsi_clk is calculated for the clock of passed drm_display_mode
and pclk is adjusted considering dual link and the burst mode.

This change is required to make the drrs to co-exist with dual link
and Burst mode.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_dsi_pll.c |   77 ++++++++++++++++++++++++++++++----
 1 file changed, 68 insertions(+), 9 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
index c58eb02..ce5949f 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -128,13 +128,11 @@  static u32 dsi_rr_formula(const struct drm_display_mode *mode,
 
 #else
 
-/* Get DSI clock from pixel clock */
-static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count)
+static u32 intel_get_bits_per_pixel(struct intel_dsi *intel_dsi)
 {
-	u32 dsi_clk_khz;
 	u32 bpp;
 
-	switch (pixel_format) {
+	switch (intel_dsi->pixel_format) {
 	default:
 	case VID_MODE_FORMAT_RGB888:
 	case VID_MODE_FORMAT_RGB666_LOOSE:
@@ -147,10 +145,70 @@  static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count)
 		bpp = 16;
 		break;
 	}
+	return bpp;
+}
+
+void adjust_pclk_for_dual_link(struct intel_dsi *intel_dsi,
+				struct drm_display_mode *mode, u32 *pclk)
+{
+	/* In dual link mode each port needs half of pixel clock */
+	*pclk = *pclk / 2;
+
+	/*
+	 * If pixel_overlap needed by panel, we need to	increase the pixel
+	 * clock for extra pixels.
+	 */
+	if (intel_dsi->dual_link & DSI_DUAL_LINK_FRONT_BACK)
+		*pclk += DIV_ROUND_UP(mode->vtotal * intel_dsi->pixel_overlap *
+							mode->vrefresh, 1000);
+}
+
+void adjust_pclk_for_burst_mode(u32 *pclk, u16 burst_mode_ratio)
+{
+	*pclk = DIV_ROUND_UP(*pclk * burst_mode_ratio, 100);
+}
+
+
+/* To recalculate the pclk considering dual link and Burst mode */
+static u32 intel_drrs_calc_pclk(struct intel_dsi *intel_dsi,
+					struct drm_display_mode *mode)
+{
+	u32 pclk;
+	int pkt_pixel_size;		/* in bits */
 
-	/* DSI data rate = pixel clock * bits per pixel / lane count
-	   pixel clock is converted from KHz to Hz */
-	dsi_clk_khz = DIV_ROUND_CLOSEST(pclk * bpp, lane_count);
+	pclk = mode->clock;
+
+	pkt_pixel_size = intel_get_bits_per_pixel(intel_dsi);
+
+	/* In dual link mode each port needs half of pixel clock */
+	if (intel_dsi->dual_link)
+		adjust_pclk_for_dual_link(intel_dsi, mode, &pclk);
+
+	/* Retaining the same Burst mode ratio for DRRS. Need to be tested */
+	if (intel_dsi->burst_mode_ratio > 100)
+		adjust_pclk_for_burst_mode(&pclk, intel_dsi->burst_mode_ratio);
+
+	DRM_DEBUG_KMS("mode->clock : %d, pclk : %d\n", mode->clock, pclk);
+	return pclk;
+}
+
+/* Get DSI clock from pixel clock */
+static u32 dsi_clk_from_pclk(struct intel_dsi *intel_dsi,
+					struct drm_display_mode *mode)
+{
+	u32 dsi_clk_khz;
+	u32 bpp;
+	u32 pclk;
+
+	bpp = intel_get_bits_per_pixel(intel_dsi);
+
+	pclk = intel_drrs_calc_pclk(intel_dsi, mode);
+
+	/*
+	 * DSI data rate = pixel clock * bits per pixel / lane count
+	 * pixel clock is converted from KHz to Hz
+	 */
+	dsi_clk_khz = DIV_ROUND_CLOSEST(pclk * bpp, intel_dsi->lane_count);
 
 	return dsi_clk_khz;
 }
@@ -205,12 +263,13 @@  static void vlv_configure_dsi_pll(struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+	struct intel_connector *intel_connector = intel_dsi->attached_connector;
 	int ret;
 	struct dsi_mnp dsi_mnp;
 	u32 dsi_clk;
 
-	dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
-				    intel_dsi->lane_count);
+	dsi_clk = dsi_clk_from_pclk(intel_dsi,
+				    intel_connector->panel.fixed_mode);
 
 	ret = dsi_calc_mnp(dsi_clk, &dsi_mnp);
 	if (ret) {