#define DSI_1  1
 #define DSI_MAX        2
 
-#define DSI_CLOCK_MASTER       DSI_0
-#define DSI_CLOCK_SLAVE                DSI_1
-
-#define DSI_LEFT               DSI_0
-#define DSI_RIGHT              DSI_1
-
-/* According to the current drm framework sequence, take the encoder of
- * DSI_1 as master encoder
- */
-#define DSI_ENCODER_MASTER     DSI_1
-#define DSI_ENCODER_SLAVE      DSI_0
-
 enum msm_dsi_phy_type {
        MSM_DSI_PHY_28NM_HPM,
        MSM_DSI_PHY_28NM_LP,
 struct msm_dsi_phy;
 void msm_dsi_phy_driver_register(void);
 void msm_dsi_phy_driver_unregister(void);
-int msm_dsi_phy_enable(struct msm_dsi_phy *phy, bool is_dual_panel,
+int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
        const unsigned long bit_rate, const unsigned long esc_rate);
 int msm_dsi_phy_disable(struct msm_dsi_phy *phy);
 void msm_dsi_phy_get_clk_pre_post(struct msm_dsi_phy *phy,
 
 #include "msm_kms.h"
 #include "dsi.h"
 
+#define DSI_CLOCK_MASTER       DSI_0
+#define DSI_CLOCK_SLAVE                DSI_1
+
+#define DSI_LEFT               DSI_0
+#define DSI_RIGHT              DSI_1
+
+/* According to the current drm framework sequence, take the encoder of
+ * DSI_1 as master encoder
+ */
+#define DSI_ENCODER_MASTER     DSI_1
+#define DSI_ENCODER_SLAVE      DSI_0
+
 struct msm_dsi_manager {
        struct msm_dsi *dsi[DSI_MAX];
 
 {
        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
        struct msm_dsi_phy *phy = msm_dsi->phy;
+       int src_pll_id = IS_DUAL_PANEL() ? DSI_CLOCK_MASTER : id;
        int ret;
 
-       ret = msm_dsi_phy_enable(phy, IS_DUAL_PANEL(), bit_rate, esc_rate);
+       ret = msm_dsi_phy_enable(phy, src_pll_id, bit_rate, esc_rate);
        if (ret)
                return ret;
 
 
 #define dsi_phy_write(offset, data) msm_writel((data), (offset))
 
 struct dsi_phy_ops {
-       int (*enable)(struct msm_dsi_phy *phy, bool is_dual_panel,
+       int (*enable)(struct msm_dsi_phy *phy, int src_pll_id,
                const unsigned long bit_rate, const unsigned long esc_rate);
        int (*disable)(struct msm_dsi_phy *phy);
 };
        enum msm_dsi_phy_type type;
        struct dsi_reg_config reg_cfg;
        struct dsi_phy_ops ops;
+
+       /* Each cell {phy_id, pll_id} of the truth table indicates
+        * if the source PLL is on the right side of the PHY.
+        * Fill default H/W values in illegal cells, eg. cell {0, 1}.
+        */
+       bool src_pll_truthtable[DSI_MAX][DSI_MAX];
 };
 
 struct dsi_dphy_timing {
        return ret;
 }
 
+static void dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg)
+{
+       int phy_id = phy->id;
+
+       if ((phy_id >= DSI_MAX) || (pll_id >= DSI_MAX))
+               return;
+
+       if (phy->cfg->src_pll_truthtable[phy_id][pll_id])
+               dsi_phy_write(phy->base + reg, 0x01);
+       else
+               dsi_phy_write(phy->base + reg, 0x00);
+}
+
 #define S_DIV_ROUND_UP(n, d)   \
        (((n) >= 0) ? (((n) + (d) - 1) / (d)) : (((n) - (d) + 1) / (d)))
 
        dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
 }
 
-static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, bool is_dual_panel,
+static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
                const unsigned long bit_rate, const unsigned long esc_rate)
 {
        struct dsi_dphy_timing *timing = &phy->timing;
 
        dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f);
 
-       if (is_dual_panel && (phy->id != DSI_CLOCK_MASTER))
-               dsi_phy_write(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL, 0x00);
-       else
-               dsi_phy_write(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL, 0x01);
+       dsi_phy_set_src_pll(phy, src_pll_id, REG_DSI_28nm_PHY_GLBL_TEST_CTRL);
 
        return 0;
 }
 static const struct dsi_phy_cfg dsi_phy_cfgs[MSM_DSI_PHY_MAX] = {
        [MSM_DSI_PHY_28NM_HPM] = {
                .type = MSM_DSI_PHY_28NM_HPM,
+               .src_pll_truthtable = { {true, true}, {false, true} },
                .reg_cfg = {
                        .num = 1,
                        .regs = {
        },
        [MSM_DSI_PHY_28NM_LP] = {
                .type = MSM_DSI_PHY_28NM_LP,
+               .src_pll_truthtable = { {true, true}, {true, true} },
                .reg_cfg = {
                        .num = 1,
                        .regs = {
        platform_driver_unregister(&dsi_phy_platform_driver);
 }
 
-int msm_dsi_phy_enable(struct msm_dsi_phy *phy, bool is_dual_panel,
+int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
        const unsigned long bit_rate, const unsigned long esc_rate)
 {
        int ret;
                return ret;
        }
 
-       return phy->cfg->ops.enable(phy, is_dual_panel, bit_rate, esc_rate);
+       return phy->cfg->ops.enable(phy, src_pll_id, bit_rate, esc_rate);
 }
 
 int msm_dsi_phy_disable(struct msm_dsi_phy *phy)