#define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c)   /* ports A and C only */
 
+/* BXT MIPI mode configure */
+#define  _BXT_MIPIA_TRANS_HACTIVE                      0x6B0F8
+#define  _BXT_MIPIC_TRANS_HACTIVE                      0x6B8F8
+#define  BXT_MIPI_TRANS_HACTIVE(tc)    _MIPI_PORT(tc, \
+               _BXT_MIPIA_TRANS_HACTIVE, _BXT_MIPIC_TRANS_HACTIVE)
+
+#define  _BXT_MIPIA_TRANS_VACTIVE                      0x6B0FC
+#define  _BXT_MIPIC_TRANS_VACTIVE                      0x6B8FC
+#define  BXT_MIPI_TRANS_VACTIVE(tc)    _MIPI_PORT(tc, \
+               _BXT_MIPIA_TRANS_VACTIVE, _BXT_MIPIC_TRANS_VACTIVE)
+
+#define  _BXT_MIPIA_TRANS_VTOTAL                       0x6B100
+#define  _BXT_MIPIC_TRANS_VTOTAL                       0x6B900
+#define  BXT_MIPI_TRANS_VTOTAL(tc)     _MIPI_PORT(tc, \
+               _BXT_MIPIA_TRANS_VTOTAL, _BXT_MIPIC_TRANS_VTOTAL)
+
 #define BXT_DSI_PLL_CTL                        0x161000
 #define  BXT_DSI_PLL_PVD_RATIO_SHIFT   16
 #define  BXT_DSI_PLL_PVD_RATIO_MASK    (3 << BXT_DSI_PLL_PVD_RATIO_SHIFT)
 #define  READ_REQUEST_PRIORITY_HIGH                    (3 << 3)
 #define  RGB_FLIP_TO_BGR                               (1 << 2)
 
+#define  BXT_PIPE_SELECT_MASK                          (7 << 7)
+#define  BXT_PIPE_SELECT_C                             (2 << 7)
+#define  BXT_PIPE_SELECT_B                             (1 << 7)
+#define  BXT_PIPE_SELECT_A                             (0 << 7)
+
 #define _MIPIA_DATA_ADDRESS            (dev_priv->mipi_mmio_base + 0xb108)
 #define _MIPIC_DATA_ADDRESS            (dev_priv->mipi_mmio_base + 0xb908)
 #define MIPI_DATA_ADDRESS(port)                _MIPI_PORT(port, _MIPIA_DATA_ADDRESS, \
 
        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);
 
        }
 
        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);
-
-               /* 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);
+               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);
+               } 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);
                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);