int msm_dsi_host_enable(struct mipi_dsi_host *host);
 int msm_dsi_host_disable(struct mipi_dsi_host *host);
 int msm_dsi_host_power_on(struct mipi_dsi_host *host,
-                       struct msm_dsi_phy_shared_timings *phy_shared_timings);
+                       struct msm_dsi_phy_shared_timings *phy_shared_timings,
+                       bool is_dual_dsi);
 int msm_dsi_host_power_off(struct mipi_dsi_host *host);
 int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
                                        struct drm_display_mode *mode);
                        struct msm_dsi_pll *src_pll);
 void msm_dsi_host_reset_phy(struct mipi_dsi_host *host);
 void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host,
-       struct msm_dsi_phy_clk_request *clk_req);
+       struct msm_dsi_phy_clk_request *clk_req,
+       bool is_dual_dsi);
 void msm_dsi_host_destroy(struct mipi_dsi_host *host);
 int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
                                        struct drm_device *dev);
 int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova);
 int dsi_clk_init_v2(struct msm_dsi_host *msm_host);
 int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host);
-int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host);
-int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host);
+int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_dual_dsi);
+int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_dual_dsi);
 
 /* dsi phy */
 struct msm_dsi_phy;
 
        struct clk *byte_intf_clk;
 
        u32 byte_clk_rate;
+       u32 pixel_clk_rate;
        u32 esc_clk_rate;
 
        /* DSI v2 specific clocks */
                goto error;
        }
 
-       ret = clk_set_rate(msm_host->pixel_clk, msm_host->mode->clock * 1000);
+       ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate);
        if (ret) {
                pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret);
                goto error;
                goto error;
        }
 
-       ret = clk_set_rate(msm_host->pixel_clk, msm_host->mode->clock * 1000);
+       ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate);
        if (ret) {
                pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret);
                goto error;
        clk_disable_unprepare(msm_host->byte_clk);
 }
 
-int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host)
+int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_dual_dsi)
 {
        struct drm_display_mode *mode = msm_host->mode;
        u8 lanes = msm_host->lanes;
        u32 pclk_rate;
 
        pclk_rate = mode->clock * 1000;
+
+       /*
+        * For dual DSI mode, the current DRM mode has the complete width of the
+        * panel. Since, the complete panel is driven by two DSI controllers,
+        * theclock rates have to be split between the two dsi controllers.
+        * Adjust the byte and pixel clock rates for each dsi host accordingly.
+        */
+       if (is_dual_dsi)
+               pclk_rate /= 2;
+
        if (lanes > 0) {
                msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes);
        } else {
        return 0;
 }
 
-int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host)
+int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_dual_dsi)
 {
        struct drm_display_mode *mode = msm_host->mode;
        u8 lanes = msm_host->lanes;
        unsigned long byte_mhz;
 
        pclk_rate = mode->clock * 1000;
+
+       /*
+        * For dual DSI mode, the current DRM mode has the complete width of the
+        * panel. Since, the complete panel is driven by two DSI controllers,
+        * theclock rates have to be split between the two dsi controllers.
+        * Adjust the byte and pixel clock rates for each dsi host accordingly.
+        */
+       if (is_dual_dsi)
+               pclk_rate /= 2;
+
        if (lanes > 0) {
                msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes);
        } else {
                pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
                msm_host->byte_clk_rate = (pclk_rate * bpp) / 8;
        }
+       msm_host->pixel_clk_rate = pclk_rate;
 
-       DBG("pclk=%d, bclk=%d", pclk_rate, msm_host->byte_clk_rate);
+       DBG("pclk=%d, bclk=%d", msm_host->pixel_clk_rate,
+                               msm_host->byte_clk_rate);
 
        msm_host->src_clk_rate = (pclk_rate * bpp) / 8;
 
        dsi_write(msm_host, REG_DSI_CTRL, data);
 }
 
-static void dsi_timing_setup(struct msm_dsi_host *msm_host)
+static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_dual_dsi)
 {
        struct drm_display_mode *mode = msm_host->mode;
        u32 hs_start = 0, vs_start = 0; /* take sync start as 0 */
        u32 ha_end = ha_start + mode->hdisplay;
        u32 va_start = v_total - mode->vsync_start;
        u32 va_end = va_start + mode->vdisplay;
+       u32 hdisplay = mode->hdisplay;
        u32 wc;
 
        DBG("");
 
+       /*
+        * For dual DSI mode, the current DRM mode has
+        * the complete width of the panel. Since, the complete
+        * panel is driven by two DSI controllers, the horizontal
+        * timings have to be split between the two dsi controllers.
+        * Adjust the DSI host timing values accordingly.
+        */
+       if (is_dual_dsi) {
+               h_total /= 2;
+               hs_end /= 2;
+               ha_start /= 2;
+               ha_end /= 2;
+               hdisplay /= 2;
+       }
+
        if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
                dsi_write(msm_host, REG_DSI_ACTIVE_H,
                        DSI_ACTIVE_H_START(ha_start) |
                        DSI_ACTIVE_VSYNC_VPOS_END(vs_end));
        } else {                /* command mode */
                /* image data and 1 byte write_memory_start cmd */
-               wc = mode->hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
+               wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
 
                dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM_CTRL,
                        DSI_CMD_MDP_STREAM_CTRL_WORD_COUNT(wc) |
                                        MIPI_DSI_DCS_LONG_WRITE));
 
                dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM_TOTAL,
-                       DSI_CMD_MDP_STREAM_TOTAL_H_TOTAL(mode->hdisplay) |
+                       DSI_CMD_MDP_STREAM_TOTAL_H_TOTAL(hdisplay) |
                        DSI_CMD_MDP_STREAM_TOTAL_V_TOTAL(mode->vdisplay));
        }
 }
 }
 
 void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host,
-       struct msm_dsi_phy_clk_request *clk_req)
+                       struct msm_dsi_phy_clk_request *clk_req,
+                       bool is_dual_dsi)
 {
        struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
        const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
        int ret;
 
-       ret = cfg_hnd->ops->calc_clk_rate(msm_host);
+       ret = cfg_hnd->ops->calc_clk_rate(msm_host, is_dual_dsi);
        if (ret) {
                pr_err("%s: unable to calc clk rate, %d\n", __func__, ret);
                return;
 }
 
 int msm_dsi_host_power_on(struct mipi_dsi_host *host,
-                       struct msm_dsi_phy_shared_timings *phy_shared_timings)
+                       struct msm_dsi_phy_shared_timings *phy_shared_timings,
+                       bool is_dual_dsi)
 {
        struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
        const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
                goto fail_disable_clk;
        }
 
-       dsi_timing_setup(msm_host);
+       dsi_timing_setup(msm_host, is_dual_dsi);
        dsi_sw_reset(msm_host);
        dsi_ctrl_config(msm_host, true, phy_shared_timings);
 
 
 {
        struct msm_dsi_phy_clk_request clk_req;
        int ret;
+       bool is_dual_dsi = IS_DUAL_DSI();
 
-       msm_dsi_host_get_phy_clk_req(msm_dsi->host, &clk_req);
+       msm_dsi_host_get_phy_clk_req(msm_dsi->host, &clk_req, is_dual_dsi);
 
        ret = msm_dsi_phy_enable(msm_dsi->phy, src_pll_id, &clk_req);
        msm_dsi_phy_get_shared_timings(msm_dsi->phy, shared_timings);
        if (is_dual_dsi && (DSI_1 == id))
                return;
 
-       ret = msm_dsi_host_power_on(host, &phy_shared_timings[id]);
+       ret = msm_dsi_host_power_on(host, &phy_shared_timings[id], is_dual_dsi);
        if (ret) {
                pr_err("%s: power on host %d failed, %d\n", __func__, id, ret);
                goto host_on_fail;
 
        if (is_dual_dsi && msm_dsi1) {
                ret = msm_dsi_host_power_on(msm_dsi1->host,
-                                           &phy_shared_timings[DSI_1]);
+                               &phy_shared_timings[DSI_1], is_dual_dsi);
                if (ret) {
                        pr_err("%s: power on host1 failed, %d\n",
                                                        __func__, ret);