drm/i915/bxt: DSI prepare changes for BXT

This patch modifies dsi_prepare() function to support the same
modeset prepare sequence for BXT also. Main changes are:
1. BXT port control register is different than VLV.
2. BXT modeset sequence needs vdisplay and hdisplay programmed
   for transcoder.
3. BXT can select PIPE for MIPI transcoders.
4. BXT needs to program register MIPI_INIT_COUNT for both the ports,
   even if only one is being used.

v2: Fixed Jani's review comments. Rectified the DSI Macros to get
    proper register offsets using _MIPI_PORT instead of _TRANSCODER

v3: Rebased on latest drm-nightly branch. Fixed Jani's review comments.

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Uma Shankar <uma.shankar@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 50159a9..5b69b41 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -737,6 +737,21 @@
 	hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio);
 
 	for_each_dsi_port(port, intel_dsi->ports) {
+		if (IS_BROXTON(dev)) {
+			/*
+			 * Program hdisplay and vdisplay on MIPI transcoder.
+			 * This is different from calculated hactive and
+			 * vactive, as they are calculated per channel basis,
+			 * whereas these values should be based on resolution.
+			 */
+			I915_WRITE(BXT_MIPI_TRANS_HACTIVE(port),
+					mode->hdisplay);
+			I915_WRITE(BXT_MIPI_TRANS_VACTIVE(port),
+					mode->vdisplay);
+			I915_WRITE(BXT_MIPI_TRANS_VTOTAL(port),
+					mode->vtotal);
+		}
+
 		I915_WRITE(MIPI_HACTIVE_AREA_COUNT(port), hactive);
 		I915_WRITE(MIPI_HFP_COUNT(port), hfp);
 
@@ -777,16 +792,39 @@
 	}
 
 	for_each_dsi_port(port, intel_dsi->ports) {
-		/* escape clock divider, 20MHz, shared for A and C.
-		 * device ready must be off when doing this! txclkesc? */
-		tmp = I915_READ(MIPI_CTRL(PORT_A));
-		tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
-		I915_WRITE(MIPI_CTRL(PORT_A), tmp | ESCAPE_CLOCK_DIVIDER_1);
+		if (IS_VALLEYVIEW(dev)) {
+			/*
+			 * escape clock divider, 20MHz, shared for A and C.
+			 * device ready must be off when doing this! txclkesc?
+			 */
+			tmp = I915_READ(MIPI_CTRL(PORT_A));
+			tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
+			I915_WRITE(MIPI_CTRL(PORT_A), tmp |
+					ESCAPE_CLOCK_DIVIDER_1);
 
-		/* read request priority is per pipe */
-		tmp = I915_READ(MIPI_CTRL(port));
-		tmp &= ~READ_REQUEST_PRIORITY_MASK;
-		I915_WRITE(MIPI_CTRL(port), tmp | READ_REQUEST_PRIORITY_HIGH);
+			/* read request priority is per pipe */
+			tmp = I915_READ(MIPI_CTRL(port));
+			tmp &= ~READ_REQUEST_PRIORITY_MASK;
+			I915_WRITE(MIPI_CTRL(port), tmp |
+					READ_REQUEST_PRIORITY_HIGH);
+		} else if (IS_BROXTON(dev)) {
+			/*
+			 * FIXME:
+			 * BXT can connect any PIPE to any MIPI port.
+			 * Select the pipe based on the MIPI port read from
+			 * VBT for now. Pick PIPE A for MIPI port A and C
+			 * for port C.
+			 */
+			tmp = I915_READ(MIPI_CTRL(port));
+			tmp &= ~BXT_PIPE_SELECT_MASK;
+
+			if (port == PORT_A)
+				tmp |= BXT_PIPE_SELECT_A;
+			else if (port == PORT_C)
+				tmp |= BXT_PIPE_SELECT_C;
+
+			I915_WRITE(MIPI_CTRL(port), tmp);
+		}
 
 		/* XXX: why here, why like this? handling in irq handler?! */
 		I915_WRITE(MIPI_INTR_STAT(port), 0xffffffff);
@@ -863,6 +901,17 @@
 		I915_WRITE(MIPI_INIT_COUNT(port),
 				txclkesc(intel_dsi->escape_clk_div, 100));
 
+		if (IS_BROXTON(dev) && (!intel_dsi->dual_link)) {
+			/*
+			 * BXT spec says write MIPI_INIT_COUNT for
+			 * both the ports, even if only one is
+			 * getting used. So write the other port
+			 * if not in dual link mode.
+			 */
+			I915_WRITE(MIPI_INIT_COUNT(port ==
+						PORT_A ? PORT_C : PORT_A),
+					intel_dsi->init_count);
+		}
 
 		/* recovery disables */
 		I915_WRITE(MIPI_EOT_DISABLE(port), tmp);