[DISPC_MGR_FLD_FIFOHANDCHECK]   = { DISPC_CONFIG2,  16, 16 },
                },
        },
+       [OMAP_DSS_CHANNEL_LCD3] = {
+               .name           = "LCD3",
+               .vsync_irq      = DISPC_IRQ_VSYNC3,
+               .framedone_irq  = DISPC_IRQ_FRAMEDONE3,
+               .sync_lost_irq  = DISPC_IRQ_SYNC_LOST3,
+               .reg_desc       = {
+                       [DISPC_MGR_FLD_ENABLE]          = { DISPC_CONTROL3,  0,  0 },
+                       [DISPC_MGR_FLD_STNTFT]          = { DISPC_CONTROL3,  3,  3 },
+                       [DISPC_MGR_FLD_GO]              = { DISPC_CONTROL3,  5,  5 },
+                       [DISPC_MGR_FLD_TFTDATALINES]    = { DISPC_CONTROL3,  9,  8 },
+                       [DISPC_MGR_FLD_STALLMODE]       = { DISPC_CONTROL3, 11, 11 },
+                       [DISPC_MGR_FLD_TCKENABLE]       = { DISPC_CONFIG3,  10, 10 },
+                       [DISPC_MGR_FLD_TCKSELECTION]    = { DISPC_CONFIG3,  11, 11 },
+                       [DISPC_MGR_FLD_CPR]             = { DISPC_CONFIG3,  15, 15 },
+                       [DISPC_MGR_FLD_FIFOHANDCHECK]   = { DISPC_CONFIG3,  16, 16 },
+               },
+       },
 };
 
 static void _omap_dispc_set_irqs(void);
                SR(CONTROL2);
                SR(CONFIG2);
        }
+       if (dss_has_feature(FEAT_MGR_LCD3)) {
+               SR(CONTROL3);
+               SR(CONFIG3);
+       }
 
        for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
                SR(DEFAULT_COLOR(i));
                RR(GLOBAL_ALPHA);
        if (dss_has_feature(FEAT_MGR_LCD2))
                RR(CONFIG2);
+       if (dss_has_feature(FEAT_MGR_LCD3))
+               RR(CONFIG3);
 
        for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
                RR(DEFAULT_COLOR(i));
        RR(CONTROL);
        if (dss_has_feature(FEAT_MGR_LCD2))
                RR(CONTROL2);
+       if (dss_has_feature(FEAT_MGR_LCD3))
+               RR(CONTROL3);
        /* clear spurious SYNC_LOST_DIGIT interrupts */
        dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
 
 static inline bool dispc_mgr_is_lcd(enum omap_channel channel)
 {
        if (channel == OMAP_DSS_CHANNEL_LCD ||
-                       channel == OMAP_DSS_CHANNEL_LCD2)
+                       channel == OMAP_DSS_CHANNEL_LCD2 ||
+                       channel == OMAP_DSS_CHANNEL_LCD3)
                return true;
        else
                return false;
                        chan = 0;
                        chan2 = 1;
                        break;
+               case OMAP_DSS_CHANNEL_LCD3:
+                       if (dss_has_feature(FEAT_MGR_LCD3)) {
+                               chan = 0;
+                               chan2 = 2;
+                       } else {
+                               BUG();
+                               return;
+                       }
+                       break;
                default:
                        BUG();
                        return;
 
        val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
 
-       if (dss_has_feature(FEAT_MGR_LCD2)) {
+       if (dss_has_feature(FEAT_MGR_LCD3)) {
+               if (FLD_GET(val, 31, 30) == 0)
+                       channel = FLD_GET(val, shift, shift);
+               else if (FLD_GET(val, 31, 30) == 1)
+                       channel = OMAP_DSS_CHANNEL_LCD2;
+               else
+                       channel = OMAP_DSS_CHANNEL_LCD3;
+       } else if (dss_has_feature(FEAT_MGR_LCD2)) {
                if (FLD_GET(val, 31, 30) == 0)
                        channel = FLD_GET(val, shift, shift);
                else
        dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
        if (dss_has_feature(FEAT_MGR_LCD2))
                dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
+       if (dss_has_feature(FEAT_MGR_LCD3))
+               dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST3;
        if (dss_feat_get_num_ovls() > 3)
                dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
 
 
                dsi_wait_pll_hsdiv_dispc_active(dsidev);
                break;
        case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
-               BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2);
+               BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
+                      channel != OMAP_DSS_CHANNEL_LCD3);
                b = 1;
                dsidev = dsi_get_dsidev_from_id(1);
                dsi_wait_pll_hsdiv_dispc_active(dsidev);
                return;
        }
 
-       pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12;
+       pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
+            (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19);
        REG_FLD_MOD(DSS_CONTROL, b, pos, pos);  /* LCDx_CLK_SWITCH */
 
-       ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
+       ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
+           (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
        dss.lcd_clk_source[ix] = clk_src;
 }
 
 enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
 {
        if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
-               int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
+               int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
+                       (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
                return dss.lcd_clk_source[ix];
        } else {
                /* LCD_CLK source is the same as DISPC_FCLK source for
 
        struct omap_overlay_manager *lcd_mgr;
        struct omap_overlay_manager *tv_mgr;
        struct omap_overlay_manager *lcd2_mgr = NULL;
+       struct omap_overlay_manager *lcd3_mgr = NULL;
        struct omap_overlay_manager *mgr = NULL;
 
        lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
        tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
+       if (dss_has_feature(FEAT_MGR_LCD3))
+               lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
        if (dss_has_feature(FEAT_MGR_LCD2))
                lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
 
-       if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
+       if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) {
+               if (!lcd3_mgr->device || force) {
+                       if (lcd3_mgr->device)
+                               lcd3_mgr->unset_device(lcd3_mgr);
+                       lcd3_mgr->set_device(lcd3_mgr, dssdev);
+                       mgr = lcd3_mgr;
+               }
+       } else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
                if (!lcd2_mgr->device || force) {
                        if (lcd2_mgr->device)
                                lcd2_mgr->unset_device(lcd2_mgr);