{
        int r = 0;
        u32 l;
-       int f;
+       int f = 0;
        u8 regn_start, regn_end, regm_start, regm_end;
        u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
 
        dsi_write_reg(DSI_PLL_CONFIGURATION1, l);
 
        BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max);
-       if (cinfo->fint < 1000000)
-               f = 0x3;
-       else if (cinfo->fint < 1250000)
-               f = 0x4;
-       else if (cinfo->fint < 1500000)
-               f = 0x5;
-       else if (cinfo->fint < 1750000)
-               f = 0x6;
-       else
-               f = 0x7;
+
+       if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) {
+               f = cinfo->fint < 1000000 ? 0x3 :
+                       cinfo->fint < 1250000 ? 0x4 :
+                       cinfo->fint < 1500000 ? 0x5 :
+                       cinfo->fint < 1750000 ? 0x6 :
+                       0x7;
+       }
 
        l = dsi_read_reg(DSI_PLL_CONFIGURATION2);
-       l = FLD_MOD(l, f, 4, 1);                /* DSI_PLL_FREQSEL */
+
+       if (dss_has_feature(FEAT_DSI_PLL_FREQSEL))
+               l = FLD_MOD(l, f, 4, 1);        /* DSI_PLL_FREQSEL */
        l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1,
                        11, 11);                /* DSI_PLL_CLKSEL */
        l = FLD_MOD(l, cinfo->highfreq,
 
        DSSDBG("dsi_complexio_init\n");
 
-       /* CIO_CLK_ICG, enable L3 clk to CIO */
-       REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14);
-
        /* A dummy read using the SCP interface to any DSIPHY register is
         * required after DSIPHY reset to complete the reset of the DSI complex
         * I/O. */
                goto err;
        }
 
-       if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 21, 1) != 1) {
-               DSSERR("ComplexIO LDO power down.\n");
-               r = -ENODEV;
-               goto err;
+       if (dss_has_feature(FEAT_DSI_LDO_STATUS)) {
+               if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 21, 1) != 1) {
+                       DSSERR("ComplexIO LDO power down.\n");
+                       r = -ENODEV;
+                       goto err;
+               }
        }
 
        dsi_complexio_timings();
        r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */
        r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */
        r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */
+       if (dss_has_feature(FEAT_DSI_VC_OCP_WIDTH))
+               r = FLD_MOD(r, 3, 11, 10);      /* OCP_WIDTH = 32 bit */
 
        r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
        r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
 
        REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */
 
+       /* DCS_CMD_ENABLE */
+       if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC))
+               REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 30, 30);
+
        dsi_vc_enable(channel, 1);
 
        dsi.vc[channel].mode = DSI_VC_MODE_L4;
 
        REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 1, 1); /* SOURCE, 1 = video port */
 
+       /* DCS_CMD_ENABLE */
+       if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC))
+               REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 30, 30);
+
        dsi_vc_enable(channel, 1);
 
        dsi.vc[channel].mode = DSI_VC_MODE_VP;
        r = FLD_MOD(r, 2, 13, 12);      /* LINE_BUFFER, 2 lines */
        r = FLD_MOD(r, 1, 14, 14);      /* TRIGGER_RESET_MODE */
        r = FLD_MOD(r, 1, 19, 19);      /* EOT_ENABLE */
-       r = FLD_MOD(r, 1, 24, 24);      /* DCS_CMD_ENABLE */
-       r = FLD_MOD(r, 0, 25, 25);      /* DCS_CMD_CODE, 1=start, 0=continue */
+       if (!dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) {
+               r = FLD_MOD(r, 1, 24, 24);      /* DCS_CMD_ENABLE */
+               /* DCS_CMD_CODE, 1=start, 0=continue */
+               r = FLD_MOD(r, 0, 25, 25);
+       }
 
        dsi_write_reg(DSI_CTRL, r);
 
 {
        int r;
 
+       /* The SCPClk is required for both PLL and CIO registers on OMAP4 */
+       /* CIO_CLK_ICG, enable L3 clk to CIO */
+       REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14);
+
        _dsi_print_reset_status();
 
        r = dsi_pll_init(dssdev, true, true);
 
        dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
        dss_select_dsi_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI);
+       dss_select_lcd_clk_source(dssdev->manager->id,
+               DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC);
 
        DSSDBG("PLL OK\n");
 
 
 
 /* DSS has feature id */
 enum dss_feat_id {
-       FEAT_GLOBAL_ALPHA       = 1 << 0,
-       FEAT_GLOBAL_ALPHA_VID1  = 1 << 1,
-       FEAT_PRE_MULT_ALPHA     = 1 << 2,
-       FEAT_LCDENABLEPOL       = 1 << 3,
-       FEAT_LCDENABLESIGNAL    = 1 << 4,
-       FEAT_PCKFREEENABLE      = 1 << 5,
-       FEAT_FUNCGATED          = 1 << 6,
-       FEAT_MGR_LCD2           = 1 << 7,
-       FEAT_LINEBUFFERSPLIT    = 1 << 8,
-       FEAT_ROWREPEATENABLE    = 1 << 9,
-       FEAT_RESIZECONF         = 1 << 10,
+       FEAT_GLOBAL_ALPHA               = 1 << 0,
+       FEAT_GLOBAL_ALPHA_VID1          = 1 << 1,
+       FEAT_PRE_MULT_ALPHA             = 1 << 2,
+       FEAT_LCDENABLEPOL               = 1 << 3,
+       FEAT_LCDENABLESIGNAL            = 1 << 4,
+       FEAT_PCKFREEENABLE              = 1 << 5,
+       FEAT_FUNCGATED                  = 1 << 6,
+       FEAT_MGR_LCD2                   = 1 << 7,
+       FEAT_LINEBUFFERSPLIT            = 1 << 8,
+       FEAT_ROWREPEATENABLE            = 1 << 9,
+       FEAT_RESIZECONF                 = 1 << 10,
        /* Independent core clk divider */
-       FEAT_CORE_CLK_DIV       = 1 << 11,
-       FEAT_LCD_CLK_SRC        = 1 << 12,
+       FEAT_CORE_CLK_DIV               = 1 << 11,
+       FEAT_LCD_CLK_SRC                = 1 << 12,
        /* DSI-PLL power command 0x3 is not working */
-       FEAT_DSI_PLL_PWR_BUG    = 1 << 13,
+       FEAT_DSI_PLL_PWR_BUG            = 1 << 13,
+       FEAT_DSI_PLL_FREQSEL            = 1 << 14,
+       FEAT_DSI_LDO_STATUS             = 1 << 15,
+       FEAT_DSI_DCS_CMD_CONFIG_VC      = 1 << 16,
+       FEAT_DSI_VC_OCP_WIDTH           = 1 << 17,
 };
 
 /* DSS register field id */