Merge branch 'for-florian' of git://gitorious.org/linux-omap-dss2/linux into fbdev...
Florian Tobias Schandinat [Sat, 15 Oct 2011 00:19:52 +0000 (00:19 +0000)]
68 files changed:
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-am3517evm.c
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/board-cm-t35.c
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/board-igep0020.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-omap3stalker.c
arch/arm/mach-omap2/board-omap3touchbook.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/board-overo.c
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/twl-common.c
drivers/media/video/omap/omap_vout.c
drivers/video/omap/Kconfig
drivers/video/omap/Makefile
drivers/video/omap/lcd_2430sdp.c [deleted file]
drivers/video/omap/lcd_apollon.c [deleted file]
drivers/video/omap/lcd_h4.c [deleted file]
drivers/video/omap/lcd_ldp.c [deleted file]
drivers/video/omap/lcd_omap3beagle.c [deleted file]
drivers/video/omap/lcd_omap3evm.c [deleted file]
drivers/video/omap/lcd_overo.c [deleted file]
drivers/video/omap2/displays/Kconfig
drivers/video/omap2/displays/Makefile
drivers/video/omap2/displays/panel-dvi.c [new file with mode: 0644]
drivers/video/omap2/displays/panel-generic-dpi.c
drivers/video/omap2/displays/panel-n8x0.c [new file with mode: 0644]
drivers/video/omap2/displays/panel-picodlp.c [new file with mode: 0644]
drivers/video/omap2/displays/panel-picodlp.h [new file with mode: 0644]
drivers/video/omap2/displays/panel-taal.c
drivers/video/omap2/dss/Kconfig
drivers/video/omap2/dss/Makefile
drivers/video/omap2/dss/core.c
drivers/video/omap2/dss/dispc.c
drivers/video/omap2/dss/dispc.h
drivers/video/omap2/dss/display.c
drivers/video/omap2/dss/dpi.c
drivers/video/omap2/dss/dsi.c
drivers/video/omap2/dss/dss.c
drivers/video/omap2/dss/dss.h
drivers/video/omap2/dss/dss_features.c
drivers/video/omap2/dss/dss_features.h
drivers/video/omap2/dss/hdmi.c
drivers/video/omap2/dss/hdmi_panel.c [moved from drivers/video/omap2/dss/hdmi_omap4_panel.c with 79% similarity]
drivers/video/omap2/dss/manager.c
drivers/video/omap2/dss/overlay.c
drivers/video/omap2/dss/rfbi.c
drivers/video/omap2/dss/sdi.c
drivers/video/omap2/dss/ti_hdmi.h [new file with mode: 0644]
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c [new file with mode: 0644]
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h [moved from drivers/video/omap2/dss/hdmi.h with 54% similarity]
drivers/video/omap2/dss/venc.c
drivers/video/omap2/omapfb/Kconfig
drivers/video/omap2/omapfb/omapfb-main.c
drivers/video/omap2/omapfb/omapfb-sysfs.c
include/video/omap-panel-dvi.h [new file with mode: 0644]
include/video/omap-panel-n8x0.h [new file with mode: 0644]
include/video/omap-panel-nokia-dsi.h
include/video/omap-panel-picodlp.h [new file with mode: 0644]
include/video/omapdss.h

index 2028464..6ab6350 100644 (file)
@@ -39,6 +39,9 @@
 #include <plat/usb.h>
 #include <plat/gpmc-smc91x.h>
 
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
 #include "mux.h"
 #include "hsmmc.h"
 #include "common-board-devices.h"
@@ -99,20 +102,72 @@ static struct platform_device sdp2430_flash_device = {
        .resource       = &sdp2430_flash_resource,
 };
 
-static struct platform_device sdp2430_lcd_device = {
-       .name           = "sdp2430_lcd",
-       .id             = -1,
-};
-
 static struct platform_device *sdp2430_devices[] __initdata = {
        &sdp2430_flash_device,
+};
+
+/* LCD */
+#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO       91
+#define SDP2430_LCD_PANEL_ENABLE_GPIO          154
+
+static int sdp2430_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+       gpio_direction_output(SDP2430_LCD_PANEL_ENABLE_GPIO, 1);
+       gpio_direction_output(SDP2430_LCD_PANEL_BACKLIGHT_GPIO, 1);
+
+       return 0;
+}
+
+static void sdp2430_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+       gpio_direction_output(SDP2430_LCD_PANEL_ENABLE_GPIO, 0);
+       gpio_direction_output(SDP2430_LCD_PANEL_BACKLIGHT_GPIO, 0);
+}
+
+static struct panel_generic_dpi_data sdp2430_panel_data = {
+       .name                   = "nec_nl2432dr22-11b",
+       .platform_enable        = sdp2430_panel_enable_lcd,
+       .platform_disable       = sdp2430_panel_disable_lcd,
+};
+
+static struct omap_dss_device sdp2430_lcd_device = {
+       .name                   = "lcd",
+       .driver_name            = "generic_dpi_panel",
+       .type                   = OMAP_DISPLAY_TYPE_DPI,
+       .phy.dpi.data_lines     = 16,
+       .data                   = &sdp2430_panel_data,
+};
+
+static struct omap_dss_device *sdp2430_dss_devices[] = {
        &sdp2430_lcd_device,
 };
 
-static struct omap_lcd_config sdp2430_lcd_config __initdata = {
-       .ctrl_name      = "internal",
+static struct omap_dss_board_info sdp2430_dss_data = {
+       .num_devices    = ARRAY_SIZE(sdp2430_dss_devices),
+       .devices        = sdp2430_dss_devices,
+       .default_device = &sdp2430_lcd_device,
 };
 
+static void __init sdp2430_display_init(void)
+{
+       int r;
+
+       static struct gpio gpios[] __initdata = {
+               { SDP2430_LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
+                       "LCD reset" },
+               { SDP2430_LCD_PANEL_BACKLIGHT_GPIO, GPIOF_OUT_INIT_LOW,
+                       "LCD Backlight" },
+       };
+
+       r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+       if (r) {
+               pr_err("Cannot request LCD GPIOs, error %d\n", r);
+               return;
+       }
+
+       omap_display_init(&sdp2430_dss_data);
+}
+
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
 
 static struct omap_smc91x_platform_data board_smc91x_data = {
@@ -137,10 +192,6 @@ static inline void board_smc91x_init(void)
 
 #endif
 
-static struct omap_board_config_kernel sdp2430_config[] __initdata = {
-       {OMAP_TAG_LCD, &sdp2430_lcd_config},
-};
-
 static void __init omap_2430sdp_init_early(void)
 {
        omap2_init_common_infrastructure();
@@ -228,9 +279,6 @@ static void __init omap_2430sdp_init(void)
 {
        omap2430_mux_init(board_mux, OMAP_PACKAGE_ZAC);
 
-       omap_board_config = sdp2430_config;
-       omap_board_config_size = ARRAY_SIZE(sdp2430_config);
-
        omap2430_i2c_init();
 
        platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
@@ -246,6 +294,8 @@ static void __init omap_2430sdp_init(void)
        /* Turn off secondary LCD backlight */
        gpio_request_one(SECONDARY_LCD_GPIO, GPIOF_OUT_INIT_LOW,
                         "Secondary LCD backlight");
+
+       sdp2430_display_init();
 }
 
 static void __init omap_2430sdp_map_io(void)
index bd600cf..18c4d19 100644 (file)
@@ -37,7 +37,7 @@
 #include <plat/dma.h>
 #include <plat/gpmc.h>
 #include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include <plat/gpmc-smc91x.h>
 
@@ -186,8 +186,7 @@ static struct omap_dss_device sdp3430_lcd_device = {
        .platform_disable       = sdp3430_panel_disable_lcd,
 };
 
-static struct panel_generic_dpi_data dvi_panel = {
-       .name                   = "generic",
+static struct panel_dvi_platform_data dvi_panel = {
        .platform_enable        = sdp3430_panel_enable_dvi,
        .platform_disable       = sdp3430_panel_disable_dvi,
 };
@@ -195,7 +194,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device sdp3430_dvi_device = {
        .name                   = "dvi",
        .type                   = OMAP_DISPLAY_TYPE_DPI,
-       .driver_name            = "generic_dpi_panel",
+       .driver_name            = "dvi",
        .data                   = &dvi_panel,
        .phy.dpi.data_lines     = 24,
 };
index c7cef44..d3874a6 100644 (file)
@@ -38,6 +38,8 @@
 #include <plat/mmc.h>
 #include <plat/omap4-keypad.h>
 #include <video/omapdss.h>
+#include <video/omap-panel-nokia-dsi.h>
+#include <video/omap-panel-picodlp.h>
 #include <linux/wl12xx.h>
 
 #include "mux.h"
@@ -52,6 +54,8 @@
 #define OMAP4_SFH7741_ENABLE_GPIO              188
 #define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
 #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define DISPLAY_SEL_GPIO       59      /* LCD2/PicoDLP switch */
+#define DLP_POWER_ON_GPIO      40
 
 #define GPIO_WIFI_PMENA                54
 #define GPIO_WIFI_IRQ          53
@@ -340,11 +344,6 @@ static int __init omap_ethernet_init(void)
        return status;
 }
 
-static struct platform_device sdp4430_lcd_device = {
-       .name           = "sdp4430_lcd",
-       .id             = -1,
-};
-
 static struct regulator_consumer_supply sdp4430_vbat_supply[] = {
        REGULATOR_SUPPLY("vddvibl", "twl6040-vibra"),
        REGULATOR_SUPPLY("vddvibr", "twl6040-vibra"),
@@ -374,21 +373,12 @@ static struct platform_device sdp4430_vbat = {
 };
 
 static struct platform_device *sdp4430_devices[] __initdata = {
-       &sdp4430_lcd_device,
        &sdp4430_gpio_keys_device,
        &sdp4430_leds_gpio,
        &sdp4430_leds_pwm,
        &sdp4430_vbat,
 };
 
-static struct omap_lcd_config sdp4430_lcd_config __initdata = {
-       .ctrl_name      = "internal",
-};
-
-static struct omap_board_config_kernel sdp4430_config[] __initdata = {
-       { OMAP_TAG_LCD,         &sdp4430_lcd_config },
-};
-
 static void __init omap_4430sdp_init_early(void)
 {
        omap2_init_common_infrastructure();
@@ -648,37 +638,202 @@ static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
        gpio_free(HDMI_GPIO_HPD);
 }
 
-static struct omap_dss_device sdp4430_hdmi_device = {
-       .name = "hdmi",
-       .driver_name = "hdmi_panel",
-       .type = OMAP_DISPLAY_TYPE_HDMI,
-       .clocks = {
-               .dispc  = {
+static struct nokia_dsi_panel_data dsi1_panel = {
+               .name           = "taal",
+               .reset_gpio     = 102,
+               .use_ext_te     = false,
+               .ext_te_gpio    = 101,
+               .esd_interval   = 0,
+};
+
+static struct omap_dss_device sdp4430_lcd_device = {
+       .name                   = "lcd",
+       .driver_name            = "taal",
+       .type                   = OMAP_DISPLAY_TYPE_DSI,
+       .data                   = &dsi1_panel,
+       .phy.dsi                = {
+               .clk_lane       = 1,
+               .clk_pol        = 0,
+               .data1_lane     = 2,
+               .data1_pol      = 0,
+               .data2_lane     = 3,
+               .data2_pol      = 0,
+
+               .module         = 0,
+       },
+
+       .clocks = {
+               .dispc = {
+                       .channel = {
+                               /* Logic Clock = 172.8 MHz */
+                               .lck_div        = 1,
+                               /* Pixel Clock = 34.56 MHz */
+                               .pck_div        = 5,
+                               .lcd_clk_src    = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,
+                       },
                        .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
                },
-               .hdmi   = {
-                       .regn   = 15,
-                       .regm2  = 1,
+
+               .dsi = {
+                       .regn           = 16,   /* Fint = 2.4 MHz */
+                       .regm           = 180,  /* DDR Clock = 216 MHz */
+                       .regm_dispc     = 5,    /* PLL1_CLK1 = 172.8 MHz */
+                       .regm_dsi       = 5,    /* PLL1_CLK2 = 172.8 MHz */
+
+                       .lp_clk_div     = 10,   /* LP Clock = 8.64 MHz */
+                       .dsi_fclk_src   = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,
+               },
+       },
+       .channel                = OMAP_DSS_CHANNEL_LCD,
+};
+
+static struct nokia_dsi_panel_data dsi2_panel = {
+               .name           = "taal",
+               .reset_gpio     = 104,
+               .use_ext_te     = false,
+               .ext_te_gpio    = 103,
+               .esd_interval   = 0,
+};
+
+static struct omap_dss_device sdp4430_lcd2_device = {
+       .name                   = "lcd2",
+       .driver_name            = "taal",
+       .type                   = OMAP_DISPLAY_TYPE_DSI,
+       .data                   = &dsi2_panel,
+       .phy.dsi                = {
+               .clk_lane       = 1,
+               .clk_pol        = 0,
+               .data1_lane     = 2,
+               .data1_pol      = 0,
+               .data2_lane     = 3,
+               .data2_pol      = 0,
+
+               .module         = 1,
+       },
+
+       .clocks = {
+               .dispc = {
+                       .channel = {
+                               /* Logic Clock = 172.8 MHz */
+                               .lck_div        = 1,
+                               /* Pixel Clock = 34.56 MHz */
+                               .pck_div        = 5,
+                               .lcd_clk_src    = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,
+                       },
+                       .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
+               },
+
+               .dsi = {
+                       .regn           = 16,   /* Fint = 2.4 MHz */
+                       .regm           = 180,  /* DDR Clock = 216 MHz */
+                       .regm_dispc     = 5,    /* PLL1_CLK1 = 172.8 MHz */
+                       .regm_dsi       = 5,    /* PLL1_CLK2 = 172.8 MHz */
+
+                       .lp_clk_div     = 10,   /* LP Clock = 8.64 MHz */
+                       .dsi_fclk_src   = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,
                },
        },
+       .channel                = OMAP_DSS_CHANNEL_LCD2,
+};
+
+static void sdp4430_lcd_init(void)
+{
+       int r;
+
+       r = gpio_request_one(dsi1_panel.reset_gpio, GPIOF_DIR_OUT,
+               "lcd1_reset_gpio");
+       if (r)
+               pr_err("%s: Could not get lcd1_reset_gpio\n", __func__);
+
+       r = gpio_request_one(dsi2_panel.reset_gpio, GPIOF_DIR_OUT,
+               "lcd2_reset_gpio");
+       if (r)
+               pr_err("%s: Could not get lcd2_reset_gpio\n", __func__);
+}
+
+static struct omap_dss_device sdp4430_hdmi_device = {
+       .name = "hdmi",
+       .driver_name = "hdmi_panel",
+       .type = OMAP_DISPLAY_TYPE_HDMI,
        .platform_enable = sdp4430_panel_enable_hdmi,
        .platform_disable = sdp4430_panel_disable_hdmi,
        .channel = OMAP_DSS_CHANNEL_DIGIT,
 };
 
+static struct picodlp_panel_data sdp4430_picodlp_pdata = {
+       .picodlp_adapter_id     = 2,
+       .emu_done_gpio          = 44,
+       .pwrgood_gpio           = 45,
+};
+
+static void sdp4430_picodlp_init(void)
+{
+       int r;
+       const struct gpio picodlp_gpios[] = {
+               {DLP_POWER_ON_GPIO, GPIOF_OUT_INIT_LOW,
+                       "DLP POWER ON"},
+               {sdp4430_picodlp_pdata.emu_done_gpio, GPIOF_IN,
+                       "DLP EMU DONE"},
+               {sdp4430_picodlp_pdata.pwrgood_gpio, GPIOF_OUT_INIT_LOW,
+                       "DLP PWRGOOD"},
+       };
+
+       r = gpio_request_array(picodlp_gpios, ARRAY_SIZE(picodlp_gpios));
+       if (r)
+               pr_err("Cannot request PicoDLP GPIOs, error %d\n", r);
+}
+
+static int sdp4430_panel_enable_picodlp(struct omap_dss_device *dssdev)
+{
+       gpio_set_value(DISPLAY_SEL_GPIO, 0);
+       gpio_set_value(DLP_POWER_ON_GPIO, 1);
+
+       return 0;
+}
+
+static void sdp4430_panel_disable_picodlp(struct omap_dss_device *dssdev)
+{
+       gpio_set_value(DLP_POWER_ON_GPIO, 0);
+       gpio_set_value(DISPLAY_SEL_GPIO, 1);
+}
+
+static struct omap_dss_device sdp4430_picodlp_device = {
+       .name                   = "picodlp",
+       .driver_name            = "picodlp_panel",
+       .type                   = OMAP_DISPLAY_TYPE_DPI,
+       .phy.dpi.data_lines     = 24,
+       .channel                = OMAP_DSS_CHANNEL_LCD2,
+       .platform_enable        = sdp4430_panel_enable_picodlp,
+       .platform_disable       = sdp4430_panel_disable_picodlp,
+       .data                   = &sdp4430_picodlp_pdata,
+};
+
 static struct omap_dss_device *sdp4430_dss_devices[] = {
+       &sdp4430_lcd_device,
+       &sdp4430_lcd2_device,
        &sdp4430_hdmi_device,
+       &sdp4430_picodlp_device,
 };
 
 static struct omap_dss_board_info sdp4430_dss_data = {
        .num_devices    = ARRAY_SIZE(sdp4430_dss_devices),
        .devices        = sdp4430_dss_devices,
-       .default_device = &sdp4430_hdmi_device,
+       .default_device = &sdp4430_lcd_device,
 };
 
-void omap_4430sdp_display_init(void)
+static void omap_4430sdp_display_init(void)
 {
+       int r;
+
+       /* Enable LCD2 by default (instead of Pico DLP) */
+       r = gpio_request_one(DISPLAY_SEL_GPIO, GPIOF_OUT_INIT_HIGH,
+                       "display_sel");
+       if (r)
+               pr_err("%s: Could not get display_sel GPIO\n", __func__);
+
+       sdp4430_lcd_init();
        sdp4430_hdmi_mux_init();
+       sdp4430_picodlp_init();
        omap_display_init(&sdp4430_dss_data);
 }
 
@@ -802,9 +957,6 @@ static void __init omap_4430sdp_init(void)
                package = OMAP_PACKAGE_CBL;
        omap4_mux_init(board_mux, NULL, package);
 
-       omap_board_config = sdp4430_config;
-       omap_board_config_size = ARRAY_SIZE(sdp4430_config);
-
        omap4_i2c_init();
        omap_sfh7741prox_init();
        platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
index f3006c3..9a68ef5 100644 (file)
@@ -36,6 +36,7 @@
 #include <plat/usb.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include "mux.h"
 #include "control.h"
@@ -333,8 +334,7 @@ static void am3517_evm_panel_disable_dvi(struct omap_dss_device *dssdev)
        dvi_enabled = 0;
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-       .name                   = "generic",
+static struct panel_dvi_platform_data dvi_panel = {
        .platform_enable        = am3517_evm_panel_enable_dvi,
        .platform_disable       = am3517_evm_panel_disable_dvi,
 };
@@ -342,7 +342,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device am3517_evm_dvi_device = {
        .type                   = OMAP_DISPLAY_TYPE_DPI,
        .name                   = "dvi",
-       .driver_name            = "generic_dpi_panel",
+       .driver_name            = "dvi",
        .data                   = &dvi_panel,
        .phy.dpi.data_lines     = 24,
 };
index 7021170..d8eb81e 100644 (file)
@@ -40,6 +40,9 @@
 #include <plat/common.h>
 #include <plat/gpmc.h>
 
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
 #include "mux.h"
 #include "control.h"
 
@@ -149,11 +152,6 @@ static struct platform_device apollon_smc91x_device = {
        .resource       = apollon_smc91x_resources,
 };
 
-static struct platform_device apollon_lcd_device = {
-       .name           = "apollon_lcd",
-       .id             = -1,
-};
-
 static struct omap_led_config apollon_led_config[] = {
        {
                .cdev   = {
@@ -191,7 +189,6 @@ static struct platform_device apollon_led_device = {
 static struct platform_device *apollon_devices[] __initdata = {
        &apollon_onenand_device,
        &apollon_smc91x_device,
-       &apollon_lcd_device,
        &apollon_led_device,
 };
 
@@ -265,12 +262,26 @@ static struct omap_usb_config apollon_usb_config __initdata = {
        .pins[0]        = 6,
 };
 
-static struct omap_lcd_config apollon_lcd_config __initdata = {
-       .ctrl_name      = "internal",
+static struct panel_generic_dpi_data apollon_panel_data = {
+       .name                   = "apollon",
 };
 
-static struct omap_board_config_kernel apollon_config[] __initdata = {
-       { OMAP_TAG_LCD,         &apollon_lcd_config },
+static struct omap_dss_device apollon_lcd_device = {
+       .name                   = "lcd",
+       .driver_name            = "generic_dpi_panel",
+       .type                   = OMAP_DISPLAY_TYPE_DPI,
+       .phy.dpi.data_lines     = 18,
+       .data                   = &apollon_panel_data,
+};
+
+static struct omap_dss_device *apollon_dss_devices[] = {
+       &apollon_lcd_device,
+};
+
+static struct omap_dss_board_info apollon_dss_data = {
+       .num_devices    = ARRAY_SIZE(apollon_dss_devices),
+       .devices        = apollon_dss_devices,
+       .default_device = &apollon_lcd_device,
 };
 
 static void __init omap_apollon_init_early(void)
@@ -314,8 +325,6 @@ static void __init omap_apollon_init(void)
        u32 v;
 
        omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
-       omap_board_config = apollon_config;
-       omap_board_config_size = ARRAY_SIZE(apollon_config);
 
        apollon_init_smc91x();
        apollon_led_init();
@@ -340,6 +349,8 @@ static void __init omap_apollon_init(void)
         */
        platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
        omap_serial_init();
+
+       omap_display_init(&apollon_dss_data);
 }
 
 static void __init omap_apollon_map_io(void)
index 3af8aab..2d112bf 100644 (file)
@@ -43,6 +43,7 @@
 #include <plat/usb.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 #include <plat/mcspi.h>
 
 #include <mach/hardware.h>
@@ -242,8 +243,7 @@ static struct omap_dss_device cm_t35_lcd_device = {
        .phy.dpi.data_lines     = 18,
 };
 
-static struct panel_generic_dpi_data dvi_panel = {
-       .name                   = "generic",
+static struct panel_dvi_platform_data dvi_panel = {
        .platform_enable        = cm_t35_panel_enable_dvi,
        .platform_disable       = cm_t35_panel_disable_dvi,
 };
@@ -251,7 +251,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device cm_t35_dvi_device = {
        .name                   = "dvi",
        .type                   = OMAP_DISPLAY_TYPE_DPI,
-       .driver_name            = "generic_dpi_panel",
+       .driver_name            = "dvi",
        .data                   = &dvi_panel,
        .phy.dpi.data_lines     = 24,
 };
index b6002ec..44da207 100644 (file)
@@ -47,6 +47,7 @@
 #include <plat/usb.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include <plat/mcspi.h>
 #include <linux/input/matrix_keypad.h>
@@ -139,7 +140,7 @@ static struct regulator_consumer_supply devkit8000_vio_supply[] = {
 };
 
 static struct panel_generic_dpi_data lcd_panel = {
-       .name                   = "generic",
+       .name                   = "innolux_at070tn83",
        .platform_enable        = devkit8000_panel_enable_lcd,
        .platform_disable       = devkit8000_panel_disable_lcd,
 };
@@ -152,8 +153,7 @@ static struct omap_dss_device devkit8000_lcd_device = {
        .phy.dpi.data_lines     = 24,
 };
 
-static struct panel_generic_dpi_data dvi_panel = {
-       .name                   = "generic",
+static struct panel_dvi_platform_data dvi_panel = {
        .platform_enable        = devkit8000_panel_enable_dvi,
        .platform_disable       = devkit8000_panel_disable_dvi,
 };
@@ -161,7 +161,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device devkit8000_dvi_device = {
        .name                   = "dvi",
        .type                   = OMAP_DISPLAY_TYPE_DPI,
-       .driver_name            = "generic_dpi_panel",
+       .driver_name            = "dvi",
        .data                   = &dvi_panel,
        .phy.dpi.data_lines     = 24,
 };
@@ -267,7 +267,7 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
 
 static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
        REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-       REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+       REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
index 45de2b3..f7c09de 100644 (file)
@@ -40,6 +40,9 @@
 #include <plat/dma.h>
 #include <plat/gpmc.h>
 
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
 #include "mux.h"
 #include "control.h"
 
@@ -157,17 +160,33 @@ static struct platform_device h4_kp_device = {
        },
 };
 
-static struct platform_device h4_lcd_device = {
-       .name           = "lcd_h4",
-       .id             = -1,
-};
-
 static struct platform_device *h4_devices[] __initdata = {
        &h4_flash_device,
        &h4_kp_device,
+};
+
+static struct panel_generic_dpi_data h4_panel_data = {
+       .name                   = "h4",
+};
+
+static struct omap_dss_device h4_lcd_device = {
+       .name                   = "lcd",
+       .driver_name            = "generic_dpi_panel",
+       .type                   = OMAP_DISPLAY_TYPE_DPI,
+       .phy.dpi.data_lines     = 16,
+       .data                   = &h4_panel_data,
+};
+
+static struct omap_dss_device *h4_dss_devices[] = {
        &h4_lcd_device,
 };
 
+static struct omap_dss_board_info h4_dss_data = {
+       .num_devices    = ARRAY_SIZE(h4_dss_devices),
+       .devices        = h4_dss_devices,
+       .default_device = &h4_lcd_device,
+};
+
 /* 2420 Sysboot setup (2430 is different) */
 static u32 get_sysboot_value(void)
 {
@@ -271,10 +290,6 @@ static void __init h4_init_flash(void)
        h4_flash_resource.end   = base + SZ_64M - 1;
 }
 
-static struct omap_lcd_config h4_lcd_config __initdata = {
-       .ctrl_name      = "internal",
-};
-
 static struct omap_usb_config h4_usb_config __initdata = {
        /* S1.10 OFF -- usb "download port"
         * usb0 switched to Mini-B port and isp1105 transceiver;
@@ -286,10 +301,6 @@ static struct omap_usb_config h4_usb_config __initdata = {
        .hmc_mode       = 0x00,         /* 0:dev|otg 1:disable 2:disable */
 };
 
-static struct omap_board_config_kernel h4_config[] __initdata = {
-       { OMAP_TAG_LCD,         &h4_lcd_config },
-};
-
 static void __init omap_h4_init_early(void)
 {
        omap2_init_common_infrastructure();
@@ -331,9 +342,6 @@ static void __init omap_h4_init(void)
 {
        omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAF);
 
-       omap_board_config = h4_config;
-       omap_board_config_size = ARRAY_SIZE(h4_config);
-
        /*
         * Make sure the serial ports are muxed on at this point.
         * You have to mux them off in device drivers later on
@@ -372,6 +380,8 @@ static void __init omap_h4_init(void)
        omap2_usbfs_init(&h4_usb_config);
        omap_serial_init();
        h4_init_flash();
+
+       omap_display_init(&h4_dss_data);
 }
 
 static void __init omap_h4_map_io(void)
index 35be778..6ff5222 100644 (file)
@@ -32,7 +32,7 @@
 #include <plat/gpmc.h>
 #include <plat/usb.h>
 #include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 #include <plat/onenand.h>
 
 #include "mux.h"
@@ -455,16 +455,16 @@ static void igep2_disable_dvi(struct omap_dss_device *dssdev)
        gpio_direction_output(IGEP2_GPIO_DVI_PUP, 0);
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-       .name                   = "generic",
+static struct panel_dvi_platform_data dvi_panel = {
        .platform_enable        = igep2_enable_dvi,
        .platform_disable       = igep2_disable_dvi,
+       .i2c_bus_num = 3,
 };
 
 static struct omap_dss_device igep2_dvi_device = {
        .type                   = OMAP_DISPLAY_TYPE_DPI,
        .name                   = "dvi",
-       .driver_name            = "generic_dpi_panel",
+       .driver_name            = "dvi",
        .data                   = &dvi_panel,
        .phy.dpi.data_lines     = 24,
 };
index 218764c..689ed49 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/io.h>
 #include <linux/smsc911x.h>
 #include <linux/mmc/host.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -34,7 +35,6 @@
 #include <asm/mach/map.h>
 
 #include <plat/mcspi.h>
-#include <mach/gpio.h>
 #include <plat/board.h>
 #include <plat/common.h>
 #include <plat/gpmc.h>
@@ -44,6 +44,9 @@
 #include <plat/usb.h>
 #include <plat/gpmc-smsc911x.h>
 
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
 #include "board-flash.h"
 #include "mux.h"
 #include "hsmmc.h"
@@ -180,29 +183,108 @@ static inline void __init ldp_init_smsc911x(void)
        gpmc_smsc911x_init(&smsc911x_cfg);
 }
 
-static struct platform_device ldp_lcd_device = {
-       .name           = "ldp_lcd",
-       .id             = -1,
+/* LCD */
+
+static int ldp_backlight_gpio;
+static int ldp_lcd_enable_gpio;
+
+#define LCD_PANEL_RESET_GPIO           55
+#define LCD_PANEL_QVGA_GPIO            56
+
+static int ldp_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+       if (gpio_is_valid(ldp_lcd_enable_gpio))
+               gpio_direction_output(ldp_lcd_enable_gpio, 1);
+       if (gpio_is_valid(ldp_backlight_gpio))
+               gpio_direction_output(ldp_backlight_gpio, 1);
+
+       return 0;
+}
+
+static void ldp_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+       if (gpio_is_valid(ldp_lcd_enable_gpio))
+               gpio_direction_output(ldp_lcd_enable_gpio, 0);
+       if (gpio_is_valid(ldp_backlight_gpio))
+               gpio_direction_output(ldp_backlight_gpio, 0);
+}
+
+static struct panel_generic_dpi_data ldp_panel_data = {
+       .name                   = "nec_nl2432dr22-11b",
+       .platform_enable        = ldp_panel_enable_lcd,
+       .platform_disable       = ldp_panel_disable_lcd,
 };
 
-static struct omap_lcd_config ldp_lcd_config __initdata = {
-       .ctrl_name      = "internal",
+static struct omap_dss_device ldp_lcd_device = {
+       .name                   = "lcd",
+       .driver_name            = "generic_dpi_panel",
+       .type                   = OMAP_DISPLAY_TYPE_DPI,
+       .phy.dpi.data_lines     = 18,
+       .data                   = &ldp_panel_data,
+};
+
+static struct omap_dss_device *ldp_dss_devices[] = {
+       &ldp_lcd_device,
 };
 
-static struct omap_board_config_kernel ldp_config[] __initdata = {
-       { OMAP_TAG_LCD,         &ldp_lcd_config },
+static struct omap_dss_board_info ldp_dss_data = {
+       .num_devices    = ARRAY_SIZE(ldp_dss_devices),
+       .devices        = ldp_dss_devices,
+       .default_device = &ldp_lcd_device,
 };
 
+static void __init ldp_display_init(void)
+{
+       int r;
+
+       static struct gpio gpios[] __initdata = {
+               {LCD_PANEL_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "LCD RESET"},
+               {LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "LCD QVGA"},
+       };
+
+       r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+       if (r) {
+               pr_err("Cannot request LCD GPIOs, error %d\n", r);
+               return;
+       }
+
+       omap_display_init(&ldp_dss_data);
+}
+
 static void __init omap_ldp_init_early(void)
 {
        omap2_init_common_infrastructure();
        omap2_init_common_devices(NULL, NULL);
 }
 
+static int ldp_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio)
+{
+       int r;
+
+       struct gpio gpios[] = {
+               {gpio + 7 , GPIOF_OUT_INIT_LOW, "LCD ENABLE"},
+               {gpio + 15, GPIOF_OUT_INIT_LOW, "LCD BACKLIGHT"},
+       };
+
+       r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+       if (r) {
+               pr_err("Cannot request LCD GPIOs, error %d\n", r);
+               ldp_backlight_gpio = -EINVAL;
+               ldp_lcd_enable_gpio = -EINVAL;
+               return r;
+       }
+
+       ldp_backlight_gpio = gpio + 15;
+       ldp_lcd_enable_gpio = gpio + 7;
+
+       return 0;
+}
+
 static struct twl4030_gpio_platform_data ldp_gpio_data = {
        .gpio_base      = OMAP_MAX_GPIO_LINES,
        .irq_base       = TWL4030_GPIO_IRQ_BASE,
        .irq_end        = TWL4030_GPIO_IRQ_END,
+       .setup          = ldp_twl_gpio_setup,
 };
 
 static struct regulator_consumer_supply ldp_vmmc1_supply[] = {
@@ -244,10 +326,31 @@ static struct regulator_init_data ldp_vaux1 = {
        .consumer_supplies              = ldp_vaux1_supplies,
 };
 
+static struct regulator_consumer_supply ldp_vpll2_supplies[] = {
+       REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+       REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+static struct regulator_init_data ldp_vpll2 = {
+       .constraints = {
+               .name                   = "VDVI",
+               .min_uV                 = 1800000,
+               .max_uV                 = 1800000,
+               .apply_uV               = true,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(ldp_vpll2_supplies),
+       .consumer_supplies      = ldp_vpll2_supplies,
+};
+
 static struct twl4030_platform_data ldp_twldata = {
        /* platform_data for children goes here */
        .vmmc1          = &ldp_vmmc1,
        .vaux1          = &ldp_vaux1,
+       .vpll2          = &ldp_vpll2,
        .gpio           = &ldp_gpio_data,
        .keypad         = &ldp_kp_twl4030_data,
 };
@@ -273,7 +376,6 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
 };
 
 static struct platform_device *ldp_devices[] __initdata = {
-       &ldp_lcd_device,
        &ldp_gpio_keys_device,
 };
 
@@ -318,8 +420,6 @@ static struct mtd_partition ldp_nand_partitions[] = {
 static void __init omap_ldp_init(void)
 {
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-       omap_board_config = ldp_config;
-       omap_board_config_size = ARRAY_SIZE(ldp_config);
        ldp_init_smsc911x();
        omap_i2c_init();
        platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
@@ -330,6 +430,7 @@ static void __init omap_ldp_init(void)
                ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
 
        omap2_hsmmc_init(mmc);
+       ldp_display_init();
 }
 
 MACHINE_START(OMAP_LDP, "OMAP LDP board")
index 3ae16b4..742ac45 100644 (file)
@@ -42,7 +42,7 @@
 #include <plat/board.h>
 #include <plat/common.h>
 #include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 #include <plat/gpmc.h>
 #include <plat/nand.h>
 #include <plat/usb.h>
@@ -203,16 +203,16 @@ static void beagle_disable_dvi(struct omap_dss_device *dssdev)
                gpio_set_value(dssdev->reset_gpio, 0);
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-       .name = "generic",
+static struct panel_dvi_platform_data dvi_panel = {
        .platform_enable = beagle_enable_dvi,
        .platform_disable = beagle_disable_dvi,
+       .i2c_bus_num = 3,
 };
 
 static struct omap_dss_device beagle_dvi_device = {
        .type = OMAP_DISPLAY_TYPE_DPI,
        .name = "dvi",
-       .driver_name = "generic_dpi_panel",
+       .driver_name = "dvi",
        .data = &dvi_panel,
        .phy.dpi.data_lines = 24,
        .reset_gpio = -EINVAL,
index c452b3f..82142c5 100644 (file)
@@ -45,7 +45,7 @@
 #include <plat/common.h>
 #include <plat/mcspi.h>
 #include <video/omapdss.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
@@ -247,8 +247,7 @@ static void omap3_evm_disable_dvi(struct omap_dss_device *dssdev)
        dvi_enabled = 0;
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-       .name                   = "generic",
+static struct panel_dvi_platform_data dvi_panel = {
        .platform_enable        = omap3_evm_enable_dvi,
        .platform_disable       = omap3_evm_disable_dvi,
 };
@@ -256,7 +255,7 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device omap3_evm_dvi_device = {
        .name                   = "dvi",
        .type                   = OMAP_DISPLAY_TYPE_DPI,
-       .driver_name            = "generic_dpi_panel",
+       .driver_name            = "dvi",
        .data                   = &dvi_panel,
        .phy.dpi.data_lines     = 24,
 };
index 080d7bd..3f10001 100644 (file)
@@ -335,7 +335,7 @@ static struct regulator_consumer_supply pandora_vmmc3_supply[] = {
 static struct regulator_consumer_supply pandora_vdds_supplies[] = {
        REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
        REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-       REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+       REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = {
index 8e10498..106a2ba 100644 (file)
@@ -41,6 +41,7 @@
 #include <plat/usb.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include <plat/mcspi.h>
 #include <linux/input/matrix_keypad.h>
@@ -107,39 +108,6 @@ static void __init omap3_stalker_display_init(void)
        return;
 }
 
-static int omap3_stalker_enable_lcd(struct omap_dss_device *dssdev)
-{
-       if (dvi_enabled) {
-               printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
-               return -EINVAL;
-       }
-       gpio_set_value(DSS_ENABLE_GPIO, 1);
-       gpio_set_value(LCD_PANEL_BKLIGHT_GPIO, 1);
-       lcd_enabled = 1;
-       return 0;
-}
-
-static void omap3_stalker_disable_lcd(struct omap_dss_device *dssdev)
-{
-       gpio_set_value(DSS_ENABLE_GPIO, 0);
-       gpio_set_value(LCD_PANEL_BKLIGHT_GPIO, 0);
-       lcd_enabled = 0;
-}
-
-static struct panel_generic_dpi_data lcd_panel = {
-       .name                   = "generic",
-       .platform_enable        = omap3_stalker_enable_lcd,
-       .platform_disable       = omap3_stalker_disable_lcd,
-};
-
-static struct omap_dss_device omap3_stalker_lcd_device = {
-       .name                   = "lcd",
-       .driver_name            = "generic_dpi_panel",
-       .data                   = &lcd_panel,
-       .phy.dpi.data_lines     = 24,
-       .type                   = OMAP_DISPLAY_TYPE_DPI,
-};
-
 static int omap3_stalker_enable_tv(struct omap_dss_device *dssdev)
 {
        return 0;
@@ -179,8 +147,7 @@ static void omap3_stalker_disable_dvi(struct omap_dss_device *dssdev)
        dvi_enabled = 0;
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-       .name                   = "generic",
+static struct panel_dvi_platform_data dvi_panel = {
        .platform_enable        = omap3_stalker_enable_dvi,
        .platform_disable       = omap3_stalker_disable_dvi,
 };
@@ -188,13 +155,12 @@ static struct panel_generic_dpi_data dvi_panel = {
 static struct omap_dss_device omap3_stalker_dvi_device = {
        .name                   = "dvi",
        .type                   = OMAP_DISPLAY_TYPE_DPI,
-       .driver_name            = "generic_dpi_panel",
+       .driver_name            = "dvi",
        .data                   = &dvi_panel,
        .phy.dpi.data_lines     = 24,
 };
 
 static struct omap_dss_device *omap3_stalker_dss_devices[] = {
-       &omap3_stalker_lcd_device,
        &omap3_stalker_tv_device,
        &omap3_stalker_dvi_device,
 };
index 852ea04..80e8276 100644 (file)
@@ -104,15 +104,6 @@ static struct omap2_hsmmc_info mmc[] = {
        {}      /* Terminator */
 };
 
-static struct platform_device omap3_touchbook_lcd_device = {
-       .name           = "omap3touchbook_lcd",
-       .id             = -1,
-};
-
-static struct omap_lcd_config omap3_touchbook_lcd_config __initdata = {
-       .ctrl_name      = "internal",
-};
-
 static struct regulator_consumer_supply touchbook_vmmc1_supply[] = {
        REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
 };
@@ -165,14 +156,12 @@ static struct twl4030_gpio_platform_data touchbook_gpio_data = {
 static struct regulator_consumer_supply touchbook_vdac_supply[] = {
 {
        .supply         = "vdac",
-       .dev            = &omap3_touchbook_lcd_device.dev,
 },
 };
 
 static struct regulator_consumer_supply touchbook_vdvi_supply[] = {
 {
        .supply         = "vdvi",
-       .dev            = &omap3_touchbook_lcd_device.dev,
 },
 };
 
@@ -316,10 +305,6 @@ static struct platform_device keys_gpio = {
        },
 };
 
-static struct omap_board_config_kernel omap3_touchbook_config[] __initdata = {
-       { OMAP_TAG_LCD,         &omap3_touchbook_lcd_config },
-};
-
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
        { .reg_offset = OMAP_MUX_TERMINATOR },
@@ -339,7 +324,6 @@ static void __init omap3_touchbook_init_irq(void)
 }
 
 static struct platform_device *omap3_touchbook_devices[] __initdata = {
-       &omap3_touchbook_lcd_device,
        &leds_gpio,
        &keys_gpio,
 };
@@ -376,8 +360,6 @@ early_param("tbr", early_touchbook_revision);
 static void __init omap3_touchbook_init(void)
 {
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-       omap_board_config = omap3_touchbook_config;
-       omap_board_config_size = ARRAY_SIZE(omap3_touchbook_config);
 
        pm_power_off = omap3_touchbook_poweroff;
 
index 9aaa960..a38ed27 100644 (file)
@@ -40,7 +40,7 @@
 #include <plat/common.h>
 #include <plat/usb.h>
 #include <plat/mmc.h>
-#include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 
 #include "hsmmc.h"
 #include "control.h"
@@ -455,16 +455,16 @@ static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
 }
 
 /* Using generic display panel */
-static struct panel_generic_dpi_data omap4_dvi_panel = {
-       .name                   = "generic",
+static struct panel_dvi_platform_data omap4_dvi_panel = {
        .platform_enable        = omap4_panda_enable_dvi,
        .platform_disable       = omap4_panda_disable_dvi,
+       .i2c_bus_num = 3,
 };
 
 struct omap_dss_device omap4_panda_dvi_device = {
        .type                   = OMAP_DISPLAY_TYPE_DPI,
        .name                   = "dvi",
-       .driver_name            = "generic_dpi_panel",
+       .driver_name            = "dvi",
        .data                   = &omap4_dvi_panel,
        .phy.dpi.data_lines     = 24,
        .reset_gpio             = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
index f949a99..da94376 100644 (file)
@@ -46,6 +46,7 @@
 #include <plat/common.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-generic-dpi.h>
+#include <video/omap-panel-dvi.h>
 #include <plat/gpmc.h>
 #include <mach/hardware.h>
 #include <plat/nand.h>
@@ -182,16 +183,16 @@ static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
        dvi_enabled = 0;
 }
 
-static struct panel_generic_dpi_data dvi_panel = {
-       .name                   = "generic",
+static struct panel_dvi_platform_data dvi_panel = {
        .platform_enable        = overo_panel_enable_dvi,
        .platform_disable       = overo_panel_disable_dvi,
+       .i2c_bus_num            = 3,
 };
 
 static struct omap_dss_device overo_dvi_device = {
        .name                   = "dvi",
        .type                   = OMAP_DISPLAY_TYPE_DPI,
-       .driver_name            = "generic_dpi_panel",
+       .driver_name            = "dvi",
        .data                   = &dvi_panel,
        .phy.dpi.data_lines     = 24,
 };
index 5ea142f..9e7dde6 100644 (file)
@@ -79,29 +79,6 @@ static struct cpuidle_params rx51_cpuidle_params[] = {
        {7505 + 15274, 484329, 1},
 };
 
-static struct omap_lcd_config rx51_lcd_config = {
-       .ctrl_name      = "internal",
-};
-
-static struct omap_fbmem_config rx51_fbmem0_config = {
-       .size = 752 * 1024,
-};
-
-static struct omap_fbmem_config rx51_fbmem1_config = {
-       .size = 752 * 1024,
-};
-
-static struct omap_fbmem_config rx51_fbmem2_config = {
-       .size = 752 * 1024,
-};
-
-static struct omap_board_config_kernel rx51_config[] = {
-       { OMAP_TAG_FBMEM,       &rx51_fbmem0_config },
-       { OMAP_TAG_FBMEM,       &rx51_fbmem1_config },
-       { OMAP_TAG_FBMEM,       &rx51_fbmem2_config },
-       { OMAP_TAG_LCD,         &rx51_lcd_config },
-};
-
 static void __init rx51_init_early(void)
 {
        struct omap_sdrc_params *sdrc_params;
@@ -128,8 +105,6 @@ static struct omap_musb_board_data musb_board_data = {
 static void __init rx51_init(void)
 {
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-       omap_board_config = rx51_config;
-       omap_board_config_size = ARRAY_SIZE(rx51_config);
        omap3_pm_init_cpuidle(rx51_cpuidle_params);
        omap_serial_init();
        usb_musb_init(&musb_board_data);
index a5b7a23..62510ec 100644 (file)
@@ -27,6 +27,8 @@
 #include <plat/omap_device.h>
 #include <plat/omap-pm.h>
 
+#include "control.h"
+
 static struct platform_device omap_display_device = {
        .name          = "omapdss",
        .id            = -1,
@@ -61,7 +63,7 @@ static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initdata = {
        { "dss_dispc", "omapdss_dispc", -1 },
        { "dss_rfbi", "omapdss_rfbi", -1 },
        { "dss_venc", "omapdss_venc", -1 },
-       { "dss_dsi1", "omapdss_dsi1", -1 },
+       { "dss_dsi1", "omapdss_dsi", 0 },
 };
 
 static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
@@ -69,11 +71,58 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
        { "dss_dispc", "omapdss_dispc", -1 },
        { "dss_rfbi", "omapdss_rfbi", -1 },
        { "dss_venc", "omapdss_venc", -1 },
-       { "dss_dsi1", "omapdss_dsi1", -1 },
-       { "dss_dsi2", "omapdss_dsi2", -1 },
+       { "dss_dsi1", "omapdss_dsi", 0 },
+       { "dss_dsi2", "omapdss_dsi", 1 },
        { "dss_hdmi", "omapdss_hdmi", -1 },
 };
 
+static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
+{
+       u32 enable_mask, enable_shift;
+       u32 pipd_mask, pipd_shift;
+       u32 reg;
+
+       if (dsi_id == 0) {
+               enable_mask = OMAP4_DSI1_LANEENABLE_MASK;
+               enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT;
+               pipd_mask = OMAP4_DSI1_PIPD_MASK;
+               pipd_shift = OMAP4_DSI1_PIPD_SHIFT;
+       } else if (dsi_id == 1) {
+               enable_mask = OMAP4_DSI2_LANEENABLE_MASK;
+               enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT;
+               pipd_mask = OMAP4_DSI2_PIPD_MASK;
+               pipd_shift = OMAP4_DSI2_PIPD_SHIFT;
+       } else {
+               return -ENODEV;
+       }
+
+       reg = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
+
+       reg &= ~enable_mask;
+       reg &= ~pipd_mask;
+
+       reg |= (lanes << enable_shift) & enable_mask;
+       reg |= (lanes << pipd_shift) & pipd_mask;
+
+       omap4_ctrl_pad_writel(reg, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY);
+
+       return 0;
+}
+
+static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
+{
+       if (cpu_is_omap44xx())
+               return omap4_dsi_mux_pads(dsi_id, lane_mask);
+
+       return 0;
+}
+
+static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
+{
+       if (cpu_is_omap44xx())
+               omap4_dsi_mux_pads(dsi_id, 0);
+}
+
 int __init omap_display_init(struct omap_dss_board_info *board_data)
 {
        int r = 0;
@@ -96,6 +145,11 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
                oh_count = ARRAY_SIZE(omap4_dss_hwmod_data);
        }
 
+       if (board_data->dsi_enable_pads == NULL)
+               board_data->dsi_enable_pads = omap_dsi_enable_pads;
+       if (board_data->dsi_disable_pads == NULL)
+               board_data->dsi_disable_pads = omap_dsi_disable_pads;
+
        pdata.board_data = board_data;
        pdata.board_data->get_context_loss_count =
                omap_pm_get_dev_context_loss_count;
index daa056e..5224357 100644 (file)
@@ -99,7 +99,7 @@ static struct regulator_init_data omap3_vdac_idata = {
 
 static struct regulator_consumer_supply omap3_vpll2_supplies[] = {
        REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-       REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+       REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static struct regulator_init_data omap3_vpll2_idata = {
@@ -235,6 +235,12 @@ static struct regulator_init_data omap4_vana_idata = {
        },
 };
 
+static struct regulator_consumer_supply omap4_vcxio_supply[] = {
+       REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
+       REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
+       REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.1"),
+};
+
 static struct regulator_init_data omap4_vcxio_idata = {
        .constraints = {
                .min_uV                 = 1800000,
@@ -243,7 +249,10 @@ static struct regulator_init_data omap4_vcxio_idata = {
                                        | REGULATOR_MODE_STANDBY,
                .valid_ops_mask         = REGULATOR_CHANGE_MODE
                                        | REGULATOR_CHANGE_STATUS,
+               .always_on              = true,
        },
+       .num_consumer_supplies  = ARRAY_SIZE(omap4_vcxio_supply),
+       .consumer_supplies      = omap4_vcxio_supply,
 };
 
 static struct regulator_init_data omap4_vusb_idata = {
index b3a5ecd..30d8896 100644 (file)
@@ -400,7 +400,6 @@ static int omapvid_setup_overlay(struct omap_vout_device *vout,
 
        ovl->get_overlay_info(ovl, &info);
        info.paddr = addr;
-       info.vaddr = NULL;
        info.width = cropwidth;
        info.height = cropheight;
        info.color_mode = vout->dss_mode;
@@ -1165,12 +1164,17 @@ static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh,
 {
        int ret = 0;
        struct omap_vout_device *vout = fh;
+       struct omap_overlay *ovl;
+       struct omapvideo_info *ovid;
        struct v4l2_window *win = &f->fmt.win;
 
+       ovid = &vout->vid_info;
+       ovl = ovid->overlays[0];
+
        ret = omap_vout_try_window(&vout->fbuf, win);
 
        if (!ret) {
-               if (vout->vid == OMAP_VIDEO1)
+               if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
                        win->global_alpha = 255;
                else
                        win->global_alpha = f->fmt.win.global_alpha;
@@ -1194,8 +1198,8 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh,
 
        ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win);
        if (!ret) {
-               /* Video1 plane does not support global alpha */
-               if (ovl->id == OMAP_DSS_VIDEO1)
+               /* Video1 plane does not support global alpha on OMAP3 */
+               if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
                        vout->win.global_alpha = 255;
                else
                        vout->win.global_alpha = f->fmt.win.global_alpha;
@@ -1788,7 +1792,9 @@ static int vidioc_s_fbuf(struct file *file, void *fh,
        if (ovl->manager && ovl->manager->get_manager_info &&
                        ovl->manager->set_manager_info) {
                ovl->manager->get_manager_info(ovl->manager, &info);
-               info.alpha_enabled = enable;
+               /* enable this only if there is no zorder cap */
+               if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
+                       info.partial_alpha_enabled = enable;
                if (ovl->manager->set_manager_info(ovl->manager, &info))
                        return -EINVAL;
        }
@@ -1820,7 +1826,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh,
        }
        if (ovl->manager && ovl->manager->get_manager_info) {
                ovl->manager->get_manager_info(ovl->manager, &info);
-               if (info.alpha_enabled)
+               if (info.partial_alpha_enabled)
                        a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
        }
 
index 196fa2e..84ff232 100644 (file)
@@ -9,35 +9,6 @@ config FB_OMAP
        help
           Frame buffer driver for OMAP based boards.
 
-config FB_OMAP_LCD_VGA
-        bool "Use LCD in VGA mode"
-               depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP
-               help
-                 Set LCD resolution as VGA (640 X 480).
-                 Default resolution without this option is QVGA(320 X 240).
-                 Please take a look at drivers/video/omap/lcd_ldp.c file
-                 for lcd driver code.
-choice
-       depends on FB_OMAP && MACH_OVERO
-       prompt "Screen resolution"
-       default FB_OMAP_079M3R
-       help
-         Selected desired screen resolution
-
-config FB_OMAP_031M3R
-       boolean "640 x 480 @ 60 Hz Reduced blanking"
-
-config FB_OMAP_048M3R
-       boolean "800 x 600 @ 60 Hz Reduced blanking"
-
-config FB_OMAP_079M3R
-       boolean "1024 x 768 @ 60 Hz Reduced blanking"
-
-config FB_OMAP_092M9R
-       boolean "1280 x 720 @ 60 Hz Reduced blanking"
-
-endchoice
-
 config FB_OMAP_LCDC_EXTERNAL
        bool "External LCD controller support"
        depends on FB_OMAP
index 25db556..ef78550 100644 (file)
@@ -17,7 +17,6 @@ objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
 objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o
 
 objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o
-objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o
 objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o
 objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o
 objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o
@@ -26,14 +25,7 @@ objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o
 objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o
 objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
 
-objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
-objs-y$(CONFIG_MACH_OMAP_2430SDP) += lcd_2430sdp.o
-objs-y$(CONFIG_MACH_OMAP_3430SDP) += lcd_2430sdp.o
-objs-y$(CONFIG_MACH_OMAP_LDP) += lcd_ldp.o
-objs-y$(CONFIG_MACH_OMAP3EVM) += lcd_omap3evm.o
-objs-y$(CONFIG_MACH_OMAP3_BEAGLE) += lcd_omap3beagle.o
 objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
-objs-y$(CONFIG_MACH_OVERO) += lcd_overo.o
 objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o
 
 omapfb-objs := $(objs-yy)
diff --git a/drivers/video/omap/lcd_2430sdp.c b/drivers/video/omap/lcd_2430sdp.c
deleted file mode 100644 (file)
index e3eccc9..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * LCD panel support for the TI 2430SDP board
- *
- * Copyright (C) 2007 MontaVista
- * Author: Hunyue Yau <hyau@mvista.com>
- *
- * Derived from drivers/video/omap/lcd-apollon.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/i2c/twl.h>
-
-#include <plat/mux.h>
-#include <asm/mach-types.h>
-
-#include "omapfb.h"
-
-#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO       91
-#define SDP2430_LCD_PANEL_ENABLE_GPIO          154
-#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO       24
-#define SDP3430_LCD_PANEL_ENABLE_GPIO          28
-
-static unsigned backlight_gpio;
-static unsigned enable_gpio;
-
-#define LCD_PIXCLOCK_MAX               5400 /* freq 5.4 MHz */
-#define PM_RECEIVER             TWL4030_MODULE_PM_RECEIVER
-#define ENABLE_VAUX2_DEDICATED  0x09
-#define ENABLE_VAUX2_DEV_GRP    0x20
-#define ENABLE_VAUX3_DEDICATED 0x03
-#define ENABLE_VAUX3_DEV_GRP   0x20
-
-#define ENABLE_VPLL2_DEDICATED          0x05
-#define ENABLE_VPLL2_DEV_GRP            0xE0
-#define TWL4030_VPLL2_DEV_GRP           0x33
-#define TWL4030_VPLL2_DEDICATED         0x36
-
-#define t2_out(c, r, v) twl_i2c_write_u8(c, r, v)
-
-
-static int sdp2430_panel_init(struct lcd_panel *panel,
-                               struct omapfb_device *fbdev)
-{
-       if (machine_is_omap_3430sdp()) {
-               enable_gpio    = SDP3430_LCD_PANEL_ENABLE_GPIO;
-               backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO;
-       } else {
-               enable_gpio    = SDP2430_LCD_PANEL_ENABLE_GPIO;
-               backlight_gpio = SDP2430_LCD_PANEL_BACKLIGHT_GPIO;
-       }
-
-       gpio_request(enable_gpio, "LCD enable");        /* LCD panel */
-       gpio_request(backlight_gpio, "LCD bl");         /* LCD backlight */
-       gpio_direction_output(enable_gpio, 0);
-       gpio_direction_output(backlight_gpio, 0);
-
-       return 0;
-}
-
-static void sdp2430_panel_cleanup(struct lcd_panel *panel)
-{
-       gpio_free(backlight_gpio);
-       gpio_free(enable_gpio);
-}
-
-static int sdp2430_panel_enable(struct lcd_panel *panel)
-{
-       u8 ded_val, ded_reg;
-       u8 grp_val, grp_reg;
-
-       if (machine_is_omap_3430sdp()) {
-               ded_reg = TWL4030_VAUX3_DEDICATED;
-               ded_val = ENABLE_VAUX3_DEDICATED;
-               grp_reg = TWL4030_VAUX3_DEV_GRP;
-               grp_val = ENABLE_VAUX3_DEV_GRP;
-
-               if (omap_rev() > OMAP3430_REV_ES1_0) {
-                       t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
-                                       TWL4030_VPLL2_DEDICATED);
-                       t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
-                                       TWL4030_VPLL2_DEV_GRP);
-               }
-       } else {
-               ded_reg = TWL4030_VAUX2_DEDICATED;
-               ded_val = ENABLE_VAUX2_DEDICATED;
-               grp_reg = TWL4030_VAUX2_DEV_GRP;
-               grp_val = ENABLE_VAUX2_DEV_GRP;
-       }
-
-       gpio_set_value(enable_gpio, 1);
-       gpio_set_value(backlight_gpio, 1);
-
-       if (0 != t2_out(PM_RECEIVER, ded_val, ded_reg))
-               return -EIO;
-       if (0 != t2_out(PM_RECEIVER, grp_val, grp_reg))
-               return -EIO;
-
-       return 0;
-}
-
-static void sdp2430_panel_disable(struct lcd_panel *panel)
-{
-       gpio_set_value(enable_gpio, 0);
-       gpio_set_value(backlight_gpio, 0);
-       if (omap_rev() > OMAP3430_REV_ES1_0) {
-               t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
-               t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
-               msleep(4);
-       }
-}
-
-static unsigned long sdp2430_panel_get_caps(struct lcd_panel *panel)
-{
-       return 0;
-}
-
-struct lcd_panel sdp2430_panel = {
-       .name           = "sdp2430",
-       .config         = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
-                         OMAP_LCDC_INV_HSYNC,
-
-       .bpp            = 16,
-       .data_lines     = 16,
-       .x_res          = 240,
-       .y_res          = 320,
-       .hsw            = 3,            /* hsync_len (4) - 1 */
-       .hfp            = 3,            /* right_margin (4) - 1 */
-       .hbp            = 39,           /* left_margin (40) - 1 */
-       .vsw            = 1,            /* vsync_len (2) - 1 */
-       .vfp            = 2,            /* lower_margin */
-       .vbp            = 7,            /* upper_margin (8) - 1 */
-
-       .pixel_clock    = LCD_PIXCLOCK_MAX,
-
-       .init           = sdp2430_panel_init,
-       .cleanup        = sdp2430_panel_cleanup,
-       .enable         = sdp2430_panel_enable,
-       .disable        = sdp2430_panel_disable,
-       .get_caps       = sdp2430_panel_get_caps,
-};
-
-static int sdp2430_panel_probe(struct platform_device *pdev)
-{
-       omapfb_register_panel(&sdp2430_panel);
-       return 0;
-}
-
-static int sdp2430_panel_remove(struct platform_device *pdev)
-{
-       return 0;
-}
-
-static int sdp2430_panel_suspend(struct platform_device *pdev,
-                                       pm_message_t mesg)
-{
-       return 0;
-}
-
-static int sdp2430_panel_resume(struct platform_device *pdev)
-{
-       return 0;
-}
-
-struct platform_driver sdp2430_panel_driver = {
-       .probe          = sdp2430_panel_probe,
-       .remove         = sdp2430_panel_remove,
-       .suspend        = sdp2430_panel_suspend,
-       .resume         = sdp2430_panel_resume,
-       .driver         = {
-               .name   = "sdp2430_lcd",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int __init sdp2430_panel_drv_init(void)
-{
-       return platform_driver_register(&sdp2430_panel_driver);
-}
-
-static void __exit sdp2430_panel_drv_exit(void)
-{
-       platform_driver_unregister(&sdp2430_panel_driver);
-}
-
-module_init(sdp2430_panel_drv_init);
-module_exit(sdp2430_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_apollon.c b/drivers/video/omap/lcd_apollon.c
deleted file mode 100644 (file)
index 10459d8..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * LCD panel support for the Samsung OMAP2 Apollon board
- *
- * Copyright (C) 2005,2006 Samsung Electronics
- * Author: Kyungmin Park <kyungmin.park@samsung.com>
- *
- * Derived from drivers/video/omap/lcd-h4.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include <mach/gpio.h>
-
-#include "omapfb.h"
-
-/* #define USE_35INCH_LCD 1 */
-
-static int apollon_panel_init(struct lcd_panel *panel,
-                               struct omapfb_device *fbdev)
-{
-       return 0;
-}
-
-static void apollon_panel_cleanup(struct lcd_panel *panel)
-{
-}
-
-static int apollon_panel_enable(struct lcd_panel *panel)
-{
-       return 0;
-}
-
-static void apollon_panel_disable(struct lcd_panel *panel)
-{
-}
-
-static unsigned long apollon_panel_get_caps(struct lcd_panel *panel)
-{
-       return 0;
-}
-
-struct lcd_panel apollon_panel = {
-       .name           = "apollon",
-       .config         = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
-                         OMAP_LCDC_INV_HSYNC,
-
-       .bpp            = 16,
-       .data_lines     = 18,
-#ifdef USE_35INCH_LCD
-       .x_res          = 240,
-       .y_res          = 320,
-       .hsw            = 2,
-       .hfp            = 3,
-       .hbp            = 9,
-       .vsw            = 4,
-       .vfp            = 3,
-       .vbp            = 5,
-#else
-       .x_res          = 480,
-       .y_res          = 272,
-       .hsw            = 41,
-       .hfp            = 2,
-       .hbp            = 2,
-       .vsw            = 10,
-       .vfp            = 2,
-       .vbp            = 2,
-#endif
-       .pixel_clock    = 6250,
-
-       .init           = apollon_panel_init,
-       .cleanup        = apollon_panel_cleanup,
-       .enable         = apollon_panel_enable,
-       .disable        = apollon_panel_disable,
-       .get_caps       = apollon_panel_get_caps,
-};
-
-static int apollon_panel_probe(struct platform_device *pdev)
-{
-       omapfb_register_panel(&apollon_panel);
-       return 0;
-}
-
-static int apollon_panel_remove(struct platform_device *pdev)
-{
-       return 0;
-}
-
-static int apollon_panel_suspend(struct platform_device *pdev,
-                                 pm_message_t mesg)
-{
-       return 0;
-}
-
-static int apollon_panel_resume(struct platform_device *pdev)
-{
-       return 0;
-}
-
-struct platform_driver apollon_panel_driver = {
-       .probe          = apollon_panel_probe,
-       .remove         = apollon_panel_remove,
-       .suspend        = apollon_panel_suspend,
-       .resume         = apollon_panel_resume,
-       .driver         = {
-               .name   = "apollon_lcd",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int __init apollon_panel_drv_init(void)
-{
-       return platform_driver_register(&apollon_panel_driver);
-}
-
-static void __exit apollon_panel_drv_exit(void)
-{
-       platform_driver_unregister(&apollon_panel_driver);
-}
-
-module_init(apollon_panel_drv_init);
-module_exit(apollon_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c
deleted file mode 100644 (file)
index 03a06a9..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * LCD panel support for the TI OMAP H4 board
- *
- * Copyright (C) 2004 Nokia Corporation
- * Author: Imre Deak <imre.deak@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include "omapfb.h"
-
-static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
-{
-       return 0;
-}
-
-static void h4_panel_cleanup(struct lcd_panel *panel)
-{
-}
-
-static int h4_panel_enable(struct lcd_panel *panel)
-{
-       return 0;
-}
-
-static void h4_panel_disable(struct lcd_panel *panel)
-{
-}
-
-static unsigned long h4_panel_get_caps(struct lcd_panel *panel)
-{
-       return 0;
-}
-
-static struct lcd_panel h4_panel = {
-       .name           = "h4",
-       .config         = OMAP_LCDC_PANEL_TFT,
-
-       .bpp            = 16,
-       .data_lines     = 16,
-       .x_res          = 240,
-       .y_res          = 320,
-       .pixel_clock    = 6250,
-       .hsw            = 15,
-       .hfp            = 15,
-       .hbp            = 60,
-       .vsw            = 1,
-       .vfp            = 1,
-       .vbp            = 1,
-
-       .init           = h4_panel_init,
-       .cleanup        = h4_panel_cleanup,
-       .enable         = h4_panel_enable,
-       .disable        = h4_panel_disable,
-       .get_caps       = h4_panel_get_caps,
-};
-
-static int h4_panel_probe(struct platform_device *pdev)
-{
-       omapfb_register_panel(&h4_panel);
-       return 0;
-}
-
-static int h4_panel_remove(struct platform_device *pdev)
-{
-       return 0;
-}
-
-static int h4_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
-       return 0;
-}
-
-static int h4_panel_resume(struct platform_device *pdev)
-{
-       return 0;
-}
-
-static struct platform_driver h4_panel_driver = {
-       .probe          = h4_panel_probe,
-       .remove         = h4_panel_remove,
-       .suspend        = h4_panel_suspend,
-       .resume         = h4_panel_resume,
-       .driver         = {
-               .name   = "lcd_h4",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int __init h4_panel_drv_init(void)
-{
-       return platform_driver_register(&h4_panel_driver);
-}
-
-static void __exit h4_panel_drv_cleanup(void)
-{
-       platform_driver_unregister(&h4_panel_driver);
-}
-
-module_init(h4_panel_drv_init);
-module_exit(h4_panel_drv_cleanup);
-
diff --git a/drivers/video/omap/lcd_ldp.c b/drivers/video/omap/lcd_ldp.c
deleted file mode 100644 (file)
index 0f5952c..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * LCD panel support for the TI LDP board
- *
- * Copyright (C) 2007 WindRiver
- * Author: Stanley Miao <stanley.miao@windriver.com>
- *
- * Derived from drivers/video/omap/lcd-2430sdp.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/i2c/twl.h>
-
-#include <mach/gpio.h>
-#include <plat/mux.h>
-#include <asm/mach-types.h>
-
-#include "omapfb.h"
-
-#define LCD_PANEL_BACKLIGHT_GPIO       (15 + OMAP_MAX_GPIO_LINES)
-#define LCD_PANEL_ENABLE_GPIO          (7 + OMAP_MAX_GPIO_LINES)
-
-#define LCD_PANEL_RESET_GPIO           55
-#define LCD_PANEL_QVGA_GPIO            56
-
-#ifdef CONFIG_FB_OMAP_LCD_VGA
-#define LCD_XRES               480
-#define LCD_YRES               640
-#define LCD_PIXCLOCK_MAX       41700
-#else
-#define LCD_XRES               240
-#define LCD_YRES               320
-#define LCD_PIXCLOCK_MAX       185186
-#endif
-
-#define PM_RECEIVER             TWL4030_MODULE_PM_RECEIVER
-#define ENABLE_VAUX2_DEDICATED  0x09
-#define ENABLE_VAUX2_DEV_GRP    0x20
-#define ENABLE_VAUX3_DEDICATED 0x03
-#define ENABLE_VAUX3_DEV_GRP   0x20
-
-#define ENABLE_VPLL2_DEDICATED          0x05
-#define ENABLE_VPLL2_DEV_GRP            0xE0
-#define TWL4030_VPLL2_DEV_GRP           0x33
-#define TWL4030_VPLL2_DEDICATED         0x36
-
-#define t2_out(c, r, v) twl_i2c_write_u8(c, r, v)
-
-
-static int ldp_panel_init(struct lcd_panel *panel,
-                               struct omapfb_device *fbdev)
-{
-       gpio_request(LCD_PANEL_RESET_GPIO, "lcd reset");
-       gpio_request(LCD_PANEL_QVGA_GPIO, "lcd qvga");
-       gpio_request(LCD_PANEL_ENABLE_GPIO, "lcd panel");
-       gpio_request(LCD_PANEL_BACKLIGHT_GPIO, "lcd backlight");
-
-       gpio_direction_output(LCD_PANEL_QVGA_GPIO, 0);
-       gpio_direction_output(LCD_PANEL_RESET_GPIO, 0);
-       gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
-       gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
-
-#ifdef CONFIG_FB_OMAP_LCD_VGA
-       gpio_set_value(LCD_PANEL_QVGA_GPIO, 0);
-#else
-       gpio_set_value(LCD_PANEL_QVGA_GPIO, 1);
-#endif
-       gpio_set_value(LCD_PANEL_RESET_GPIO, 1);
-
-       return 0;
-}
-
-static void ldp_panel_cleanup(struct lcd_panel *panel)
-{
-       gpio_free(LCD_PANEL_BACKLIGHT_GPIO);
-       gpio_free(LCD_PANEL_ENABLE_GPIO);
-       gpio_free(LCD_PANEL_QVGA_GPIO);
-       gpio_free(LCD_PANEL_RESET_GPIO);
-}
-
-static int ldp_panel_enable(struct lcd_panel *panel)
-{
-       if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
-                       TWL4030_VPLL2_DEDICATED))
-               return -EIO;
-       if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
-                       TWL4030_VPLL2_DEV_GRP))
-               return -EIO;
-
-       gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
-       gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 1);
-
-       if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEDICATED,
-                               TWL4030_VAUX3_DEDICATED))
-               return -EIO;
-       if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEV_GRP,
-                               TWL4030_VAUX3_DEV_GRP))
-               return -EIO;
-
-       return 0;
-}
-
-static void ldp_panel_disable(struct lcd_panel *panel)
-{
-       gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
-       gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
-
-       t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
-       t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
-       msleep(4);
-}
-
-static unsigned long ldp_panel_get_caps(struct lcd_panel *panel)
-{
-       return 0;
-}
-
-struct lcd_panel ldp_panel = {
-       .name           = "ldp",
-       .config         = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
-                         OMAP_LCDC_INV_HSYNC,
-
-       .bpp            = 16,
-       .data_lines     = 18,
-       .x_res          = LCD_XRES,
-       .y_res          = LCD_YRES,
-       .hsw            = 3,            /* hsync_len (4) - 1 */
-       .hfp            = 3,            /* right_margin (4) - 1 */
-       .hbp            = 39,           /* left_margin (40) - 1 */
-       .vsw            = 1,            /* vsync_len (2) - 1 */
-       .vfp            = 2,            /* lower_margin */
-       .vbp            = 7,            /* upper_margin (8) - 1 */
-
-       .pixel_clock    = LCD_PIXCLOCK_MAX,
-
-       .init           = ldp_panel_init,
-       .cleanup        = ldp_panel_cleanup,
-       .enable         = ldp_panel_enable,
-       .disable        = ldp_panel_disable,
-       .get_caps       = ldp_panel_get_caps,
-};
-
-static int ldp_panel_probe(struct platform_device *pdev)
-{
-       omapfb_register_panel(&ldp_panel);
-       return 0;
-}
-
-static int ldp_panel_remove(struct platform_device *pdev)
-{
-       return 0;
-}
-
-static int ldp_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
-       return 0;
-}
-
-static int ldp_panel_resume(struct platform_device *pdev)
-{
-       return 0;
-}
-
-struct platform_driver ldp_panel_driver = {
-       .probe          = ldp_panel_probe,
-       .remove         = ldp_panel_remove,
-       .suspend        = ldp_panel_suspend,
-       .resume         = ldp_panel_resume,
-       .driver         = {
-               .name   = "ldp_lcd",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int __init ldp_panel_drv_init(void)
-{
-       return platform_driver_register(&ldp_panel_driver);
-}
-
-static void __exit ldp_panel_drv_exit(void)
-{
-       platform_driver_unregister(&ldp_panel_driver);
-}
-
-module_init(ldp_panel_drv_init);
-module_exit(ldp_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
deleted file mode 100644 (file)
index d7c6c3e..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * LCD panel support for the TI OMAP3 Beagle board
- *
- * Author: Koen Kooi <koen@openembedded.org>
- *
- * Derived from drivers/video/omap/lcd-omap3evm.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/i2c/twl.h>
-
-#include <asm/mach-types.h>
-
-#include "omapfb.h"
-
-#define LCD_PANEL_ENABLE_GPIO       170
-
-static int omap3beagle_panel_init(struct lcd_panel *panel,
-                               struct omapfb_device *fbdev)
-{
-       gpio_request(LCD_PANEL_ENABLE_GPIO, "LCD enable");
-       return 0;
-}
-
-static void omap3beagle_panel_cleanup(struct lcd_panel *panel)
-{
-       gpio_free(LCD_PANEL_ENABLE_GPIO);
-}
-
-static int omap3beagle_panel_enable(struct lcd_panel *panel)
-{
-       gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
-       return 0;
-}
-
-static void omap3beagle_panel_disable(struct lcd_panel *panel)
-{
-       gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
-}
-
-static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel)
-{
-       return 0;
-}
-
-struct lcd_panel omap3beagle_panel = {
-       .name           = "omap3beagle",
-       .config         = OMAP_LCDC_PANEL_TFT,
-
-       .bpp            = 16,
-       .data_lines     = 24,
-       .x_res          = 1024,
-       .y_res          = 768,
-       .hsw            = 3,            /* hsync_len (4) - 1 */
-       .hfp            = 3,            /* right_margin (4) - 1 */
-       .hbp            = 39,           /* left_margin (40) - 1 */
-       .vsw            = 1,            /* vsync_len (2) - 1 */
-       .vfp            = 2,            /* lower_margin */
-       .vbp            = 7,            /* upper_margin (8) - 1 */
-
-       .pixel_clock    = 64000,
-
-       .init           = omap3beagle_panel_init,
-       .cleanup        = omap3beagle_panel_cleanup,
-       .enable         = omap3beagle_panel_enable,
-       .disable        = omap3beagle_panel_disable,
-       .get_caps       = omap3beagle_panel_get_caps,
-};
-
-static int omap3beagle_panel_probe(struct platform_device *pdev)
-{
-       omapfb_register_panel(&omap3beagle_panel);
-       return 0;
-}
-
-static int omap3beagle_panel_remove(struct platform_device *pdev)
-{
-       return 0;
-}
-
-static int omap3beagle_panel_suspend(struct platform_device *pdev,
-                                  pm_message_t mesg)
-{
-       return 0;
-}
-
-static int omap3beagle_panel_resume(struct platform_device *pdev)
-{
-       return 0;
-}
-
-struct platform_driver omap3beagle_panel_driver = {
-       .probe          = omap3beagle_panel_probe,
-       .remove         = omap3beagle_panel_remove,
-       .suspend        = omap3beagle_panel_suspend,
-       .resume         = omap3beagle_panel_resume,
-       .driver         = {
-               .name   = "omap3beagle_lcd",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int __init omap3beagle_panel_drv_init(void)
-{
-       return platform_driver_register(&omap3beagle_panel_driver);
-}
-
-static void __exit omap3beagle_panel_drv_exit(void)
-{
-       platform_driver_unregister(&omap3beagle_panel_driver);
-}
-
-module_init(omap3beagle_panel_drv_init);
-module_exit(omap3beagle_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_omap3evm.c b/drivers/video/omap/lcd_omap3evm.c
deleted file mode 100644 (file)
index 06840da..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * LCD panel support for the TI OMAP3 EVM board
- *
- * Author: Steve Sakoman <steve@sakoman.com>
- *
- * Derived from drivers/video/omap/lcd-apollon.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/i2c/twl.h>
-
-#include <plat/mux.h>
-#include <asm/mach-types.h>
-
-#include "omapfb.h"
-
-#define LCD_PANEL_ENABLE_GPIO       153
-#define LCD_PANEL_LR                2
-#define LCD_PANEL_UD                3
-#define LCD_PANEL_INI               152
-#define LCD_PANEL_QVGA              154
-#define LCD_PANEL_RESB              155
-
-#define ENABLE_VDAC_DEDICATED  0x03
-#define ENABLE_VDAC_DEV_GRP    0x20
-#define ENABLE_VPLL2_DEDICATED 0x05
-#define ENABLE_VPLL2_DEV_GRP   0xE0
-
-#define TWL_LED_LEDEN          0x00
-#define TWL_PWMA_PWMAON                0x00
-#define TWL_PWMA_PWMAOFF       0x01
-
-static unsigned int bklight_level;
-
-static int omap3evm_panel_init(struct lcd_panel *panel,
-                               struct omapfb_device *fbdev)
-{
-       gpio_request(LCD_PANEL_LR, "LCD lr");
-       gpio_request(LCD_PANEL_UD, "LCD ud");
-       gpio_request(LCD_PANEL_INI, "LCD ini");
-       gpio_request(LCD_PANEL_RESB, "LCD resb");
-       gpio_request(LCD_PANEL_QVGA, "LCD qvga");
-
-       gpio_direction_output(LCD_PANEL_RESB, 1);
-       gpio_direction_output(LCD_PANEL_INI, 1);
-       gpio_direction_output(LCD_PANEL_QVGA, 0);
-       gpio_direction_output(LCD_PANEL_LR, 1);
-       gpio_direction_output(LCD_PANEL_UD, 1);
-
-       twl_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN);
-       twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON);
-       twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF);
-       bklight_level = 100;
-
-       return 0;
-}
-
-static void omap3evm_panel_cleanup(struct lcd_panel *panel)
-{
-       gpio_free(LCD_PANEL_QVGA);
-       gpio_free(LCD_PANEL_RESB);
-       gpio_free(LCD_PANEL_INI);
-       gpio_free(LCD_PANEL_UD);
-       gpio_free(LCD_PANEL_LR);
-}
-
-static int omap3evm_panel_enable(struct lcd_panel *panel)
-{
-       gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
-       return 0;
-}
-
-static void omap3evm_panel_disable(struct lcd_panel *panel)
-{
-       gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
-}
-
-static unsigned long omap3evm_panel_get_caps(struct lcd_panel *panel)
-{
-       return 0;
-}
-
-static int omap3evm_bklight_setlevel(struct lcd_panel *panel,
-                                               unsigned int level)
-{
-       u8 c;
-       if ((level >= 0) && (level <= 100)) {
-               c = (125 * (100 - level)) / 100 + 2;
-               twl_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF);
-               bklight_level = level;
-       }
-       return 0;
-}
-
-static unsigned int omap3evm_bklight_getlevel(struct lcd_panel *panel)
-{
-       return bklight_level;
-}
-
-static unsigned int omap3evm_bklight_getmaxlevel(struct lcd_panel *panel)
-{
-       return 100;
-}
-
-struct lcd_panel omap3evm_panel = {
-       .name           = "omap3evm",
-       .config         = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
-                         OMAP_LCDC_INV_HSYNC,
-
-       .bpp            = 16,
-       .data_lines     = 18,
-       .x_res          = 480,
-       .y_res          = 640,
-       .hsw            = 3,            /* hsync_len (4) - 1 */
-       .hfp            = 3,            /* right_margin (4) - 1 */
-       .hbp            = 39,           /* left_margin (40) - 1 */
-       .vsw            = 1,            /* vsync_len (2) - 1 */
-       .vfp            = 2,            /* lower_margin */
-       .vbp            = 7,            /* upper_margin (8) - 1 */
-
-       .pixel_clock    = 26000,
-
-       .init           = omap3evm_panel_init,
-       .cleanup        = omap3evm_panel_cleanup,
-       .enable         = omap3evm_panel_enable,
-       .disable        = omap3evm_panel_disable,
-       .get_caps       = omap3evm_panel_get_caps,
-       .set_bklight_level      = omap3evm_bklight_setlevel,
-       .get_bklight_level      = omap3evm_bklight_getlevel,
-       .get_bklight_max        = omap3evm_bklight_getmaxlevel,
-};
-
-static int omap3evm_panel_probe(struct platform_device *pdev)
-{
-       omapfb_register_panel(&omap3evm_panel);
-       return 0;
-}
-
-static int omap3evm_panel_remove(struct platform_device *pdev)
-{
-       return 0;
-}
-
-static int omap3evm_panel_suspend(struct platform_device *pdev,
-                                  pm_message_t mesg)
-{
-       return 0;
-}
-
-static int omap3evm_panel_resume(struct platform_device *pdev)
-{
-       return 0;
-}
-
-struct platform_driver omap3evm_panel_driver = {
-       .probe          = omap3evm_panel_probe,
-       .remove         = omap3evm_panel_remove,
-       .suspend        = omap3evm_panel_suspend,
-       .resume         = omap3evm_panel_resume,
-       .driver         = {
-               .name   = "omap3evm_lcd",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int __init omap3evm_panel_drv_init(void)
-{
-       return platform_driver_register(&omap3evm_panel_driver);
-}
-
-static void __exit omap3evm_panel_drv_exit(void)
-{
-       platform_driver_unregister(&omap3evm_panel_driver);
-}
-
-module_init(omap3evm_panel_drv_init);
-module_exit(omap3evm_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_overo.c b/drivers/video/omap/lcd_overo.c
deleted file mode 100644 (file)
index 564933f..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * LCD panel support for the Gumstix Overo
- *
- * Author: Steve Sakoman <steve@sakoman.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/i2c/twl.h>
-
-#include <mach/gpio.h>
-#include <plat/mux.h>
-#include <asm/mach-types.h>
-
-#include "omapfb.h"
-
-#define LCD_ENABLE       144
-
-static int overo_panel_init(struct lcd_panel *panel,
-                               struct omapfb_device *fbdev)
-{
-       if ((gpio_request(LCD_ENABLE, "LCD_ENABLE") == 0) &&
-           (gpio_direction_output(LCD_ENABLE, 1) == 0))
-               gpio_export(LCD_ENABLE, 0);
-       else
-               printk(KERN_ERR "could not obtain gpio for LCD_ENABLE\n");
-
-       return 0;
-}
-
-static void overo_panel_cleanup(struct lcd_panel *panel)
-{
-       gpio_free(LCD_ENABLE);
-}
-
-static int overo_panel_enable(struct lcd_panel *panel)
-{
-       gpio_set_value(LCD_ENABLE, 1);
-       return 0;
-}
-
-static void overo_panel_disable(struct lcd_panel *panel)
-{
-       gpio_set_value(LCD_ENABLE, 0);
-}
-
-static unsigned long overo_panel_get_caps(struct lcd_panel *panel)
-{
-       return 0;
-}
-
-struct lcd_panel overo_panel = {
-       .name           = "overo",
-       .config         = OMAP_LCDC_PANEL_TFT,
-       .bpp            = 16,
-       .data_lines     = 24,
-
-#if defined CONFIG_FB_OMAP_031M3R
-
-       /* 640 x 480 @ 60 Hz  Reduced blanking VESA CVT 0.31M3-R */
-       .x_res          = 640,
-       .y_res          = 480,
-       .hfp            = 48,
-       .hsw            = 32,
-       .hbp            = 80,
-       .vfp            = 3,
-       .vsw            = 4,
-       .vbp            = 7,
-       .pixel_clock    = 23500,
-
-#elif defined CONFIG_FB_OMAP_048M3R
-
-       /* 800 x 600 @ 60 Hz  Reduced blanking VESA CVT 0.48M3-R */
-       .x_res          = 800,
-       .y_res          = 600,
-       .hfp            = 48,
-       .hsw            = 32,
-       .hbp            = 80,
-       .vfp            = 3,
-       .vsw            = 4,
-       .vbp            = 11,
-       .pixel_clock    = 35500,
-
-#elif defined CONFIG_FB_OMAP_079M3R
-
-       /* 1024 x 768 @ 60 Hz  Reduced blanking VESA CVT 0.79M3-R */
-       .x_res          = 1024,
-       .y_res          = 768,
-       .hfp            = 48,
-       .hsw            = 32,
-       .hbp            = 80,
-       .vfp            = 3,
-       .vsw            = 4,
-       .vbp            = 15,
-       .pixel_clock    = 56000,
-
-#elif defined CONFIG_FB_OMAP_092M9R
-
-       /* 1280 x 720 @ 60 Hz  Reduced blanking VESA CVT 0.92M9-R */
-       .x_res          = 1280,
-       .y_res          = 720,
-       .hfp            = 48,
-       .hsw            = 32,
-       .hbp            = 80,
-       .vfp            = 3,
-       .vsw            = 5,
-       .vbp            = 13,
-       .pixel_clock    = 64000,
-
-#else
-
-       /* use 640 x 480 if no config option */
-       /* 640 x 480 @ 60 Hz  Reduced blanking VESA CVT 0.31M3-R */
-       .x_res          = 640,
-       .y_res          = 480,
-       .hfp            = 48,
-       .hsw            = 32,
-       .hbp            = 80,
-       .vfp            = 3,
-       .vsw            = 4,
-       .vbp            = 7,
-       .pixel_clock    = 23500,
-
-#endif
-
-       .init           = overo_panel_init,
-       .cleanup        = overo_panel_cleanup,
-       .enable         = overo_panel_enable,
-       .disable        = overo_panel_disable,
-       .get_caps       = overo_panel_get_caps,
-};
-
-static int overo_panel_probe(struct platform_device *pdev)
-{
-       omapfb_register_panel(&overo_panel);
-       return 0;
-}
-
-static int overo_panel_remove(struct platform_device *pdev)
-{
-       /* omapfb does not have unregister_panel */
-       return 0;
-}
-
-static struct platform_driver overo_panel_driver = {
-       .probe          = overo_panel_probe,
-       .remove         = overo_panel_remove,
-       .driver         = {
-               .name   = "overo_lcd",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int __init overo_panel_drv_init(void)
-{
-       return platform_driver_register(&overo_panel_driver);
-}
-
-static void __exit overo_panel_drv_exit(void)
-{
-       platform_driver_unregister(&overo_panel_driver);
-}
-
-module_init(overo_panel_drv_init);
-module_exit(overo_panel_drv_exit);
index 609a280..8d8e1fe 100644 (file)
@@ -10,6 +10,13 @@ config PANEL_GENERIC_DPI
          Supports LCD Panel used in TI SDP3430 and EVM boards,
          OMAP3517 EVM boards and CM-T35.
 
+config PANEL_DVI
+       tristate "DVI output"
+       depends on OMAP2_DSS_DPI
+       help
+         Driver for external monitors, connected via DVI. The driver uses i2c
+         to read EDID information from the monitor.
+
 config PANEL_LGPHILIPS_LB035Q02
        tristate "LG.Philips LB035Q02 LCD Panel"
        depends on OMAP2_DSS_DPI && SPI
@@ -19,20 +26,30 @@ config PANEL_LGPHILIPS_LB035Q02
 config PANEL_SHARP_LS037V7DW01
         tristate "Sharp LS037V7DW01 LCD Panel"
         depends on OMAP2_DSS_DPI
-        select BACKLIGHT_CLASS_DEVICE
+        depends on BACKLIGHT_CLASS_DEVICE
         help
           LCD Panel used in TI's SDP3430 and EVM boards
 
 config PANEL_NEC_NL8048HL11_01B
        tristate "NEC NL8048HL11-01B Panel"
        depends on OMAP2_DSS_DPI
+       depends on SPI
+       depends on BACKLIGHT_CLASS_DEVICE
        help
                This NEC NL8048HL11-01B panel is TFT LCD
                used in the Zoom2/3/3630 sdp boards.
 
+config PANEL_PICODLP
+       tristate "TI PICO DLP mini-projector"
+       depends on OMAP2_DSS && I2C
+       help
+               A mini-projector used in TI's SDP4430 and EVM boards
+               For more info please visit http://www.dlp.com/projector/
+
 config PANEL_TAAL
         tristate "Taal DSI Panel"
         depends on OMAP2_DSS_DSI
+        depends on BACKLIGHT_CLASS_DEVICE
         help
           Taal DSI command mode panel from TPO.
 
@@ -45,7 +62,14 @@ config PANEL_TPO_TD043MTEA1
 config PANEL_ACX565AKM
        tristate "ACX565AKM Panel"
        depends on OMAP2_DSS_SDI && SPI
-       select BACKLIGHT_CLASS_DEVICE
+       depends on BACKLIGHT_CLASS_DEVICE
        help
          This is the LCD panel used on Nokia N900
+
+config PANEL_N8X0
+       tristate "N8X0 Panel"
+       depends on OMAP2_DSS_RFBI && SPI
+       depends on BACKLIGHT_CLASS_DEVICE
+       help
+         This is the LCD panel used on Nokia N8x0
 endmenu
index 0f601ab..fbfafc6 100644 (file)
@@ -1,8 +1,11 @@
 obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o
+obj-$(CONFIG_PANEL_DVI) += panel-dvi.o
 obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
 obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
 obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
 
 obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
+obj-$(CONFIG_PANEL_PICODLP) +=  panel-picodlp.o
 obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
 obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o
+obj-$(CONFIG_PANEL_N8X0) += panel-n8x0.o
diff --git a/drivers/video/omap2/displays/panel-dvi.c b/drivers/video/omap2/displays/panel-dvi.c
new file mode 100644 (file)
index 0000000..03eb14a
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * DVI output support
+ *
+ * Copyright (C) 2011 Texas Instruments Inc
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <video/omapdss.h>
+#include <linux/i2c.h>
+#include <drm/drm_edid.h>
+
+#include <video/omap-panel-dvi.h>
+
+static const struct omap_video_timings panel_dvi_default_timings = {
+       .x_res          = 640,
+       .y_res          = 480,
+
+       .pixel_clock    = 23500,
+
+       .hfp            = 48,
+       .hsw            = 32,
+       .hbp            = 80,
+
+       .vfp            = 3,
+       .vsw            = 4,
+       .vbp            = 7,
+};
+
+struct panel_drv_data {
+       struct omap_dss_device *dssdev;
+
+       struct mutex lock;
+};
+
+static inline struct panel_dvi_platform_data
+*get_pdata(const struct omap_dss_device *dssdev)
+{
+       return dssdev->data;
+}
+
+static int panel_dvi_power_on(struct omap_dss_device *dssdev)
+{
+       struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
+       int r;
+
+       if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+               return 0;
+
+       r = omapdss_dpi_display_enable(dssdev);
+       if (r)
+               goto err0;
+
+       if (pdata->platform_enable) {
+               r = pdata->platform_enable(dssdev);
+               if (r)
+                       goto err1;
+       }
+
+       return 0;
+err1:
+       omapdss_dpi_display_disable(dssdev);
+err0:
+       return r;
+}
+
+static void panel_dvi_power_off(struct omap_dss_device *dssdev)
+{
+       struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
+
+       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+               return;
+
+       if (pdata->platform_disable)
+               pdata->platform_disable(dssdev);
+
+       omapdss_dpi_display_disable(dssdev);
+}
+
+static int panel_dvi_probe(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata;
+
+       ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
+       if (!ddata)
+               return -ENOMEM;
+
+       dssdev->panel.timings = panel_dvi_default_timings;
+       dssdev->panel.config = OMAP_DSS_LCD_TFT;
+
+       ddata->dssdev = dssdev;
+       mutex_init(&ddata->lock);
+
+       dev_set_drvdata(&dssdev->dev, ddata);
+
+       return 0;
+}
+
+static void __exit panel_dvi_remove(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+
+       mutex_lock(&ddata->lock);
+
+       dev_set_drvdata(&dssdev->dev, NULL);
+
+       mutex_unlock(&ddata->lock);
+
+       kfree(ddata);
+}
+
+static int panel_dvi_enable(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+       int r;
+
+       mutex_lock(&ddata->lock);
+
+       r = panel_dvi_power_on(dssdev);
+       if (r == 0)
+               dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+       mutex_unlock(&ddata->lock);
+
+       return r;
+}
+
+static void panel_dvi_disable(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+
+       mutex_lock(&ddata->lock);
+
+       panel_dvi_power_off(dssdev);
+
+       dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+       mutex_unlock(&ddata->lock);
+}
+
+static int panel_dvi_suspend(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+
+       mutex_lock(&ddata->lock);
+
+       panel_dvi_power_off(dssdev);
+
+       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+
+       mutex_unlock(&ddata->lock);
+
+       return 0;
+}
+
+static int panel_dvi_resume(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+       int r;
+
+       mutex_lock(&ddata->lock);
+
+       r = panel_dvi_power_on(dssdev);
+       if (r == 0)
+               dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+       mutex_unlock(&ddata->lock);
+
+       return r;
+}
+
+static void panel_dvi_set_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+
+       mutex_lock(&ddata->lock);
+       dpi_set_timings(dssdev, timings);
+       mutex_unlock(&ddata->lock);
+}
+
+static void panel_dvi_get_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+
+       mutex_lock(&ddata->lock);
+       *timings = dssdev->panel.timings;
+       mutex_unlock(&ddata->lock);
+}
+
+static int panel_dvi_check_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+       int r;
+
+       mutex_lock(&ddata->lock);
+       r = dpi_check_timings(dssdev, timings);
+       mutex_unlock(&ddata->lock);
+
+       return r;
+}
+
+
+static int panel_dvi_ddc_read(struct i2c_adapter *adapter,
+               unsigned char *buf, u16 count, u8 offset)
+{
+       int r, retries;
+
+       for (retries = 3; retries > 0; retries--) {
+               struct i2c_msg msgs[] = {
+                       {
+                               .addr   = DDC_ADDR,
+                               .flags  = 0,
+                               .len    = 1,
+                               .buf    = &offset,
+                       }, {
+                               .addr   = DDC_ADDR,
+                               .flags  = I2C_M_RD,
+                               .len    = count,
+                               .buf    = buf,
+                       }
+               };
+
+               r = i2c_transfer(adapter, msgs, 2);
+               if (r == 2)
+                       return 0;
+
+               if (r != -EAGAIN)
+                       break;
+       }
+
+       return r < 0 ? r : -EIO;
+}
+
+static int panel_dvi_read_edid(struct omap_dss_device *dssdev,
+               u8 *edid, int len)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+       struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
+       struct i2c_adapter *adapter;
+       int r, l, bytes_read;
+
+       mutex_lock(&ddata->lock);
+
+       if (pdata->i2c_bus_num == 0) {
+               r = -ENODEV;
+               goto err;
+       }
+
+       adapter = i2c_get_adapter(pdata->i2c_bus_num);
+       if (!adapter) {
+               dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
+                               pdata->i2c_bus_num);
+               r = -EINVAL;
+               goto err;
+       }
+
+       l = min(EDID_LENGTH, len);
+       r = panel_dvi_ddc_read(adapter, edid, l, 0);
+       if (r)
+               goto err;
+
+       bytes_read = l;
+
+       /* if there are extensions, read second block */
+       if (len > EDID_LENGTH && edid[0x7e] > 0) {
+               l = min(EDID_LENGTH, len - EDID_LENGTH);
+
+               r = panel_dvi_ddc_read(adapter, edid + EDID_LENGTH,
+                               l, EDID_LENGTH);
+               if (r)
+                       goto err;
+
+               bytes_read += l;
+       }
+
+       mutex_unlock(&ddata->lock);
+
+       return bytes_read;
+
+err:
+       mutex_unlock(&ddata->lock);
+       return r;
+}
+
+static bool panel_dvi_detect(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+       struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
+       struct i2c_adapter *adapter;
+       unsigned char out;
+       int r;
+
+       mutex_lock(&ddata->lock);
+
+       if (pdata->i2c_bus_num == 0)
+               goto out;
+
+       adapter = i2c_get_adapter(pdata->i2c_bus_num);
+       if (!adapter)
+               goto out;
+
+       r = panel_dvi_ddc_read(adapter, &out, 1, 0);
+
+       mutex_unlock(&ddata->lock);
+
+       return r == 0;
+
+out:
+       mutex_unlock(&ddata->lock);
+       return true;
+}
+
+static struct omap_dss_driver panel_dvi_driver = {
+       .probe          = panel_dvi_probe,
+       .remove         = __exit_p(panel_dvi_remove),
+
+       .enable         = panel_dvi_enable,
+       .disable        = panel_dvi_disable,
+       .suspend        = panel_dvi_suspend,
+       .resume         = panel_dvi_resume,
+
+       .set_timings    = panel_dvi_set_timings,
+       .get_timings    = panel_dvi_get_timings,
+       .check_timings  = panel_dvi_check_timings,
+
+       .read_edid      = panel_dvi_read_edid,
+       .detect         = panel_dvi_detect,
+
+       .driver         = {
+               .name   = "dvi",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init panel_dvi_init(void)
+{
+       return omap_dss_register_driver(&panel_dvi_driver);
+}
+
+static void __exit panel_dvi_exit(void)
+{
+       omap_dss_unregister_driver(&panel_dvi_driver);
+}
+
+module_init(panel_dvi_init);
+module_exit(panel_dvi_exit);
+MODULE_LICENSE("GPL");
index 9c90f75..519c47d 100644 (file)
@@ -58,30 +58,6 @@ struct panel_config {
 
 /* Panel configurations */
 static struct panel_config generic_dpi_panels[] = {
-       /* Generic Panel */
-       {
-               {
-                       .x_res          = 640,
-                       .y_res          = 480,
-
-                       .pixel_clock    = 23500,
-
-                       .hfp            = 48,
-                       .hsw            = 32,
-                       .hbp            = 80,
-
-                       .vfp            = 3,
-                       .vsw            = 4,
-                       .vbp            = 7,
-               },
-               .acbi                   = 0x0,
-               .acb                    = 0x0,
-               .config                 = OMAP_DSS_LCD_TFT,
-               .power_on_delay         = 0,
-               .power_off_delay        = 0,
-               .name                   = "generic",
-       },
-
        /* Sharp LQ043T1DG01 */
        {
                {
@@ -232,6 +208,95 @@ static struct panel_config generic_dpi_panels[] = {
                .power_off_delay        = 0,
                .name                   = "powertip_ph480272t",
        },
+
+       /* Innolux AT070TN83 */
+       {
+               {
+                       .x_res          = 800,
+                       .y_res          = 480,
+
+                       .pixel_clock    = 40000,
+
+                       .hsw            = 48,
+                       .hfp            = 1,
+                       .hbp            = 1,
+
+                       .vsw            = 3,
+                       .vfp            = 12,
+                       .vbp            = 25,
+               },
+               .acbi                   = 0x0,
+               .acb                    = 0x28,
+               .config                 = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+                                         OMAP_DSS_LCD_IHS,
+               .power_on_delay         = 0,
+               .power_off_delay        = 0,
+               .name                   = "innolux_at070tn83",
+       },
+
+       /* NEC NL2432DR22-11B */
+       {
+               {
+                       .x_res          = 240,
+                       .y_res          = 320,
+
+                       .pixel_clock    = 5400,
+
+                       .hsw            = 3,
+                       .hfp            = 3,
+                       .hbp            = 39,
+
+                       .vsw            = 1,
+                       .vfp            = 2,
+                       .vbp            = 7,
+               },
+               .config                 = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+                                               OMAP_DSS_LCD_IHS,
+               .name                   = "nec_nl2432dr22-11b",
+       },
+
+       /* Unknown panel used in OMAP H4 */
+       {
+               {
+                       .x_res          = 240,
+                       .y_res          = 320,
+
+                       .pixel_clock    = 6250,
+
+                       .hsw            = 15,
+                       .hfp            = 15,
+                       .hbp            = 60,
+
+                       .vsw            = 1,
+                       .vfp            = 1,
+                       .vbp            = 1,
+               },
+               .config                 = OMAP_DSS_LCD_TFT,
+
+               .name                   = "h4",
+       },
+
+       /* Unknown panel used in Samsung OMAP2 Apollon */
+       {
+               {
+                       .x_res          = 480,
+                       .y_res          = 272,
+
+                       .pixel_clock    = 6250,
+
+                       .hsw            = 41,
+                       .hfp            = 2,
+                       .hbp            = 2,
+
+                       .vsw            = 10,
+                       .vfp            = 2,
+                       .vbp            = 2,
+               },
+               .config                 = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+                                               OMAP_DSS_LCD_IHS,
+
+               .name                   = "apollon",
+       },
 };
 
 struct panel_drv_data {
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
new file mode 100644 (file)
index 0000000..150e8ba
--- /dev/null
@@ -0,0 +1,747 @@
+/* #define DEBUG */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/backlight.h>
+#include <linux/fb.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-n8x0.h>
+
+#define BLIZZARD_REV_CODE                      0x00
+#define BLIZZARD_CONFIG                        0x02
+#define BLIZZARD_PLL_DIV                       0x04
+#define BLIZZARD_PLL_LOCK_RANGE                0x06
+#define BLIZZARD_PLL_CLOCK_SYNTH_0             0x08
+#define BLIZZARD_PLL_CLOCK_SYNTH_1             0x0a
+#define BLIZZARD_PLL_MODE                      0x0c
+#define BLIZZARD_CLK_SRC                       0x0e
+#define BLIZZARD_MEM_BANK0_ACTIVATE            0x10
+#define BLIZZARD_MEM_BANK0_STATUS              0x14
+#define BLIZZARD_PANEL_CONFIGURATION           0x28
+#define BLIZZARD_HDISP                         0x2a
+#define BLIZZARD_HNDP                          0x2c
+#define BLIZZARD_VDISP0                        0x2e
+#define BLIZZARD_VDISP1                        0x30
+#define BLIZZARD_VNDP                          0x32
+#define BLIZZARD_HSW                           0x34
+#define BLIZZARD_VSW                           0x38
+#define BLIZZARD_DISPLAY_MODE                  0x68
+#define BLIZZARD_INPUT_WIN_X_START_0           0x6c
+#define BLIZZARD_DATA_SOURCE_SELECT            0x8e
+#define BLIZZARD_DISP_MEM_DATA_PORT            0x90
+#define BLIZZARD_DISP_MEM_READ_ADDR0           0x92
+#define BLIZZARD_POWER_SAVE                    0xE6
+#define BLIZZARD_NDISP_CTRL_STATUS             0xE8
+
+/* Data source select */
+/* For S1D13745 */
+#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND      0x00
+#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE     0x01
+#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE      0x04
+#define BLIZZARD_SRC_DISABLE_OVERLAY           0x05
+/* For S1D13744 */
+#define BLIZZARD_SRC_WRITE_LCD                 0x00
+#define BLIZZARD_SRC_BLT_LCD                   0x06
+
+#define BLIZZARD_COLOR_RGB565                  0x01
+#define BLIZZARD_COLOR_YUV420                  0x09
+
+#define BLIZZARD_VERSION_S1D13745              0x01    /* Hailstorm */
+#define BLIZZARD_VERSION_S1D13744              0x02    /* Blizzard */
+
+#define MIPID_CMD_READ_DISP_ID         0x04
+#define MIPID_CMD_READ_RED             0x06
+#define MIPID_CMD_READ_GREEN           0x07
+#define MIPID_CMD_READ_BLUE            0x08
+#define MIPID_CMD_READ_DISP_STATUS     0x09
+#define MIPID_CMD_RDDSDR               0x0F
+#define MIPID_CMD_SLEEP_IN             0x10
+#define MIPID_CMD_SLEEP_OUT            0x11
+#define MIPID_CMD_DISP_OFF             0x28
+#define MIPID_CMD_DISP_ON              0x29
+
+static struct panel_drv_data {
+       struct mutex lock;
+
+       struct omap_dss_device *dssdev;
+       struct spi_device *spidev;
+       struct backlight_device *bldev;
+
+       int blizzard_ver;
+} s_drv_data;
+
+
+static inline
+struct panel_n8x0_data *get_board_data(const struct omap_dss_device *dssdev)
+{
+       return dssdev->data;
+}
+
+static inline
+struct panel_drv_data *get_drv_data(const struct omap_dss_device *dssdev)
+{
+       return &s_drv_data;
+}
+
+
+static inline void blizzard_cmd(u8 cmd)
+{
+       omap_rfbi_write_command(&cmd, 1);
+}
+
+static inline void blizzard_write(u8 cmd, const u8 *buf, int len)
+{
+       omap_rfbi_write_command(&cmd, 1);
+       omap_rfbi_write_data(buf, len);
+}
+
+static inline void blizzard_read(u8 cmd, u8 *buf, int len)
+{
+       omap_rfbi_write_command(&cmd, 1);
+       omap_rfbi_read_data(buf, len);
+}
+
+static u8 blizzard_read_reg(u8 cmd)
+{
+       u8 data;
+       blizzard_read(cmd, &data, 1);
+       return data;
+}
+
+static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
+               int x, int y, int w, int h)
+{
+       struct panel_drv_data *ddata = get_drv_data(dssdev);
+       u8 tmp[18];
+       int x_end, y_end;
+
+       x_end = x + w - 1;
+       y_end = y + h - 1;
+
+       tmp[0] = x;
+       tmp[1] = x >> 8;
+       tmp[2] = y;
+       tmp[3] = y >> 8;
+       tmp[4] = x_end;
+       tmp[5] = x_end >> 8;
+       tmp[6] = y_end;
+       tmp[7] = y_end >> 8;
+
+       /* scaling? */
+       tmp[8] = x;
+       tmp[9] = x >> 8;
+       tmp[10] = y;
+       tmp[11] = y >> 8;
+       tmp[12] = x_end;
+       tmp[13] = x_end >> 8;
+       tmp[14] = y_end;
+       tmp[15] = y_end >> 8;
+
+       tmp[16] = BLIZZARD_COLOR_RGB565;
+
+       if (ddata->blizzard_ver == BLIZZARD_VERSION_S1D13745)
+               tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
+       else
+               tmp[17] = ddata->blizzard_ver == BLIZZARD_VERSION_S1D13744 ?
+                       BLIZZARD_SRC_WRITE_LCD :
+                       BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
+
+       omap_rfbi_configure(dssdev, 16, 8);
+
+       blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
+
+       omap_rfbi_configure(dssdev, 16, 16);
+}
+
+static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
+               int wlen, u8 *rbuf, int rlen)
+{
+       struct spi_message      m;
+       struct spi_transfer     *x, xfer[4];
+       u16                     w;
+       int                     r;
+
+       spi_message_init(&m);
+
+       memset(xfer, 0, sizeof(xfer));
+       x = &xfer[0];
+
+       cmd &=  0xff;
+       x->tx_buf               = &cmd;
+       x->bits_per_word        = 9;
+       x->len                  = 2;
+       spi_message_add_tail(x, &m);
+
+       if (wlen) {
+               x++;
+               x->tx_buf               = wbuf;
+               x->len                  = wlen;
+               x->bits_per_word        = 9;
+               spi_message_add_tail(x, &m);
+       }
+
+       if (rlen) {
+               x++;
+               x->rx_buf       = &w;
+               x->len          = 1;
+               spi_message_add_tail(x, &m);
+
+               if (rlen > 1) {
+                       /* Arrange for the extra clock before the first
+                        * data bit.
+                        */
+                       x->bits_per_word = 9;
+                       x->len           = 2;
+
+                       x++;
+                       x->rx_buf        = &rbuf[1];
+                       x->len           = rlen - 1;
+                       spi_message_add_tail(x, &m);
+               }
+       }
+
+       r = spi_sync(spi, &m);
+       if (r < 0)
+               dev_dbg(&spi->dev, "spi_sync %d\n", r);
+
+       if (rlen)
+               rbuf[0] = w & 0xff;
+}
+
+static inline void mipid_cmd(struct spi_device *spi, int cmd)
+{
+       mipid_transfer(spi, cmd, NULL, 0, NULL, 0);
+}
+
+static inline void mipid_write(struct spi_device *spi,
+               int reg, const u8 *buf, int len)
+{
+       mipid_transfer(spi, reg, buf, len, NULL, 0);
+}
+
+static inline void mipid_read(struct spi_device *spi,
+               int reg, u8 *buf, int len)
+{
+       mipid_transfer(spi, reg, NULL, 0, buf, len);
+}
+
+static void set_data_lines(struct spi_device *spi, int data_lines)
+{
+       u16 par;
+
+       switch (data_lines) {
+       case 16:
+               par = 0x150;
+               break;
+       case 18:
+               par = 0x160;
+               break;
+       case 24:
+               par = 0x170;
+               break;
+       }
+
+       mipid_write(spi, 0x3a, (u8 *)&par, 2);
+}
+
+static void send_init_string(struct spi_device *spi)
+{
+       u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
+       mipid_write(spi, 0xc2, (u8 *)initpar, sizeof(initpar));
+}
+
+static void send_display_on(struct spi_device *spi)
+{
+       mipid_cmd(spi, MIPID_CMD_DISP_ON);
+}
+
+static void send_display_off(struct spi_device *spi)
+{
+       mipid_cmd(spi, MIPID_CMD_DISP_OFF);
+}
+
+static void send_sleep_out(struct spi_device *spi)
+{
+       mipid_cmd(spi, MIPID_CMD_SLEEP_OUT);
+       msleep(120);
+}
+
+static void send_sleep_in(struct spi_device *spi)
+{
+       mipid_cmd(spi, MIPID_CMD_SLEEP_IN);
+       msleep(50);
+}
+
+static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
+{
+       int r;
+       struct panel_n8x0_data *bdata = get_board_data(dssdev);
+       struct panel_drv_data *ddata = get_drv_data(dssdev);
+       struct spi_device *spi = ddata->spidev;
+       u8 rev, conf;
+       u8 display_id[3];
+       const char *panel_name;
+
+       if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+               return 0;
+
+       gpio_direction_output(bdata->ctrl_pwrdown, 1);
+
+       if (bdata->platform_enable) {
+               r = bdata->platform_enable(dssdev);
+               if (r)
+                       goto err_plat_en;
+       }
+
+       r = omapdss_rfbi_display_enable(dssdev);
+       if (r)
+               goto err_rfbi_en;
+
+       rev = blizzard_read_reg(BLIZZARD_REV_CODE);
+       conf = blizzard_read_reg(BLIZZARD_CONFIG);
+
+       switch (rev & 0xfc) {
+       case 0x9c:
+               ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744;
+               dev_info(&dssdev->dev, "s1d13744 LCD controller rev %d "
+                       "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
+               break;
+       case 0xa4:
+               ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745;
+               dev_info(&dssdev->dev, "s1d13745 LCD controller rev %d "
+                       "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
+               break;
+       default:
+               dev_err(&dssdev->dev, "invalid s1d1374x revision %02x\n", rev);
+               r = -ENODEV;
+               goto err_inv_chip;
+       }
+
+       /* panel */
+
+       gpio_direction_output(bdata->panel_reset, 1);
+
+       mipid_read(spi, MIPID_CMD_READ_DISP_ID, display_id, 3);
+       dev_dbg(&spi->dev, "MIPI display ID: %02x%02x%02x\n",
+                       display_id[0], display_id[1], display_id[2]);
+
+       switch (display_id[0]) {
+       case 0x45:
+               panel_name = "lph8923";
+               break;
+       case 0x83:
+               panel_name = "ls041y3";
+               break;
+       default:
+               dev_err(&dssdev->dev, "invalid display ID 0x%x\n",
+                               display_id[0]);
+               r = -ENODEV;
+               goto err_inv_panel;
+       }
+
+       dev_info(&dssdev->dev, "%s rev %02x LCD detected\n",
+                       panel_name, display_id[1]);
+
+       send_sleep_out(spi);
+       send_init_string(spi);
+       set_data_lines(spi, 24);
+       send_display_on(spi);
+
+       return 0;
+
+err_inv_panel:
+       /*
+        * HACK: we should turn off the panel here, but there is some problem
+        * with the initialization sequence, and we fail to init the panel if we
+        * have turned it off
+        */
+       /* gpio_direction_output(bdata->panel_reset, 0); */
+err_inv_chip:
+       omapdss_rfbi_display_disable(dssdev);
+err_rfbi_en:
+       if (bdata->platform_disable)
+               bdata->platform_disable(dssdev);
+err_plat_en:
+       gpio_direction_output(bdata->ctrl_pwrdown, 0);
+       return r;
+}
+
+static void n8x0_panel_power_off(struct omap_dss_device *dssdev)
+{
+       struct panel_n8x0_data *bdata = get_board_data(dssdev);
+       struct panel_drv_data *ddata = get_drv_data(dssdev);
+       struct spi_device *spi = ddata->spidev;
+
+       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+               return;
+
+       send_display_off(spi);
+       send_sleep_in(spi);
+
+       if (bdata->platform_disable)
+               bdata->platform_disable(dssdev);
+
+       /*
+        * HACK: we should turn off the panel here, but there is some problem
+        * with the initialization sequence, and we fail to init the panel if we
+        * have turned it off
+        */
+       /* gpio_direction_output(bdata->panel_reset, 0); */
+       gpio_direction_output(bdata->ctrl_pwrdown, 0);
+       omapdss_rfbi_display_disable(dssdev);
+}
+
+static const struct rfbi_timings n8x0_panel_timings = {
+       .cs_on_time     = 0,
+
+       .we_on_time     = 9000,
+       .we_off_time    = 18000,
+       .we_cycle_time  = 36000,
+
+       .re_on_time     = 9000,
+       .re_off_time    = 27000,
+       .re_cycle_time  = 36000,
+
+       .access_time    = 27000,
+       .cs_off_time    = 36000,
+
+       .cs_pulse_width = 0,
+};
+
+static int n8x0_bl_update_status(struct backlight_device *dev)
+{
+       struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
+       struct panel_n8x0_data *bdata = get_board_data(dssdev);
+       struct panel_drv_data *ddata = get_drv_data(dssdev);
+       int r;
+       int level;
+
+       mutex_lock(&ddata->lock);
+
+       if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
+                       dev->props.power == FB_BLANK_UNBLANK)
+               level = dev->props.brightness;
+       else
+               level = 0;
+
+       dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
+
+       if (!bdata->set_backlight)
+               r = -EINVAL;
+       else
+               r = bdata->set_backlight(dssdev, level);
+
+       mutex_unlock(&ddata->lock);
+
+       return r;
+}
+
+static int n8x0_bl_get_intensity(struct backlight_device *dev)
+{
+       if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
+                       dev->props.power == FB_BLANK_UNBLANK)
+               return dev->props.brightness;
+
+       return 0;
+}
+
+static const struct backlight_ops n8x0_bl_ops = {
+       .get_brightness = n8x0_bl_get_intensity,
+       .update_status  = n8x0_bl_update_status,
+};
+
+static int n8x0_panel_probe(struct omap_dss_device *dssdev)
+{
+       struct panel_n8x0_data *bdata = get_board_data(dssdev);
+       struct panel_drv_data *ddata;
+       struct backlight_device *bldev;
+       struct backlight_properties props;
+       int r;
+
+       dev_dbg(&dssdev->dev, "probe\n");
+
+       if (!bdata)
+               return -EINVAL;
+
+       s_drv_data.dssdev = dssdev;
+
+       ddata = &s_drv_data;
+
+       mutex_init(&ddata->lock);
+
+       dssdev->panel.config = OMAP_DSS_LCD_TFT;
+       dssdev->panel.timings.x_res = 800;
+       dssdev->panel.timings.y_res = 480;
+       dssdev->ctrl.pixel_size = 16;
+       dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
+
+       memset(&props, 0, sizeof(props));
+       props.max_brightness = 127;
+       props.type = BACKLIGHT_PLATFORM;
+       bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
+                       dssdev, &n8x0_bl_ops, &props);
+       if (IS_ERR(bldev)) {
+               r = PTR_ERR(bldev);
+               dev_err(&dssdev->dev, "register backlight failed\n");
+               return r;
+       }
+
+       ddata->bldev = bldev;
+
+       bldev->props.fb_blank = FB_BLANK_UNBLANK;
+       bldev->props.power = FB_BLANK_UNBLANK;
+       bldev->props.brightness = 127;
+
+       n8x0_bl_update_status(bldev);
+
+       return 0;
+}
+
+static void n8x0_panel_remove(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = get_drv_data(dssdev);
+       struct backlight_device *bldev;
+
+       dev_dbg(&dssdev->dev, "remove\n");
+
+       bldev = ddata->bldev;
+       bldev->props.power = FB_BLANK_POWERDOWN;
+       n8x0_bl_update_status(bldev);
+       backlight_device_unregister(bldev);
+
+       dev_set_drvdata(&dssdev->dev, NULL);
+}
+
+static int n8x0_panel_enable(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = get_drv_data(dssdev);
+       int r;
+
+       dev_dbg(&dssdev->dev, "enable\n");
+
+       mutex_lock(&ddata->lock);
+
+       rfbi_bus_lock();
+
+       r = n8x0_panel_power_on(dssdev);
+
+       rfbi_bus_unlock();
+
+       if (r) {
+               mutex_unlock(&ddata->lock);
+               return r;
+       }
+
+       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+       mutex_unlock(&ddata->lock);
+
+       return 0;
+}
+
+static void n8x0_panel_disable(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = get_drv_data(dssdev);
+
+       dev_dbg(&dssdev->dev, "disable\n");
+
+       mutex_lock(&ddata->lock);
+
+       rfbi_bus_lock();
+
+       n8x0_panel_power_off(dssdev);
+
+       rfbi_bus_unlock();
+
+       dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+       mutex_unlock(&ddata->lock);
+}
+
+static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = get_drv_data(dssdev);
+
+       dev_dbg(&dssdev->dev, "suspend\n");
+
+       mutex_lock(&ddata->lock);
+
+       rfbi_bus_lock();
+
+       n8x0_panel_power_off(dssdev);
+
+       rfbi_bus_unlock();
+
+       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+
+       mutex_unlock(&ddata->lock);
+
+       return 0;
+}
+
+static int n8x0_panel_resume(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = get_drv_data(dssdev);
+       int r;
+
+       dev_dbg(&dssdev->dev, "resume\n");
+
+       mutex_lock(&ddata->lock);
+
+       rfbi_bus_lock();
+
+       r = n8x0_panel_power_on(dssdev);
+
+       rfbi_bus_unlock();
+
+       if (r) {
+               mutex_unlock(&ddata->lock);
+               return r;
+       }
+
+       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+       mutex_unlock(&ddata->lock);
+
+       return 0;
+}
+
+static void n8x0_panel_get_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       *timings = dssdev->panel.timings;
+}
+
+static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
+               u16 *xres, u16 *yres)
+{
+       *xres = dssdev->panel.timings.x_res;
+       *yres = dssdev->panel.timings.y_res;
+}
+
+static void update_done(void *data)
+{
+       rfbi_bus_unlock();
+}
+
+static int n8x0_panel_update(struct omap_dss_device *dssdev,
+               u16 x, u16 y, u16 w, u16 h)
+{
+       struct panel_drv_data *ddata = get_drv_data(dssdev);
+
+       dev_dbg(&dssdev->dev, "update\n");
+
+       mutex_lock(&ddata->lock);
+       rfbi_bus_lock();
+
+       omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h);
+
+       blizzard_ctrl_setup_update(dssdev, x, y, w, h);
+
+       omap_rfbi_update(dssdev, x, y, w, h, update_done, NULL);
+
+       mutex_unlock(&ddata->lock);
+
+       return 0;
+}
+
+static int n8x0_panel_sync(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = get_drv_data(dssdev);
+
+       dev_dbg(&dssdev->dev, "sync\n");
+
+       mutex_lock(&ddata->lock);
+       rfbi_bus_lock();
+       rfbi_bus_unlock();
+       mutex_unlock(&ddata->lock);
+
+       return 0;
+}
+
+static struct omap_dss_driver n8x0_panel_driver = {
+       .probe          = n8x0_panel_probe,
+       .remove         = n8x0_panel_remove,
+
+       .enable         = n8x0_panel_enable,
+       .disable        = n8x0_panel_disable,
+       .suspend        = n8x0_panel_suspend,
+       .resume         = n8x0_panel_resume,
+
+       .update         = n8x0_panel_update,
+       .sync           = n8x0_panel_sync,
+
+       .get_resolution = n8x0_panel_get_resolution,
+       .get_recommended_bpp = omapdss_default_get_recommended_bpp,
+
+       .get_timings    = n8x0_panel_get_timings,
+
+       .driver         = {
+               .name   = "n8x0_panel",
+               .owner  = THIS_MODULE,
+       },
+};
+
+/* PANEL */
+
+static int mipid_spi_probe(struct spi_device *spi)
+{
+       dev_dbg(&spi->dev, "mipid_spi_probe\n");
+
+       spi->mode = SPI_MODE_0;
+
+       s_drv_data.spidev = spi;
+
+       return 0;
+}
+
+static int mipid_spi_remove(struct spi_device *spi)
+{
+       dev_dbg(&spi->dev, "mipid_spi_remove\n");
+       return 0;
+}
+
+static struct spi_driver mipid_spi_driver = {
+       .driver = {
+               .name   = "lcd_mipid",
+               .bus    = &spi_bus_type,
+               .owner  = THIS_MODULE,
+       },
+       .probe  = mipid_spi_probe,
+       .remove = __devexit_p(mipid_spi_remove),
+};
+
+static int __init n8x0_panel_drv_init(void)
+{
+       int r;
+
+       r = spi_register_driver(&mipid_spi_driver);
+       if (r) {
+               pr_err("n8x0_panel: spi driver registration failed\n");
+               return r;
+       }
+
+       r = omap_dss_register_driver(&n8x0_panel_driver);
+       if (r) {
+               pr_err("n8x0_panel: dss driver registration failed\n");
+               spi_unregister_driver(&mipid_spi_driver);
+               return r;
+       }
+
+       return 0;
+}
+
+static void __exit n8x0_panel_drv_exit(void)
+{
+       spi_unregister_driver(&mipid_spi_driver);
+
+       omap_dss_unregister_driver(&n8x0_panel_driver);
+}
+
+module_init(n8x0_panel_drv_init);
+module_exit(n8x0_panel_drv_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
new file mode 100644 (file)
index 0000000..98ebdad
--- /dev/null
@@ -0,0 +1,594 @@
+/*
+ * picodlp panel driver
+ * picodlp_i2c_driver: i2c_client driver
+ *
+ * Copyright (C) 2009-2011 Texas Instruments
+ * Author: Mythri P K <mythripk@ti.com>
+ * Mayuresh Janorkar <mayur@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include <video/omapdss.h>
+#include <video/omap-panel-picodlp.h>
+
+#include "panel-picodlp.h"
+
+struct picodlp_data {
+       struct mutex lock;
+       struct i2c_client *picodlp_i2c_client;
+};
+
+static struct i2c_board_info picodlp_i2c_board_info = {
+       I2C_BOARD_INFO("picodlp_i2c_driver", 0x1b),
+};
+
+struct picodlp_i2c_data {
+       struct mutex xfer_lock;
+};
+
+static struct i2c_device_id picodlp_i2c_id[] = {
+       { "picodlp_i2c_driver", 0 },
+};
+
+struct picodlp_i2c_command {
+       u8 reg;
+       u32 value;
+};
+
+static struct omap_video_timings pico_ls_timings = {
+       .x_res          = 864,
+       .y_res          = 480,
+       .hsw            = 7,
+       .hfp            = 11,
+       .hbp            = 7,
+
+       .pixel_clock    = 19200,
+
+       .vsw            = 2,
+       .vfp            = 3,
+       .vbp            = 14,
+};
+
+static inline struct picodlp_panel_data
+               *get_panel_data(const struct omap_dss_device *dssdev)
+{
+       return (struct picodlp_panel_data *) dssdev->data;
+}
+
+static u32 picodlp_i2c_read(struct i2c_client *client, u8 reg)
+{
+       u8 read_cmd[] = {READ_REG_SELECT, reg}, data[4];
+       struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
+       struct i2c_msg msg[2];
+
+       mutex_lock(&picodlp_i2c_data->xfer_lock);
+
+       msg[0].addr = client->addr;
+       msg[0].flags = 0;
+       msg[0].len = 2;
+       msg[0].buf = read_cmd;
+
+       msg[1].addr = client->addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].len = 4;
+       msg[1].buf = data;
+
+       i2c_transfer(client->adapter, msg, 2);
+       mutex_unlock(&picodlp_i2c_data->xfer_lock);
+       return (data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24));
+}
+
+static int picodlp_i2c_write_block(struct i2c_client *client,
+                                       u8 *data, int len)
+{
+       struct i2c_msg msg;
+       int i, r, msg_count = 1;
+
+       struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
+
+       if (len < 1 || len > 32) {
+               dev_err(&client->dev,
+                       "too long syn_write_block len %d\n", len);
+               return -EIO;
+       }
+       mutex_lock(&picodlp_i2c_data->xfer_lock);
+
+       msg.addr = client->addr;
+       msg.flags = 0;
+       msg.len = len;
+       msg.buf = data;
+       r = i2c_transfer(client->adapter, &msg, msg_count);
+       mutex_unlock(&picodlp_i2c_data->xfer_lock);
+
+       /*
+        * i2c_transfer returns:
+        * number of messages sent in case of success
+        * a negative error number in case of failure
+        */
+       if (r != msg_count)
+               goto err;
+
+       /* In case of success */
+       for (i = 0; i < len; i++)
+               dev_dbg(&client->dev,
+                       "addr %x bw 0x%02x[%d]: 0x%02x\n",
+                       client->addr, data[0] + i, i, data[i]);
+
+       return 0;
+err:
+       dev_err(&client->dev, "picodlp_i2c_write error\n");
+       return r;
+}
+
+static int picodlp_i2c_write(struct i2c_client *client, u8 reg, u32 value)
+{
+       u8 data[5];
+       int i;
+
+       data[0] = reg;
+       for (i = 1; i < 5; i++)
+               data[i] = (value >> (32 - (i) * 8)) & 0xFF;
+
+       return picodlp_i2c_write_block(client, data, 5);
+}
+
+static int picodlp_i2c_write_array(struct i2c_client *client,
+                       const struct picodlp_i2c_command commands[],
+                       int count)
+{
+       int i, r = 0;
+       for (i = 0; i < count; i++) {
+               r = picodlp_i2c_write(client, commands[i].reg,
+                                               commands[i].value);
+               if (r)
+                       return r;
+       }
+       return r;
+}
+
+static int picodlp_wait_for_dma_done(struct i2c_client *client)
+{
+       u8 trial = 100;
+
+       do {
+               msleep(1);
+               if (!trial--)
+                       return -ETIMEDOUT;
+       } while (picodlp_i2c_read(client, MAIN_STATUS) & DMA_STATUS);
+
+       return 0;
+}
+
+/**
+ * picodlp_i2c_init:   i2c_initialization routine
+ * client:     i2c_client for communication
+ *
+ * return
+ *             0       : Success, no error
+ *     error code      : Failure
+ */
+static int picodlp_i2c_init(struct i2c_client *client)
+{
+       int r;
+       static const struct picodlp_i2c_command init_cmd_set1[] = {
+               {SOFT_RESET, 1},
+               {DMD_PARK_TRIGGER, 1},
+               {MISC_REG, 5},
+               {SEQ_CONTROL, 0},
+               {SEQ_VECTOR, 0x100},
+               {DMD_BLOCK_COUNT, 7},
+               {DMD_VCC_CONTROL, 0x109},
+               {DMD_PARK_PULSE_COUNT, 0xA},
+               {DMD_PARK_PULSE_WIDTH, 0xB},
+               {DMD_PARK_DELAY, 0x2ED},
+               {DMD_SHADOW_ENABLE, 0},
+               {FLASH_OPCODE, 0xB},
+               {FLASH_DUMMY_BYTES, 1},
+               {FLASH_ADDR_BYTES, 3},
+               {PBC_CONTROL, 0},
+               {FLASH_START_ADDR, CMT_LUT_0_START_ADDR},
+               {FLASH_READ_BYTES, CMT_LUT_0_SIZE},
+               {CMT_SPLASH_LUT_START_ADDR, 0},
+               {CMT_SPLASH_LUT_DEST_SELECT, CMT_LUT_ALL},
+               {PBC_CONTROL, 1},
+       };
+
+       static const struct picodlp_i2c_command init_cmd_set2[] = {
+               {PBC_CONTROL, 0},
+               {CMT_SPLASH_LUT_DEST_SELECT, 0},
+               {PBC_CONTROL, 0},
+               {FLASH_START_ADDR, SEQUENCE_0_START_ADDR},
+               {FLASH_READ_BYTES, SEQUENCE_0_SIZE},
+               {SEQ_RESET_LUT_START_ADDR, 0},
+               {SEQ_RESET_LUT_DEST_SELECT, SEQ_SEQ_LUT},
+               {PBC_CONTROL, 1},
+       };
+
+       static const struct picodlp_i2c_command init_cmd_set3[] = {
+               {PBC_CONTROL, 0},
+               {SEQ_RESET_LUT_DEST_SELECT, 0},
+               {PBC_CONTROL, 0},
+               {FLASH_START_ADDR, DRC_TABLE_0_START_ADDR},
+               {FLASH_READ_BYTES, DRC_TABLE_0_SIZE},
+               {SEQ_RESET_LUT_START_ADDR, 0},
+               {SEQ_RESET_LUT_DEST_SELECT, SEQ_DRC_LUT_ALL},
+               {PBC_CONTROL, 1},
+       };
+
+       static const struct picodlp_i2c_command init_cmd_set4[] = {
+               {PBC_CONTROL, 0},
+               {SEQ_RESET_LUT_DEST_SELECT, 0},
+               {SDC_ENABLE, 1},
+               {AGC_CTRL, 7},
+               {CCA_C1A, 0x100},
+               {CCA_C1B, 0x0},
+               {CCA_C1C, 0x0},
+               {CCA_C2A, 0x0},
+               {CCA_C2B, 0x100},
+               {CCA_C2C, 0x0},
+               {CCA_C3A, 0x0},
+               {CCA_C3B, 0x0},
+               {CCA_C3C, 0x100},
+               {CCA_C7A, 0x100},
+               {CCA_C7B, 0x100},
+               {CCA_C7C, 0x100},
+               {CCA_ENABLE, 1},
+               {CPU_IF_MODE, 1},
+               {SHORT_FLIP, 1},
+               {CURTAIN_CONTROL, 0},
+               {DMD_PARK_TRIGGER, 0},
+               {R_DRIVE_CURRENT, 0x298},
+               {G_DRIVE_CURRENT, 0x298},
+               {B_DRIVE_CURRENT, 0x298},
+               {RGB_DRIVER_ENABLE, 7},
+               {SEQ_CONTROL, 0},
+               {ACTGEN_CONTROL, 0x10},
+               {SEQUENCE_MODE, SEQ_LOCK},
+               {DATA_FORMAT, RGB888},
+               {INPUT_RESOLUTION, WVGA_864_LANDSCAPE},
+               {INPUT_SOURCE, PARALLEL_RGB},
+               {CPU_IF_SYNC_METHOD, 1},
+               {SEQ_CONTROL, 1}
+       };
+
+       r = picodlp_i2c_write_array(client, init_cmd_set1,
+                                               ARRAY_SIZE(init_cmd_set1));
+       if (r)
+               return r;
+
+       r = picodlp_wait_for_dma_done(client);
+       if (r)
+               return r;
+
+       r = picodlp_i2c_write_array(client, init_cmd_set2,
+                                       ARRAY_SIZE(init_cmd_set2));
+       if (r)
+               return r;
+
+       r = picodlp_wait_for_dma_done(client);
+       if (r)
+               return r;
+
+       r = picodlp_i2c_write_array(client, init_cmd_set3,
+                                       ARRAY_SIZE(init_cmd_set3));
+       if (r)
+               return r;
+
+       r = picodlp_wait_for_dma_done(client);
+       if (r)
+               return r;
+
+       r = picodlp_i2c_write_array(client, init_cmd_set4,
+                                       ARRAY_SIZE(init_cmd_set4));
+       if (r)
+               return r;
+
+       return 0;
+}
+
+static int picodlp_i2c_probe(struct i2c_client *client,
+               const struct i2c_device_id *id)
+{
+       struct picodlp_i2c_data *picodlp_i2c_data;
+
+       picodlp_i2c_data = kzalloc(sizeof(struct picodlp_i2c_data), GFP_KERNEL);
+
+       if (!picodlp_i2c_data)
+               return -ENOMEM;
+
+       mutex_init(&picodlp_i2c_data->xfer_lock);
+       i2c_set_clientdata(client, picodlp_i2c_data);
+
+       return 0;
+}
+
+static int picodlp_i2c_remove(struct i2c_client *client)
+{
+       struct picodlp_i2c_data *picodlp_i2c_data =
+                                       i2c_get_clientdata(client);
+       kfree(picodlp_i2c_data);
+       return 0;
+}
+
+static struct i2c_driver picodlp_i2c_driver = {
+       .driver = {
+               .name   = "picodlp_i2c_driver",
+       },
+       .probe          = picodlp_i2c_probe,
+       .remove         = picodlp_i2c_remove,
+       .id_table       = picodlp_i2c_id,
+};
+
+static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
+{
+       int r, trial = 100;
+       struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
+       struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
+
+       if (dssdev->platform_enable) {
+               r = dssdev->platform_enable(dssdev);
+               if (r)
+                       return r;
+       }
+
+       gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
+       msleep(1);
+       gpio_set_value(picodlp_pdata->pwrgood_gpio, 1);
+
+       while (!gpio_get_value(picodlp_pdata->emu_done_gpio)) {
+               if (!trial--) {
+                       dev_err(&dssdev->dev, "emu_done signal not"
+                                               " going high\n");
+                       return -ETIMEDOUT;
+               }
+               msleep(5);
+       }
+       /*
+        * As per dpp2600 programming guide,
+        * it is required to sleep for 1000ms after emu_done signal goes high
+        * then only i2c commands can be successfully sent to dpp2600
+        */
+       msleep(1000);
+       r = omapdss_dpi_display_enable(dssdev);
+       if (r) {
+               dev_err(&dssdev->dev, "failed to enable DPI\n");
+               goto err1;
+       }
+
+       r = picodlp_i2c_init(picod->picodlp_i2c_client);
+       if (r)
+               goto err;
+
+       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+       return r;
+err:
+       omapdss_dpi_display_disable(dssdev);
+err1:
+       if (dssdev->platform_disable)
+               dssdev->platform_disable(dssdev);
+
+       return r;
+}
+
+static void picodlp_panel_power_off(struct omap_dss_device *dssdev)
+{
+       struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
+
+       omapdss_dpi_display_disable(dssdev);
+
+       gpio_set_value(picodlp_pdata->emu_done_gpio, 0);
+       gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
+
+       if (dssdev->platform_disable)
+               dssdev->platform_disable(dssdev);
+}
+
+static int picodlp_panel_probe(struct omap_dss_device *dssdev)
+{
+       struct picodlp_data *picod;
+       struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
+       struct i2c_adapter *adapter;
+       struct i2c_client *picodlp_i2c_client;
+       int r = 0, picodlp_adapter_id;
+
+       dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_ONOFF |
+                               OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IVS;
+       dssdev->panel.acb = 0x0;
+       dssdev->panel.timings = pico_ls_timings;
+
+       picod =  kzalloc(sizeof(struct picodlp_data), GFP_KERNEL);
+       if (!picod)
+               return -ENOMEM;
+
+       mutex_init(&picod->lock);
+
+       picodlp_adapter_id = picodlp_pdata->picodlp_adapter_id;
+
+       adapter = i2c_get_adapter(picodlp_adapter_id);
+       if (!adapter) {
+               dev_err(&dssdev->dev, "can't get i2c adapter\n");
+               r = -ENODEV;
+               goto err;
+       }
+
+       picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info);
+       if (!picodlp_i2c_client) {
+               dev_err(&dssdev->dev, "can't add i2c device::"
+                                        " picodlp_i2c_client is NULL\n");
+               r = -ENODEV;
+               goto err;
+       }
+
+       picod->picodlp_i2c_client = picodlp_i2c_client;
+
+       dev_set_drvdata(&dssdev->dev, picod);
+       return r;
+err:
+       kfree(picod);
+       return r;
+}
+
+static void picodlp_panel_remove(struct omap_dss_device *dssdev)
+{
+       struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
+
+       i2c_unregister_device(picod->picodlp_i2c_client);
+       dev_set_drvdata(&dssdev->dev, NULL);
+       dev_dbg(&dssdev->dev, "removing picodlp panel\n");
+
+       kfree(picod);
+}
+
+static int picodlp_panel_enable(struct omap_dss_device *dssdev)
+{
+       struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
+       int r;
+
+       dev_dbg(&dssdev->dev, "enabling picodlp panel\n");
+
+       mutex_lock(&picod->lock);
+       if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+               mutex_unlock(&picod->lock);
+               return -EINVAL;
+       }
+
+       r = picodlp_panel_power_on(dssdev);
+       mutex_unlock(&picod->lock);
+
+       return r;
+}
+
+static void picodlp_panel_disable(struct omap_dss_device *dssdev)
+{
+       struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
+
+       mutex_lock(&picod->lock);
+       /* Turn off DLP Power */
+       if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+               picodlp_panel_power_off(dssdev);
+
+       dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+       mutex_unlock(&picod->lock);
+
+       dev_dbg(&dssdev->dev, "disabling picodlp panel\n");
+}
+
+static int picodlp_panel_suspend(struct omap_dss_device *dssdev)
+{
+       struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
+
+       mutex_lock(&picod->lock);
+       /* Turn off DLP Power */
+       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
+               mutex_unlock(&picod->lock);
+               dev_err(&dssdev->dev, "unable to suspend picodlp panel,"
+                                       " panel is not ACTIVE\n");
+               return -EINVAL;
+       }
+
+       picodlp_panel_power_off(dssdev);
+
+       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+       mutex_unlock(&picod->lock);
+
+       dev_dbg(&dssdev->dev, "suspending picodlp panel\n");
+       return 0;
+}
+
+static int picodlp_panel_resume(struct omap_dss_device *dssdev)
+{
+       struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
+       int r;
+
+       mutex_lock(&picod->lock);
+       if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
+               mutex_unlock(&picod->lock);
+               dev_err(&dssdev->dev, "unable to resume picodlp panel,"
+                       " panel is not ACTIVE\n");
+               return -EINVAL;
+       }
+
+       r = picodlp_panel_power_on(dssdev);
+       mutex_unlock(&picod->lock);
+       dev_dbg(&dssdev->dev, "resuming picodlp panel\n");
+       return r;
+}
+
+static void picodlp_get_resolution(struct omap_dss_device *dssdev,
+                                       u16 *xres, u16 *yres)
+{
+       *xres = dssdev->panel.timings.x_res;
+       *yres = dssdev->panel.timings.y_res;
+}
+
+static struct omap_dss_driver picodlp_driver = {
+       .probe          = picodlp_panel_probe,
+       .remove         = picodlp_panel_remove,
+
+       .enable         = picodlp_panel_enable,
+       .disable        = picodlp_panel_disable,
+
+       .get_resolution = picodlp_get_resolution,
+
+       .suspend        = picodlp_panel_suspend,
+       .resume         = picodlp_panel_resume,
+
+       .driver         = {
+               .name   = "picodlp_panel",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init picodlp_init(void)
+{
+       int r = 0;
+
+       r = i2c_add_driver(&picodlp_i2c_driver);
+       if (r) {
+               printk(KERN_WARNING "picodlp_i2c_driver" \
+                       " registration failed\n");
+               return r;
+       }
+
+       r = omap_dss_register_driver(&picodlp_driver);
+       if (r)
+               i2c_del_driver(&picodlp_i2c_driver);
+
+       return r;
+}
+
+static void __exit picodlp_exit(void)
+{
+       i2c_del_driver(&picodlp_i2c_driver);
+       omap_dss_unregister_driver(&picodlp_driver);
+}
+
+module_init(picodlp_init);
+module_exit(picodlp_exit);
+
+MODULE_AUTHOR("Mythri P K <mythripk@ti.com>");
+MODULE_DESCRIPTION("picodlp driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-picodlp.h b/drivers/video/omap2/displays/panel-picodlp.h
new file mode 100644 (file)
index 0000000..a34b431
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * Header file required by picodlp panel driver
+ *
+ * Copyright (C) 2009-2011 Texas Instruments
+ * Author: Mythri P K <mythripk@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __OMAP2_DISPLAY_PANEL_PICODLP_H
+#define __OMAP2_DISPLAY_PANEL_PICODLP_H
+
+/* Commands used for configuring picodlp panel */
+
+#define MAIN_STATUS                    0x03
+#define PBC_CONTROL                    0x08
+#define INPUT_SOURCE                   0x0B
+#define INPUT_RESOLUTION               0x0C
+#define DATA_FORMAT                    0x0D
+#define IMG_ROTATION                   0x0E
+#define LONG_FLIP                      0x0F
+#define SHORT_FLIP                     0x10
+#define TEST_PAT_SELECT                        0x11
+#define R_DRIVE_CURRENT                        0x12
+#define G_DRIVE_CURRENT                        0x13
+#define B_DRIVE_CURRENT                        0x14
+#define READ_REG_SELECT                        0x15
+#define RGB_DRIVER_ENABLE              0x16
+
+#define CPU_IF_MODE                    0x18
+#define FRAME_RATE                     0x19
+#define CPU_IF_SYNC_METHOD             0x1A
+#define CPU_IF_SOF                     0x1B
+#define CPU_IF_EOF                     0x1C
+#define CPU_IF_SLEEP                   0x1D
+
+#define SEQUENCE_MODE                  0x1E
+#define SOFT_RESET                     0x1F
+#define FRONT_END_RESET                        0x21
+#define AUTO_PWR_ENABLE                        0x22
+
+#define VSYNC_LINE_DELAY               0x23
+#define CPU_PI_HORIZ_START             0x24
+#define CPU_PI_VERT_START              0x25
+#define CPU_PI_HORIZ_WIDTH             0x26
+#define CPU_PI_VERT_HEIGHT             0x27
+
+#define PIXEL_MASK_CROP                        0x28
+#define CROP_FIRST_LINE                        0x29
+#define CROP_LAST_LINE                 0x2A
+#define CROP_FIRST_PIXEL               0x2B
+#define CROP_LAST_PIXEL                        0x2C
+#define DMD_PARK_TRIGGER               0x2D
+
+#define MISC_REG                       0x30
+
+/* AGC registers */
+#define AGC_CTRL                       0x50
+#define AGC_CLIPPED_PIXS               0x55
+#define AGC_BRIGHT_PIXS                        0x56
+#define AGC_BG_PIXS                    0x57
+#define AGC_SAFETY_MARGIN              0x17
+
+/* Color Coordinate Adjustment registers */
+#define CCA_ENABLE             0x5E
+#define CCA_C1A                        0x5F
+#define CCA_C1B                        0x60
+#define CCA_C1C                        0x61
+#define CCA_C2A                        0x62
+#define CCA_C2B                        0x63
+#define CCA_C2C                        0x64
+#define CCA_C3A                        0x65
+#define CCA_C3B                        0x66
+#define CCA_C3C                        0x67
+#define CCA_C7A                        0x71
+#define CCA_C7B                        0x72
+#define CCA_C7C                        0x73
+
+/**
+ * DLP Pico Processor 2600 comes with flash
+ * We can do DMA operations from flash for accessing Look Up Tables
+ */
+#define DMA_STATUS                     0x100
+#define FLASH_ADDR_BYTES               0x74
+#define FLASH_DUMMY_BYTES              0x75
+#define FLASH_WRITE_BYTES              0x76
+#define FLASH_READ_BYTES               0x77
+#define FLASH_OPCODE                   0x78
+#define FLASH_START_ADDR               0x79
+#define FLASH_DUMMY2                   0x7A
+#define FLASH_WRITE_DATA               0x7B
+
+#define TEMPORAL_DITH_DISABLE          0x7E
+#define SEQ_CONTROL                    0x82
+#define SEQ_VECTOR                     0x83
+
+/* DMD is Digital Micromirror Device */
+#define DMD_BLOCK_COUNT                        0x84
+#define DMD_VCC_CONTROL                        0x86
+#define DMD_PARK_PULSE_COUNT           0x87
+#define DMD_PARK_PULSE_WIDTH           0x88
+#define DMD_PARK_DELAY                 0x89
+#define DMD_SHADOW_ENABLE              0x8E
+#define SEQ_STATUS                     0x8F
+#define FLASH_CLOCK_CONTROL            0x98
+#define DMD_PARK                       0x2D
+
+#define SDRAM_BIST_ENABLE              0x46
+#define DDR_DRIVER_STRENGTH            0x9A
+#define SDC_ENABLE                     0x9D
+#define SDC_BUFF_SWAP_DISABLE          0xA3
+#define CURTAIN_CONTROL                        0xA6
+#define DDR_BUS_SWAP_ENABLE            0xA7
+#define DMD_TRC_ENABLE                 0xA8
+#define DMD_BUS_SWAP_ENABLE            0xA9
+
+#define ACTGEN_ENABLE                  0xAE
+#define ACTGEN_CONTROL                 0xAF
+#define ACTGEN_HORIZ_BP                        0xB0
+#define ACTGEN_VERT_BP                 0xB1
+
+/* Look Up Table access */
+#define CMT_SPLASH_LUT_START_ADDR      0xFA
+#define CMT_SPLASH_LUT_DEST_SELECT     0xFB
+#define CMT_SPLASH_LUT_DATA            0xFC
+#define SEQ_RESET_LUT_START_ADDR       0xFD
+#define SEQ_RESET_LUT_DEST_SELECT      0xFE
+#define SEQ_RESET_LUT_DATA             0xFF
+
+/* Input source definitions */
+#define PARALLEL_RGB           0
+#define INT_TEST_PATTERN       1
+#define SPLASH_SCREEN          2
+#define CPU_INTF               3
+#define BT656                  4
+
+/* Standard input resolution definitions */
+#define QWVGA_LANDSCAPE                3       /* (427h*240v) */
+#define WVGA_864_LANDSCAPE     21      /* (864h*480v) */
+#define WVGA_DMD_OPTICAL_TEST  35      /* (608h*684v) */
+
+/* Standard data format definitions */
+#define RGB565                 0
+#define RGB666                 1
+#define RGB888                 2
+
+/* Test Pattern definitions */
+#define TPG_CHECKERBOARD       0
+#define TPG_BLACK              1
+#define TPG_WHITE              2
+#define TPG_RED                        3
+#define TPG_BLUE               4
+#define TPG_GREEN              5
+#define TPG_VLINES_BLACK       6
+#define TPG_HLINES_BLACK       7
+#define TPG_VLINES_ALT         8
+#define TPG_HLINES_ALT         9
+#define TPG_DIAG_LINES         10
+#define TPG_GREYRAMP_VERT      11
+#define TPG_GREYRAMP_HORIZ     12
+#define TPG_ANSI_CHECKERBOARD  13
+
+/* sequence mode definitions */
+#define SEQ_FREE_RUN           0
+#define SEQ_LOCK               1
+
+/* curtain color definitions */
+#define CURTAIN_BLACK          0
+#define CURTAIN_RED            1
+#define CURTAIN_GREEN          2
+#define CURTAIN_BLUE           3
+#define CURTAIN_YELLOW         4
+#define CURTAIN_MAGENTA                5
+#define CURTAIN_CYAN           6
+#define CURTAIN_WHITE          7
+
+/* LUT definitions */
+#define CMT_LUT_NONE           0
+#define CMT_LUT_GREEN          1
+#define CMT_LUT_RED            2
+#define CMT_LUT_BLUE           3
+#define CMT_LUT_ALL            4
+#define SPLASH_LUT             5
+
+#define SEQ_LUT_NONE           0
+#define SEQ_DRC_LUT_0          1
+#define SEQ_DRC_LUT_1          2
+#define SEQ_DRC_LUT_2          3
+#define SEQ_DRC_LUT_3          4
+#define SEQ_SEQ_LUT            5
+#define SEQ_DRC_LUT_ALL                6
+#define WPC_PROGRAM_LUT                7
+
+#define BITSTREAM_START_ADDR           0x00000000
+#define BITSTREAM_SIZE                 0x00040000
+
+#define WPC_FW_0_START_ADDR            0x00040000
+#define WPC_FW_0_SIZE                  0x00000ce8
+
+#define SEQUENCE_0_START_ADDR          0x00044000
+#define SEQUENCE_0_SIZE                        0x00001000
+
+#define SEQUENCE_1_START_ADDR          0x00045000
+#define SEQUENCE_1_SIZE                        0x00000d10
+
+#define SEQUENCE_2_START_ADDR          0x00046000
+#define SEQUENCE_2_SIZE                        0x00000d10
+
+#define SEQUENCE_3_START_ADDR          0x00047000
+#define SEQUENCE_3_SIZE                        0x00000d10
+
+#define SEQUENCE_4_START_ADDR          0x00048000
+#define SEQUENCE_4_SIZE                        0x00000d10
+
+#define SEQUENCE_5_START_ADDR          0x00049000
+#define SEQUENCE_5_SIZE                        0x00000d10
+
+#define SEQUENCE_6_START_ADDR          0x0004a000
+#define SEQUENCE_6_SIZE                        0x00000d10
+
+#define CMT_LUT_0_START_ADDR           0x0004b200
+#define CMT_LUT_0_SIZE                 0x00000600
+
+#define CMT_LUT_1_START_ADDR           0x0004b800
+#define CMT_LUT_1_SIZE                 0x00000600
+
+#define CMT_LUT_2_START_ADDR           0x0004be00
+#define CMT_LUT_2_SIZE                 0x00000600
+
+#define CMT_LUT_3_START_ADDR           0x0004c400
+#define CMT_LUT_3_SIZE                 0x00000600
+
+#define CMT_LUT_4_START_ADDR           0x0004ca00
+#define CMT_LUT_4_SIZE                 0x00000600
+
+#define CMT_LUT_5_START_ADDR           0x0004d000
+#define CMT_LUT_5_SIZE                 0x00000600
+
+#define CMT_LUT_6_START_ADDR           0x0004d600
+#define CMT_LUT_6_SIZE                 0x00000600
+
+#define DRC_TABLE_0_START_ADDR         0x0004dc00
+#define DRC_TABLE_0_SIZE               0x00000100
+
+#define SPLASH_0_START_ADDR            0x0004dd00
+#define SPLASH_0_SIZE                  0x00032280
+
+#define SEQUENCE_7_START_ADDR          0x00080000
+#define SEQUENCE_7_SIZE                        0x00000d10
+
+#define SEQUENCE_8_START_ADDR          0x00081800
+#define SEQUENCE_8_SIZE                        0x00000d10
+
+#define SEQUENCE_9_START_ADDR          0x00083000
+#define SEQUENCE_9_SIZE                        0x00000d10
+
+#define CMT_LUT_7_START_ADDR           0x0008e000
+#define CMT_LUT_7_SIZE                 0x00000600
+
+#define CMT_LUT_8_START_ADDR           0x0008e800
+#define CMT_LUT_8_SIZE                 0x00000600
+
+#define CMT_LUT_9_START_ADDR           0x0008f000
+#define CMT_LUT_9_SIZE                 0x00000600
+
+#define SPLASH_1_START_ADDR            0x0009a000
+#define SPLASH_1_SIZE                  0x00032280
+
+#define SPLASH_2_START_ADDR            0x000cd000
+#define SPLASH_2_SIZE                  0x00032280
+
+#define SPLASH_3_START_ADDR            0x00100000
+#define SPLASH_3_SIZE                  0x00032280
+
+#define OPT_SPLASH_0_START_ADDR                0x00134000
+#define OPT_SPLASH_0_SIZE              0x000cb100
+
+#endif
index ca00843..80c3f6a 100644 (file)
 
 #include <video/omapdss.h>
 #include <video/omap-panel-nokia-dsi.h>
+#include <video/mipi_display.h>
 
 /* DSI Virtual channel. Hardcoded for now. */
 #define TCH 0
 
 #define DCS_READ_NUM_ERRORS    0x05
-#define DCS_READ_POWER_MODE    0x0a
-#define DCS_READ_MADCTL                0x0b
-#define DCS_READ_PIXEL_FORMAT  0x0c
-#define DCS_RDDSDR             0x0f
-#define DCS_SLEEP_IN           0x10
-#define DCS_SLEEP_OUT          0x11
-#define DCS_DISPLAY_OFF                0x28
-#define DCS_DISPLAY_ON         0x29
-#define DCS_COLUMN_ADDR                0x2a
-#define DCS_PAGE_ADDR          0x2b
-#define DCS_MEMORY_WRITE       0x2c
-#define DCS_TEAR_OFF           0x34
-#define DCS_TEAR_ON            0x35
-#define DCS_MEM_ACC_CTRL       0x36
-#define DCS_PIXEL_FORMAT       0x3a
 #define DCS_BRIGHTNESS         0x51
 #define DCS_CTRL_DISPLAY       0x53
 #define DCS_WRITE_CABC         0x55
@@ -222,8 +208,6 @@ struct taal_data {
 
        struct delayed_work te_timeout_work;
 
-       bool use_dsi_bl;
-
        bool cabc_broken;
        unsigned cabc_mode;
 
@@ -302,7 +286,7 @@ static int taal_sleep_in(struct taal_data *td)
 
        hw_guard_wait(td);
 
-       cmd = DCS_SLEEP_IN;
+       cmd = MIPI_DCS_ENTER_SLEEP_MODE;
        r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
        if (r)
                return r;
@@ -321,7 +305,7 @@ static int taal_sleep_out(struct taal_data *td)
 
        hw_guard_wait(td);
 
-       r = taal_dcs_write_0(td, DCS_SLEEP_OUT);
+       r = taal_dcs_write_0(td, MIPI_DCS_EXIT_SLEEP_MODE);
        if (r)
                return r;
 
@@ -356,7 +340,7 @@ static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
        u8 mode;
        int b5, b6, b7;
 
-       r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode);
+       r = taal_dcs_read_1(td, MIPI_DCS_GET_ADDRESS_MODE, &mode);
        if (r)
                return r;
 
@@ -390,7 +374,7 @@ static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
        mode &= ~((1<<7) | (1<<6) | (1<<5));
        mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
 
-       return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode);
+       return taal_dcs_write_1(td, MIPI_DCS_SET_ADDRESS_MODE, mode);
 }
 
 static int taal_set_update_window(struct taal_data *td,
@@ -403,7 +387,7 @@ static int taal_set_update_window(struct taal_data *td,
        u16 y2 = y + h - 1;
 
        u8 buf[5];
-       buf[0] = DCS_COLUMN_ADDR;
+       buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
        buf[1] = (x1 >> 8) & 0xff;
        buf[2] = (x1 >> 0) & 0xff;
        buf[3] = (x2 >> 8) & 0xff;
@@ -413,7 +397,7 @@ static int taal_set_update_window(struct taal_data *td,
        if (r)
                return r;
 
-       buf[0] = DCS_PAGE_ADDR;
+       buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
        buf[1] = (y1 >> 8) & 0xff;
        buf[2] = (y1 >> 0) & 0xff;
        buf[3] = (y2 >> 8) & 0xff;
@@ -555,7 +539,6 @@ static int taal_bl_update_status(struct backlight_device *dev)
 {
        struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-       struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
        int r;
        int level;
 
@@ -569,23 +552,16 @@ static int taal_bl_update_status(struct backlight_device *dev)
 
        mutex_lock(&td->lock);
 
-       if (td->use_dsi_bl) {
-               if (td->enabled) {
-                       dsi_bus_lock(dssdev);
+       if (td->enabled) {
+               dsi_bus_lock(dssdev);
 
-                       r = taal_wake_up(dssdev);
-                       if (!r)
-                               r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
+               r = taal_wake_up(dssdev);
+               if (!r)
+                       r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
 
-                       dsi_bus_unlock(dssdev);
-               } else {
-                       r = 0;
-               }
+               dsi_bus_unlock(dssdev);
        } else {
-               if (!panel_data->set_backlight)
-                       r = -EINVAL;
-               else
-                       r = panel_data->set_backlight(dssdev, level);
+               r = 0;
        }
 
        mutex_unlock(&td->lock);
@@ -964,7 +940,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
 {
        struct backlight_properties props;
        struct taal_data *td;
-       struct backlight_device *bldev;
+       struct backlight_device *bldev = NULL;
        struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
        struct panel_config *panel_config = NULL;
        int r, i;
@@ -990,7 +966,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
        dssdev->panel.config = OMAP_DSS_LCD_TFT;
        dssdev->panel.timings = panel_config->timings;
-       dssdev->ctrl.pixel_size = 24;
+       dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
 
        td = kzalloc(sizeof(*td), GFP_KERNEL);
        if (!td) {
@@ -1025,35 +1001,26 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
        taal_hw_reset(dssdev);
 
-       /* if no platform set_backlight() defined, presume DSI backlight
-        * control */
-       memset(&props, 0, sizeof(struct backlight_properties));
-       if (!panel_data->set_backlight)
-               td->use_dsi_bl = true;
-
-       if (td->use_dsi_bl)
+       if (panel_data->use_dsi_backlight) {
+               memset(&props, 0, sizeof(struct backlight_properties));
                props.max_brightness = 255;
-       else
-               props.max_brightness = 127;
-
-       props.type = BACKLIGHT_RAW;
-       bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
-                                       dssdev, &taal_bl_ops, &props);
-       if (IS_ERR(bldev)) {
-               r = PTR_ERR(bldev);
-               goto err_bl;
-       }
 
-       td->bldev = bldev;
+               props.type = BACKLIGHT_RAW;
+               bldev = backlight_device_register(dev_name(&dssdev->dev),
+                               &dssdev->dev, dssdev, &taal_bl_ops, &props);
+               if (IS_ERR(bldev)) {
+                       r = PTR_ERR(bldev);
+                       goto err_bl;
+               }
+
+               td->bldev = bldev;
 
-       bldev->props.fb_blank = FB_BLANK_UNBLANK;
-       bldev->props.power = FB_BLANK_UNBLANK;
-       if (td->use_dsi_bl)
+               bldev->props.fb_blank = FB_BLANK_UNBLANK;
+               bldev->props.power = FB_BLANK_UNBLANK;
                bldev->props.brightness = 255;
-       else
-               bldev->props.brightness = 127;
 
-       taal_bl_update_status(bldev);
+               taal_bl_update_status(bldev);
+       }
 
        if (panel_data->use_ext_te) {
                int gpio = panel_data->ext_te_gpio;
@@ -1111,7 +1078,8 @@ err_irq:
        if (panel_data->use_ext_te)
                gpio_free(panel_data->ext_te_gpio);
 err_gpio:
-       backlight_device_unregister(bldev);
+       if (bldev != NULL)
+               backlight_device_unregister(bldev);
 err_bl:
        destroy_workqueue(td->workqueue);
 err_wq:
@@ -1140,9 +1108,11 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
        }
 
        bldev = td->bldev;
-       bldev->props.power = FB_BLANK_POWERDOWN;
-       taal_bl_update_status(bldev);
-       backlight_device_unregister(bldev);
+       if (bldev != NULL) {
+               bldev->props.power = FB_BLANK_POWERDOWN;
+               taal_bl_update_status(bldev);
+               backlight_device_unregister(bldev);
+       }
 
        taal_cancel_ulps_work(dssdev);
        taal_cancel_esd_work(dssdev);
@@ -1195,7 +1165,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
        if (r)
                goto err;
 
-       r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
+       r = taal_dcs_write_1(td, MIPI_DCS_SET_PIXEL_FORMAT,
+               MIPI_DCS_PIXEL_FMT_24BIT);
        if (r)
                goto err;
 
@@ -1209,7 +1180,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
                        goto err;
        }
 
-       r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
+       r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_ON);
        if (r)
                goto err;
 
@@ -1246,7 +1217,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
        struct taal_data *td = dev_get_drvdata(&dssdev->dev);
        int r;
 
-       r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
+       r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
        if (!r)
                r = taal_sleep_in(td);
 
@@ -1529,9 +1500,9 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
        int r;
 
        if (enable)
-               r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
+               r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
        else
-               r = taal_dcs_write_0(td, DCS_TEAR_OFF);
+               r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
 
        if (!panel_data->use_ext_te)
                omapdss_dsi_enable_te(dssdev, enable);
@@ -1851,7 +1822,7 @@ static void taal_esd_work(struct work_struct *work)
                goto err;
        }
 
-       r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
+       r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1);
        if (r) {
                dev_err(&dssdev->dev, "failed to read Taal status\n");
                goto err;
@@ -1864,7 +1835,7 @@ static void taal_esd_work(struct work_struct *work)
                goto err;
        }
 
-       r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
+       r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2);
        if (r) {
                dev_err(&dssdev->dev, "failed to read Taal status\n");
                goto err;
@@ -1880,7 +1851,7 @@ static void taal_esd_work(struct work_struct *work)
        /* Self-diagnostics result is also shown on TE GPIO line. We need
         * to re-enable TE after self diagnostics */
        if (td->te_enabled && panel_data->use_ext_te) {
-               r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
+               r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
                if (r)
                        goto err;
        }
index 0d12524..7be7c06 100644 (file)
@@ -1,5 +1,5 @@
 menuconfig OMAP2_DSS
-        tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)"
+        tristate "OMAP2+ Display Subsystem support"
         depends on ARCH_OMAP2PLUS
         help
          OMAP2+ Display Subsystem support.
index 10d9d3b..bd34ac5 100644 (file)
@@ -6,4 +6,4 @@ omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
 omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
 omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
 omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
-                                   hdmi_omap4_panel.o
+                                   hdmi_panel.o ti_hdmi_4xxx_ip.o
index 76821fe..86ec12e 100644 (file)
@@ -145,6 +145,10 @@ static int dss_initialize_debugfs(void)
        debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir,
                        &venc_dump_regs, &dss_debug_fops);
 #endif
+#ifdef CONFIG_OMAP4_DSS_HDMI
+       debugfs_create_file("hdmi", S_IRUGO, dss_debugfs_dir,
+                       &hdmi_dump_regs, &dss_debug_fops);
+#endif
        return 0;
 }
 
index 0f3961a..6892cfd 100644 (file)
@@ -106,7 +106,7 @@ static struct {
        int irq;
        struct clk *dss_clk;
 
-       u32     fifo_size[3];
+       u32     fifo_size[MAX_DSS_OVERLAYS];
 
        spinlock_t irq_lock;
        u32 irq_error_mask;
@@ -171,172 +171,98 @@ static int dispc_get_ctx_loss_count(void)
 
 static void dispc_save_context(void)
 {
-       int i;
+       int i, j;
 
        DSSDBG("dispc_save_context\n");
 
        SR(IRQENABLE);
        SR(CONTROL);
        SR(CONFIG);
-       SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
-       SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
-       SR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
-       SR(TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
        SR(LINE_NUMBER);
-       SR(TIMING_H(OMAP_DSS_CHANNEL_LCD));
-       SR(TIMING_V(OMAP_DSS_CHANNEL_LCD));
-       SR(POL_FREQ(OMAP_DSS_CHANNEL_LCD));
-       SR(DIVISORo(OMAP_DSS_CHANNEL_LCD));
-       if (dss_has_feature(FEAT_GLOBAL_ALPHA))
+       if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+                       dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
                SR(GLOBAL_ALPHA);
-       SR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
-       SR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
        if (dss_has_feature(FEAT_MGR_LCD2)) {
                SR(CONTROL2);
-               SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
-               SR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
-               SR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
-               SR(TIMING_H(OMAP_DSS_CHANNEL_LCD2));
-               SR(TIMING_V(OMAP_DSS_CHANNEL_LCD2));
-               SR(POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
-               SR(DIVISORo(OMAP_DSS_CHANNEL_LCD2));
                SR(CONFIG2);
        }
 
-       SR(OVL_BA0(OMAP_DSS_GFX));
-       SR(OVL_BA1(OMAP_DSS_GFX));
-       SR(OVL_POSITION(OMAP_DSS_GFX));
-       SR(OVL_SIZE(OMAP_DSS_GFX));
-       SR(OVL_ATTRIBUTES(OMAP_DSS_GFX));
-       SR(OVL_FIFO_THRESHOLD(OMAP_DSS_GFX));
-       SR(OVL_ROW_INC(OMAP_DSS_GFX));
-       SR(OVL_PIXEL_INC(OMAP_DSS_GFX));
-       SR(OVL_WINDOW_SKIP(OMAP_DSS_GFX));
-       SR(OVL_TABLE_BA(OMAP_DSS_GFX));
+       for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
+               SR(DEFAULT_COLOR(i));
+               SR(TRANS_COLOR(i));
+               SR(SIZE_MGR(i));
+               if (i == OMAP_DSS_CHANNEL_DIGIT)
+                       continue;
+               SR(TIMING_H(i));
+               SR(TIMING_V(i));
+               SR(POL_FREQ(i));
+               SR(DIVISORo(i));
 
-       SR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD));
-       SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
-       SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
+               SR(DATA_CYCLE1(i));
+               SR(DATA_CYCLE2(i));
+               SR(DATA_CYCLE3(i));
 
-       if (dss_has_feature(FEAT_CPR)) {
-               SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
-               SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
-               SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
-       }
-       if (dss_has_feature(FEAT_MGR_LCD2)) {
                if (dss_has_feature(FEAT_CPR)) {
-                       SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
-                       SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
-                       SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
+                       SR(CPR_COEF_R(i));
+                       SR(CPR_COEF_G(i));
+                       SR(CPR_COEF_B(i));
                }
-
-               SR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
-               SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
-               SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
        }
 
-       if (dss_has_feature(FEAT_PRELOAD))
-               SR(OVL_PRELOAD(OMAP_DSS_GFX));
-
-       /* VID1 */
-       SR(OVL_BA0(OMAP_DSS_VIDEO1));
-       SR(OVL_BA1(OMAP_DSS_VIDEO1));
-       SR(OVL_POSITION(OMAP_DSS_VIDEO1));
-       SR(OVL_SIZE(OMAP_DSS_VIDEO1));
-       SR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO1));
-       SR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1));
-       SR(OVL_ROW_INC(OMAP_DSS_VIDEO1));
-       SR(OVL_PIXEL_INC(OMAP_DSS_VIDEO1));
-       SR(OVL_FIR(OMAP_DSS_VIDEO1));
-       SR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1));
-       SR(OVL_ACCU0(OMAP_DSS_VIDEO1));
-       SR(OVL_ACCU1(OMAP_DSS_VIDEO1));
-
-       for (i = 0; i < 8; i++)
-               SR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, i));
-
-       for (i = 0; i < 8; i++)
-               SR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, i));
-
-       for (i = 0; i < 5; i++)
-               SR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i));
-
-       if (dss_has_feature(FEAT_FIR_COEF_V)) {
-               for (i = 0; i < 8; i++)
-                       SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i));
-       }
-
-       if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
-               SR(OVL_BA0_UV(OMAP_DSS_VIDEO1));
-               SR(OVL_BA1_UV(OMAP_DSS_VIDEO1));
-               SR(OVL_FIR2(OMAP_DSS_VIDEO1));
-               SR(OVL_ACCU2_0(OMAP_DSS_VIDEO1));
-               SR(OVL_ACCU2_1(OMAP_DSS_VIDEO1));
-
-               for (i = 0; i < 8; i++)
-                       SR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, i));
-
-               for (i = 0; i < 8; i++)
-                       SR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, i));
-
-               for (i = 0; i < 8; i++)
-                       SR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, i));
-       }
-       if (dss_has_feature(FEAT_ATTR2))
-               SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
-
-       if (dss_has_feature(FEAT_PRELOAD))
-               SR(OVL_PRELOAD(OMAP_DSS_VIDEO1));
-
-       /* VID2 */
-       SR(OVL_BA0(OMAP_DSS_VIDEO2));
-       SR(OVL_BA1(OMAP_DSS_VIDEO2));
-       SR(OVL_POSITION(OMAP_DSS_VIDEO2));
-       SR(OVL_SIZE(OMAP_DSS_VIDEO2));
-       SR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO2));
-       SR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2));
-       SR(OVL_ROW_INC(OMAP_DSS_VIDEO2));
-       SR(OVL_PIXEL_INC(OMAP_DSS_VIDEO2));
-       SR(OVL_FIR(OMAP_DSS_VIDEO2));
-       SR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2));
-       SR(OVL_ACCU0(OMAP_DSS_VIDEO2));
-       SR(OVL_ACCU1(OMAP_DSS_VIDEO2));
+       for (i = 0; i < dss_feat_get_num_ovls(); i++) {
+               SR(OVL_BA0(i));
+               SR(OVL_BA1(i));
+               SR(OVL_POSITION(i));
+               SR(OVL_SIZE(i));
+               SR(OVL_ATTRIBUTES(i));
+               SR(OVL_FIFO_THRESHOLD(i));
+               SR(OVL_ROW_INC(i));
+               SR(OVL_PIXEL_INC(i));
+               if (dss_has_feature(FEAT_PRELOAD))
+                       SR(OVL_PRELOAD(i));
+               if (i == OMAP_DSS_GFX) {
+                       SR(OVL_WINDOW_SKIP(i));
+                       SR(OVL_TABLE_BA(i));
+                       continue;
+               }
+               SR(OVL_FIR(i));
+               SR(OVL_PICTURE_SIZE(i));
+               SR(OVL_ACCU0(i));
+               SR(OVL_ACCU1(i));
 
-       for (i = 0; i < 8; i++)
-               SR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, i));
+               for (j = 0; j < 8; j++)
+                       SR(OVL_FIR_COEF_H(i, j));
 
-       for (i = 0; i < 8; i++)
-               SR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, i));
+               for (j = 0; j < 8; j++)
+                       SR(OVL_FIR_COEF_HV(i, j));
 
-       for (i = 0; i < 5; i++)
-               SR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i));
+               for (j = 0; j < 5; j++)
+                       SR(OVL_CONV_COEF(i, j));
 
-       if (dss_has_feature(FEAT_FIR_COEF_V)) {
-               for (i = 0; i < 8; i++)
-                       SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i));
-       }
+               if (dss_has_feature(FEAT_FIR_COEF_V)) {
+                       for (j = 0; j < 8; j++)
+                               SR(OVL_FIR_COEF_V(i, j));
+               }
 
-       if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
-               SR(OVL_BA0_UV(OMAP_DSS_VIDEO2));
-               SR(OVL_BA1_UV(OMAP_DSS_VIDEO2));
-               SR(OVL_FIR2(OMAP_DSS_VIDEO2));
-               SR(OVL_ACCU2_0(OMAP_DSS_VIDEO2));
-               SR(OVL_ACCU2_1(OMAP_DSS_VIDEO2));
+               if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+                       SR(OVL_BA0_UV(i));
+                       SR(OVL_BA1_UV(i));
+                       SR(OVL_FIR2(i));
+                       SR(OVL_ACCU2_0(i));
+                       SR(OVL_ACCU2_1(i));
 
-               for (i = 0; i < 8; i++)
-                       SR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, i));
+                       for (j = 0; j < 8; j++)
+                               SR(OVL_FIR_COEF_H2(i, j));
 
-               for (i = 0; i < 8; i++)
-                       SR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, i));
+                       for (j = 0; j < 8; j++)
+                               SR(OVL_FIR_COEF_HV2(i, j));
 
-               for (i = 0; i < 8; i++)
-                       SR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, i));
+                       for (j = 0; j < 8; j++)
+                               SR(OVL_FIR_COEF_V2(i, j));
+               }
+               if (dss_has_feature(FEAT_ATTR2))
+                       SR(OVL_ATTRIBUTES2(i));
        }
-       if (dss_has_feature(FEAT_ATTR2))
-               SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
-
-       if (dss_has_feature(FEAT_PRELOAD))
-               SR(OVL_PRELOAD(OMAP_DSS_VIDEO2));
 
        if (dss_has_feature(FEAT_CORE_CLK_DIV))
                SR(DIVISOR);
@@ -349,7 +275,7 @@ static void dispc_save_context(void)
 
 static void dispc_restore_context(void)
 {
-       int i, ctx;
+       int i, j, ctx;
 
        DSSDBG("dispc_restore_context\n");
 
@@ -367,165 +293,89 @@ static void dispc_restore_context(void)
        /*RR(IRQENABLE);*/
        /*RR(CONTROL);*/
        RR(CONFIG);
-       RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
-       RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
-       RR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
-       RR(TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
        RR(LINE_NUMBER);
-       RR(TIMING_H(OMAP_DSS_CHANNEL_LCD));
-       RR(TIMING_V(OMAP_DSS_CHANNEL_LCD));
-       RR(POL_FREQ(OMAP_DSS_CHANNEL_LCD));
-       RR(DIVISORo(OMAP_DSS_CHANNEL_LCD));
-       if (dss_has_feature(FEAT_GLOBAL_ALPHA))
+       if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+                       dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
                RR(GLOBAL_ALPHA);
-       RR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
-       RR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
-       if (dss_has_feature(FEAT_MGR_LCD2)) {
-               RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
-               RR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
-               RR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
-               RR(TIMING_H(OMAP_DSS_CHANNEL_LCD2));
-               RR(TIMING_V(OMAP_DSS_CHANNEL_LCD2));
-               RR(POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
-               RR(DIVISORo(OMAP_DSS_CHANNEL_LCD2));
+       if (dss_has_feature(FEAT_MGR_LCD2))
                RR(CONFIG2);
-       }
-
-       RR(OVL_BA0(OMAP_DSS_GFX));
-       RR(OVL_BA1(OMAP_DSS_GFX));
-       RR(OVL_POSITION(OMAP_DSS_GFX));
-       RR(OVL_SIZE(OMAP_DSS_GFX));
-       RR(OVL_ATTRIBUTES(OMAP_DSS_GFX));
-       RR(OVL_FIFO_THRESHOLD(OMAP_DSS_GFX));
-       RR(OVL_ROW_INC(OMAP_DSS_GFX));
-       RR(OVL_PIXEL_INC(OMAP_DSS_GFX));
-       RR(OVL_WINDOW_SKIP(OMAP_DSS_GFX));
-       RR(OVL_TABLE_BA(OMAP_DSS_GFX));
-
 
-       RR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD));
-       RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
-       RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
+       for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
+               RR(DEFAULT_COLOR(i));
+               RR(TRANS_COLOR(i));
+               RR(SIZE_MGR(i));
+               if (i == OMAP_DSS_CHANNEL_DIGIT)
+                       continue;
+               RR(TIMING_H(i));
+               RR(TIMING_V(i));
+               RR(POL_FREQ(i));
+               RR(DIVISORo(i));
 
-       if (dss_has_feature(FEAT_CPR)) {
-               RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
-               RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
-               RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
-       }
-       if (dss_has_feature(FEAT_MGR_LCD2)) {
-               RR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
-               RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
-               RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
+               RR(DATA_CYCLE1(i));
+               RR(DATA_CYCLE2(i));
+               RR(DATA_CYCLE3(i));
 
                if (dss_has_feature(FEAT_CPR)) {
-                       RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
-                       RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
-                       RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
+                       RR(CPR_COEF_R(i));
+                       RR(CPR_COEF_G(i));
+                       RR(CPR_COEF_B(i));
                }
        }
 
-       if (dss_has_feature(FEAT_PRELOAD))
-               RR(OVL_PRELOAD(OMAP_DSS_GFX));
-
-       /* VID1 */
-       RR(OVL_BA0(OMAP_DSS_VIDEO1));
-       RR(OVL_BA1(OMAP_DSS_VIDEO1));
-       RR(OVL_POSITION(OMAP_DSS_VIDEO1));
-       RR(OVL_SIZE(OMAP_DSS_VIDEO1));
-       RR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO1));
-       RR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1));
-       RR(OVL_ROW_INC(OMAP_DSS_VIDEO1));
-       RR(OVL_PIXEL_INC(OMAP_DSS_VIDEO1));
-       RR(OVL_FIR(OMAP_DSS_VIDEO1));
-       RR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1));
-       RR(OVL_ACCU0(OMAP_DSS_VIDEO1));
-       RR(OVL_ACCU1(OMAP_DSS_VIDEO1));
-
-       for (i = 0; i < 8; i++)
-               RR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, i));
-
-       for (i = 0; i < 8; i++)
-               RR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, i));
-
-       for (i = 0; i < 5; i++)
-               RR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i));
-
-       if (dss_has_feature(FEAT_FIR_COEF_V)) {
-               for (i = 0; i < 8; i++)
-                       RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i));
-       }
-
-       if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
-               RR(OVL_BA0_UV(OMAP_DSS_VIDEO1));
-               RR(OVL_BA1_UV(OMAP_DSS_VIDEO1));
-               RR(OVL_FIR2(OMAP_DSS_VIDEO1));
-               RR(OVL_ACCU2_0(OMAP_DSS_VIDEO1));
-               RR(OVL_ACCU2_1(OMAP_DSS_VIDEO1));
-
-               for (i = 0; i < 8; i++)
-                       RR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, i));
-
-               for (i = 0; i < 8; i++)
-                       RR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, i));
-
-               for (i = 0; i < 8; i++)
-                       RR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, i));
-       }
-       if (dss_has_feature(FEAT_ATTR2))
-               RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
-
-       if (dss_has_feature(FEAT_PRELOAD))
-               RR(OVL_PRELOAD(OMAP_DSS_VIDEO1));
-
-       /* VID2 */
-       RR(OVL_BA0(OMAP_DSS_VIDEO2));
-       RR(OVL_BA1(OMAP_DSS_VIDEO2));
-       RR(OVL_POSITION(OMAP_DSS_VIDEO2));
-       RR(OVL_SIZE(OMAP_DSS_VIDEO2));
-       RR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO2));
-       RR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2));
-       RR(OVL_ROW_INC(OMAP_DSS_VIDEO2));
-       RR(OVL_PIXEL_INC(OMAP_DSS_VIDEO2));
-       RR(OVL_FIR(OMAP_DSS_VIDEO2));
-       RR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2));
-       RR(OVL_ACCU0(OMAP_DSS_VIDEO2));
-       RR(OVL_ACCU1(OMAP_DSS_VIDEO2));
+       for (i = 0; i < dss_feat_get_num_ovls(); i++) {
+               RR(OVL_BA0(i));
+               RR(OVL_BA1(i));
+               RR(OVL_POSITION(i));
+               RR(OVL_SIZE(i));
+               RR(OVL_ATTRIBUTES(i));
+               RR(OVL_FIFO_THRESHOLD(i));
+               RR(OVL_ROW_INC(i));
+               RR(OVL_PIXEL_INC(i));
+               if (dss_has_feature(FEAT_PRELOAD))
+                       RR(OVL_PRELOAD(i));
+               if (i == OMAP_DSS_GFX) {
+                       RR(OVL_WINDOW_SKIP(i));
+                       RR(OVL_TABLE_BA(i));
+                       continue;
+               }
+               RR(OVL_FIR(i));
+               RR(OVL_PICTURE_SIZE(i));
+               RR(OVL_ACCU0(i));
+               RR(OVL_ACCU1(i));
 
-       for (i = 0; i < 8; i++)
-               RR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, i));
+               for (j = 0; j < 8; j++)
+                       RR(OVL_FIR_COEF_H(i, j));
 
-       for (i = 0; i < 8; i++)
-               RR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, i));
+               for (j = 0; j < 8; j++)
+                       RR(OVL_FIR_COEF_HV(i, j));
 
-       for (i = 0; i < 5; i++)
-               RR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i));
+               for (j = 0; j < 5; j++)
+                       RR(OVL_CONV_COEF(i, j));
 
-       if (dss_has_feature(FEAT_FIR_COEF_V)) {
-               for (i = 0; i < 8; i++)
-                       RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i));
-       }
+               if (dss_has_feature(FEAT_FIR_COEF_V)) {
+                       for (j = 0; j < 8; j++)
+                               RR(OVL_FIR_COEF_V(i, j));
+               }
 
-       if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
-               RR(OVL_BA0_UV(OMAP_DSS_VIDEO2));
-               RR(OVL_BA1_UV(OMAP_DSS_VIDEO2));
-               RR(OVL_FIR2(OMAP_DSS_VIDEO2));
-               RR(OVL_ACCU2_0(OMAP_DSS_VIDEO2));
-               RR(OVL_ACCU2_1(OMAP_DSS_VIDEO2));
+               if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+                       RR(OVL_BA0_UV(i));
+                       RR(OVL_BA1_UV(i));
+                       RR(OVL_FIR2(i));
+                       RR(OVL_ACCU2_0(i));
+                       RR(OVL_ACCU2_1(i));
 
-               for (i = 0; i < 8; i++)
-                       RR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, i));
+                       for (j = 0; j < 8; j++)
+                               RR(OVL_FIR_COEF_H2(i, j));
 
-               for (i = 0; i < 8; i++)
-                       RR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, i));
+                       for (j = 0; j < 8; j++)
+                               RR(OVL_FIR_COEF_HV2(i, j));
 
-               for (i = 0; i < 8; i++)
-                       RR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, i));
+                       for (j = 0; j < 8; j++)
+                               RR(OVL_FIR_COEF_V2(i, j));
+               }
+               if (dss_has_feature(FEAT_ATTR2))
+                       RR(OVL_ATTRIBUTES2(i));
        }
-       if (dss_has_feature(FEAT_ATTR2))
-               RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
-
-       if (dss_has_feature(FEAT_PRELOAD))
-               RR(OVL_PRELOAD(OMAP_DSS_VIDEO2));
 
        if (dss_has_feature(FEAT_CORE_CLK_DIV))
                RR(DIVISOR);
@@ -570,13 +420,28 @@ void dispc_runtime_put(void)
        WARN_ON(r < 0);
 }
 
+static inline bool dispc_mgr_is_lcd(enum omap_channel channel)
+{
+       if (channel == OMAP_DSS_CHANNEL_LCD ||
+                       channel == OMAP_DSS_CHANNEL_LCD2)
+               return true;
+       else
+               return false;
+}
+
+static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel)
+{
+       struct omap_overlay_manager *mgr =
+               omap_dss_get_overlay_manager(channel);
 
-bool dispc_go_busy(enum omap_channel channel)
+       return mgr ? mgr->device : NULL;
+}
+
+bool dispc_mgr_go_busy(enum omap_channel channel)
 {
        int bit;
 
-       if (channel == OMAP_DSS_CHANNEL_LCD ||
-                       channel == OMAP_DSS_CHANNEL_LCD2)
+       if (dispc_mgr_is_lcd(channel))
                bit = 5; /* GOLCD */
        else
                bit = 6; /* GODIGIT */
@@ -587,13 +452,12 @@ bool dispc_go_busy(enum omap_channel channel)
                return REG_GET(DISPC_CONTROL, bit, bit) == 1;
 }
 
-void dispc_go(enum omap_channel channel)
+void dispc_mgr_go(enum omap_channel channel)
 {
        int bit;
        bool enable_bit, go_bit;
 
-       if (channel == OMAP_DSS_CHANNEL_LCD ||
-                       channel == OMAP_DSS_CHANNEL_LCD2)
+       if (dispc_mgr_is_lcd(channel))
                bit = 0; /* LCDENABLE */
        else
                bit = 1; /* DIGITALENABLE */
@@ -607,8 +471,7 @@ void dispc_go(enum omap_channel channel)
        if (!enable_bit)
                return;
 
-       if (channel == OMAP_DSS_CHANNEL_LCD ||
-                       channel == OMAP_DSS_CHANNEL_LCD2)
+       if (dispc_mgr_is_lcd(channel))
                bit = 5; /* GOLCD */
        else
                bit = 6; /* GODIGIT */
@@ -632,43 +495,44 @@ void dispc_go(enum omap_channel channel)
                REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
 }
 
-static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value)
+static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
 {
        dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value);
 }
 
-static void _dispc_write_firhv_reg(enum omap_plane plane, int reg, u32 value)
+static void dispc_ovl_write_firhv_reg(enum omap_plane plane, int reg, u32 value)
 {
        dispc_write_reg(DISPC_OVL_FIR_COEF_HV(plane, reg), value);
 }
 
-static void _dispc_write_firv_reg(enum omap_plane plane, int reg, u32 value)
+static void dispc_ovl_write_firv_reg(enum omap_plane plane, int reg, u32 value)
 {
        dispc_write_reg(DISPC_OVL_FIR_COEF_V(plane, reg), value);
 }
 
-static void _dispc_write_firh2_reg(enum omap_plane plane, int reg, u32 value)
+static void dispc_ovl_write_firh2_reg(enum omap_plane plane, int reg, u32 value)
 {
        BUG_ON(plane == OMAP_DSS_GFX);
 
        dispc_write_reg(DISPC_OVL_FIR_COEF_H2(plane, reg), value);
 }
 
-static void _dispc_write_firhv2_reg(enum omap_plane plane, int reg, u32 value)
+static void dispc_ovl_write_firhv2_reg(enum omap_plane plane, int reg,
+               u32 value)
 {
        BUG_ON(plane == OMAP_DSS_GFX);
 
        dispc_write_reg(DISPC_OVL_FIR_COEF_HV2(plane, reg), value);
 }
 
-static void _dispc_write_firv2_reg(enum omap_plane plane, int reg, u32 value)
+static void dispc_ovl_write_firv2_reg(enum omap_plane plane, int reg, u32 value)
 {
        BUG_ON(plane == OMAP_DSS_GFX);
 
        dispc_write_reg(DISPC_OVL_FIR_COEF_V2(plane, reg), value);
 }
 
-static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
+static void dispc_ovl_set_scale_coef(enum omap_plane plane, int hscaleup,
                                  int vscaleup, int five_taps,
                                  enum omap_color_component color_comp)
 {
@@ -769,11 +633,11 @@ static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
                        | FLD_VAL(v_coef[i].vc2, 31, 24);
 
                if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
-                       _dispc_write_firh_reg(plane, i, h);
-                       _dispc_write_firhv_reg(plane, i, hv);
+                       dispc_ovl_write_firh_reg(plane, i, h);
+                       dispc_ovl_write_firhv_reg(plane, i, hv);
                } else {
-                       _dispc_write_firh2_reg(plane, i, h);
-                       _dispc_write_firhv2_reg(plane, i, hv);
+                       dispc_ovl_write_firh2_reg(plane, i, h);
+                       dispc_ovl_write_firhv2_reg(plane, i, hv);
                }
 
        }
@@ -784,15 +648,16 @@ static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
                        v = FLD_VAL(v_coef[i].vc00, 7, 0)
                                | FLD_VAL(v_coef[i].vc22, 15, 8);
                        if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y)
-                               _dispc_write_firv_reg(plane, i, v);
+                               dispc_ovl_write_firv_reg(plane, i, v);
                        else
-                               _dispc_write_firv2_reg(plane, i, v);
+                               dispc_ovl_write_firv2_reg(plane, i, v);
                }
        }
 }
 
 static void _dispc_setup_color_conv_coef(void)
 {
+       int i;
        const struct color_conv_coef {
                int  ry,  rcr,  rcb,   gy,  gcr,  gcb,   by,  bcr,  bcb;
                int  full_range;
@@ -806,65 +671,54 @@ static void _dispc_setup_color_conv_coef(void)
 
        ct = &ctbl_bt601_5;
 
-       dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 0),
-               CVAL(ct->rcr, ct->ry));
-       dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 1),
-               CVAL(ct->gy,  ct->rcb));
-       dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 2),
-               CVAL(ct->gcb, ct->gcr));
-       dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 3),
-               CVAL(ct->bcr, ct->by));
-       dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 4),
-               CVAL(0, ct->bcb));
-
-       dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 0),
-               CVAL(ct->rcr, ct->ry));
-       dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 1),
-               CVAL(ct->gy, ct->rcb));
-       dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 2),
-               CVAL(ct->gcb, ct->gcr));
-       dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 3),
-               CVAL(ct->bcr, ct->by));
-       dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 4),
-               CVAL(0, ct->bcb));
+       for (i = 1; i < dss_feat_get_num_ovls(); i++) {
+               dispc_write_reg(DISPC_OVL_CONV_COEF(i, 0),
+                       CVAL(ct->rcr, ct->ry));
+               dispc_write_reg(DISPC_OVL_CONV_COEF(i, 1),
+                       CVAL(ct->gy,  ct->rcb));
+               dispc_write_reg(DISPC_OVL_CONV_COEF(i, 2),
+                       CVAL(ct->gcb, ct->gcr));
+               dispc_write_reg(DISPC_OVL_CONV_COEF(i, 3),
+                       CVAL(ct->bcr, ct->by));
+               dispc_write_reg(DISPC_OVL_CONV_COEF(i, 4),
+                       CVAL(0, ct->bcb));
 
-#undef CVAL
+               REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), ct->full_range,
+                       11, 11);
+       }
 
-       REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO1),
-               ct->full_range, 11, 11);
-       REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO2),
-               ct->full_range, 11, 11);
+#undef CVAL
 }
 
 
-static void _dispc_set_plane_ba0(enum omap_plane plane, u32 paddr)
+static void dispc_ovl_set_ba0(enum omap_plane plane, u32 paddr)
 {
        dispc_write_reg(DISPC_OVL_BA0(plane), paddr);
 }
 
-static void _dispc_set_plane_ba1(enum omap_plane plane, u32 paddr)
+static void dispc_ovl_set_ba1(enum omap_plane plane, u32 paddr)
 {
        dispc_write_reg(DISPC_OVL_BA1(plane), paddr);
 }
 
-static void _dispc_set_plane_ba0_uv(enum omap_plane plane, u32 paddr)
+static void dispc_ovl_set_ba0_uv(enum omap_plane plane, u32 paddr)
 {
        dispc_write_reg(DISPC_OVL_BA0_UV(plane), paddr);
 }
 
-static void _dispc_set_plane_ba1_uv(enum omap_plane plane, u32 paddr)
+static void dispc_ovl_set_ba1_uv(enum omap_plane plane, u32 paddr)
 {
        dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr);
 }
 
-static void _dispc_set_plane_pos(enum omap_plane plane, int x, int y)
+static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y)
 {
        u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
 
        dispc_write_reg(DISPC_OVL_POSITION(plane), val);
 }
 
-static void _dispc_set_pic_size(enum omap_plane plane, int width, int height)
+static void dispc_ovl_set_pic_size(enum omap_plane plane, int width, int height)
 {
        u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
 
@@ -874,7 +728,7 @@ static void _dispc_set_pic_size(enum omap_plane plane, int width, int height)
                dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
 }
 
-static void _dispc_set_vid_size(enum omap_plane plane, int width, int height)
+static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height)
 {
        u32 val;
 
@@ -885,44 +739,61 @@ static void _dispc_set_vid_size(enum omap_plane plane, int width, int height)
        dispc_write_reg(DISPC_OVL_SIZE(plane), val);
 }
 
-static void _dispc_set_pre_mult_alpha(enum omap_plane plane, bool enable)
+static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder)
 {
-       if (!dss_has_feature(FEAT_PRE_MULT_ALPHA))
+       struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+
+       if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
                return;
 
-       if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
-               plane == OMAP_DSS_VIDEO1)
+       REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26);
+}
+
+static void dispc_ovl_enable_zorder_planes(void)
+{
+       int i;
+
+       if (!dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
                return;
 
-       REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28);
+       for (i = 0; i < dss_feat_get_num_ovls(); i++)
+               REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
 }
 
-static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
+static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable)
 {
-       if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
+       struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+
+       if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
                return;
 
-       if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
-               plane == OMAP_DSS_VIDEO1)
+       REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28);
+}
+
+static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
+{
+       static const unsigned shifts[] = { 0, 8, 16, 24, };
+       int shift;
+       struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+
+       if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
                return;
 
-       if (plane == OMAP_DSS_GFX)
-               REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 7, 0);
-       else if (plane == OMAP_DSS_VIDEO2)
-               REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 23, 16);
+       shift = shifts[plane];
+       REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, shift + 7, shift);
 }
 
-static void _dispc_set_pix_inc(enum omap_plane plane, s32 inc)
+static void dispc_ovl_set_pix_inc(enum omap_plane plane, s32 inc)
 {
        dispc_write_reg(DISPC_OVL_PIXEL_INC(plane), inc);
 }
 
-static void _dispc_set_row_inc(enum omap_plane plane, s32 inc)
+static void dispc_ovl_set_row_inc(enum omap_plane plane, s32 inc)
 {
        dispc_write_reg(DISPC_OVL_ROW_INC(plane), inc);
 }
 
-static void _dispc_set_color_mode(enum omap_plane plane,
+static void dispc_ovl_set_color_mode(enum omap_plane plane,
                enum omap_color_mode color_mode)
 {
        u32 m = 0;
@@ -1003,7 +874,7 @@ static void _dispc_set_color_mode(enum omap_plane plane,
        REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1);
 }
 
-void dispc_set_channel_out(enum omap_plane plane,
+static void dispc_ovl_set_channel_out(enum omap_plane plane,
                enum omap_channel channel)
 {
        int shift;
@@ -1016,6 +887,7 @@ void dispc_set_channel_out(enum omap_plane plane,
                break;
        case OMAP_DSS_VIDEO1:
        case OMAP_DSS_VIDEO2:
+       case OMAP_DSS_VIDEO3:
                shift = 16;
                break;
        default:
@@ -1050,24 +922,13 @@ void dispc_set_channel_out(enum omap_plane plane,
        dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
 }
 
-static void dispc_set_burst_size(enum omap_plane plane,
+static void dispc_ovl_set_burst_size(enum omap_plane plane,
                enum omap_burst_size burst_size)
 {
+       static const unsigned shifts[] = { 6, 14, 14, 14, };
        int shift;
 
-       switch (plane) {
-       case OMAP_DSS_GFX:
-               shift = 6;
-               break;
-       case OMAP_DSS_VIDEO1:
-       case OMAP_DSS_VIDEO2:
-               shift = 14;
-               break;
-       default:
-               BUG();
-               return;
-       }
-
+       shift = shifts[plane];
        REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), burst_size, shift + 1, shift);
 }
 
@@ -1078,10 +939,10 @@ static void dispc_configure_burst_sizes(void)
 
        /* Configure burst size always to maximum size */
        for (i = 0; i < omap_dss_get_num_overlays(); ++i)
-               dispc_set_burst_size(i, burst_size);
+               dispc_ovl_set_burst_size(i, burst_size);
 }
 
-u32 dispc_get_burst_size(enum omap_plane plane)
+u32 dispc_ovl_get_burst_size(enum omap_plane plane)
 {
        unsigned unit = dss_feat_get_burst_size_unit();
        /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
@@ -1102,7 +963,7 @@ void dispc_enable_gamma_table(bool enable)
        REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
 }
 
-void dispc_enable_cpr(enum omap_channel channel, bool enable)
+void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
 {
        u16 reg;
 
@@ -1116,12 +977,12 @@ void dispc_enable_cpr(enum omap_channel channel, bool enable)
        REG_FLD_MOD(reg, enable, 15, 15);
 }
 
-void dispc_set_cpr_coef(enum omap_channel channel,
+void dispc_mgr_set_cpr_coef(enum omap_channel channel,
                struct omap_dss_cpr_coefs *coefs)
 {
        u32 coef_r, coef_g, coef_b;
 
-       if (channel != OMAP_DSS_CHANNEL_LCD && channel != OMAP_DSS_CHANNEL_LCD2)
+       if (!dispc_mgr_is_lcd(channel))
                return;
 
        coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) |
@@ -1136,7 +997,7 @@ void dispc_set_cpr_coef(enum omap_channel channel,
        dispc_write_reg(DISPC_CPR_COEF_B(channel), coef_b);
 }
 
-static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
+static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable)
 {
        u32 val;
 
@@ -1147,19 +1008,16 @@ static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
        dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
 }
 
-void dispc_enable_replication(enum omap_plane plane, bool enable)
+static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable)
 {
-       int bit;
-
-       if (plane == OMAP_DSS_GFX)
-               bit = 5;
-       else
-               bit = 10;
+       static const unsigned shifts[] = { 5, 10, 10, 10 };
+       int shift;
 
-       REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit);
+       shift = shifts[plane];
+       REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift);
 }
 
-void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
+void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
 {
        u32 val;
        BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
@@ -1186,19 +1044,20 @@ static void dispc_read_plane_fifo_sizes(void)
 
        dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
 
-       for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) {
+       for (plane = 0; plane < dss_feat_get_num_ovls(); ++plane) {
                size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end);
                size *= unit;
                dispc.fifo_size[plane] = size;
        }
 }
 
-u32 dispc_get_plane_fifo_size(enum omap_plane plane)
+u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
 {
        return dispc.fifo_size[plane];
 }
 
-void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
+static void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low,
+               u32 high)
 {
        u8 hi_start, hi_end, lo_start, lo_end;
        u32 unit;
@@ -1233,7 +1092,7 @@ void dispc_enable_fifomerge(bool enable)
        REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
 }
 
-static void _dispc_set_fir(enum omap_plane plane,
+static void dispc_ovl_set_fir(enum omap_plane plane,
                                int hinc, int vinc,
                                enum omap_color_component color_comp)
 {
@@ -1256,7 +1115,7 @@ static void _dispc_set_fir(enum omap_plane plane,
        }
 }
 
-static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
+static void dispc_ovl_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
 {
        u32 val;
        u8 hor_start, hor_end, vert_start, vert_end;
@@ -1270,7 +1129,7 @@ static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
        dispc_write_reg(DISPC_OVL_ACCU0(plane), val);
 }
 
-static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
+static void dispc_ovl_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
 {
        u32 val;
        u8 hor_start, hor_end, vert_start, vert_end;
@@ -1284,7 +1143,8 @@ static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
        dispc_write_reg(DISPC_OVL_ACCU1(plane), val);
 }
 
-static void _dispc_set_vid_accu2_0(enum omap_plane plane, int haccu, int vaccu)
+static void dispc_ovl_set_vid_accu2_0(enum omap_plane plane, int haccu,
+               int vaccu)
 {
        u32 val;
 
@@ -1292,7 +1152,8 @@ static void _dispc_set_vid_accu2_0(enum omap_plane plane, int haccu, int vaccu)
        dispc_write_reg(DISPC_OVL_ACCU2_0(plane), val);
 }
 
-static void _dispc_set_vid_accu2_1(enum omap_plane plane, int haccu, int vaccu)
+static void dispc_ovl_set_vid_accu2_1(enum omap_plane plane, int haccu,
+               int vaccu)
 {
        u32 val;
 
@@ -1300,7 +1161,7 @@ static void _dispc_set_vid_accu2_1(enum omap_plane plane, int haccu, int vaccu)
        dispc_write_reg(DISPC_OVL_ACCU2_1(plane), val);
 }
 
-static void _dispc_set_scale_param(enum omap_plane plane,
+static void dispc_ovl_set_scale_param(enum omap_plane plane,
                u16 orig_width, u16 orig_height,
                u16 out_width, u16 out_height,
                bool five_taps, u8 rotation,
@@ -1312,15 +1173,16 @@ static void _dispc_set_scale_param(enum omap_plane plane,
        hscaleup = orig_width <= out_width;
        vscaleup = orig_height <= out_height;
 
-       _dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps, color_comp);
+       dispc_ovl_set_scale_coef(plane, hscaleup, vscaleup, five_taps,
+                       color_comp);
 
        fir_hinc = 1024 * orig_width / out_width;
        fir_vinc = 1024 * orig_height / out_height;
 
-       _dispc_set_fir(plane, fir_hinc, fir_vinc, color_comp);
+       dispc_ovl_set_fir(plane, fir_hinc, fir_vinc, color_comp);
 }
 
-static void _dispc_set_scaling_common(enum omap_plane plane,
+static void dispc_ovl_set_scaling_common(enum omap_plane plane,
                u16 orig_width, u16 orig_height,
                u16 out_width, u16 out_height,
                bool ilace, bool five_taps,
@@ -1331,7 +1193,7 @@ static void _dispc_set_scaling_common(enum omap_plane plane,
        int accu1 = 0;
        u32 l;
 
-       _dispc_set_scale_param(plane, orig_width, orig_height,
+       dispc_ovl_set_scale_param(plane, orig_width, orig_height,
                                out_width, out_height, five_taps,
                                rotation, DISPC_COLOR_COMPONENT_RGB_Y);
        l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
@@ -1370,11 +1232,11 @@ static void _dispc_set_scaling_common(enum omap_plane plane,
                }
        }
 
-       _dispc_set_vid_accu0(plane, 0, accu0);
-       _dispc_set_vid_accu1(plane, 0, accu1);
+       dispc_ovl_set_vid_accu0(plane, 0, accu0);
+       dispc_ovl_set_vid_accu1(plane, 0, accu1);
 }
 
-static void _dispc_set_scaling_uv(enum omap_plane plane,
+static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
                u16 orig_width, u16 orig_height,
                u16 out_width, u16 out_height,
                bool ilace, bool five_taps,
@@ -1422,7 +1284,7 @@ static void _dispc_set_scaling_uv(enum omap_plane plane,
        if (out_height != orig_height)
                scale_y = true;
 
-       _dispc_set_scale_param(plane, orig_width, orig_height,
+       dispc_ovl_set_scale_param(plane, orig_width, orig_height,
                        out_width, out_height, five_taps,
                                rotation, DISPC_COLOR_COMPONENT_UV);
 
@@ -1433,11 +1295,11 @@ static void _dispc_set_scaling_uv(enum omap_plane plane,
        /* set V scaling */
        REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6);
 
-       _dispc_set_vid_accu2_0(plane, 0x80, 0);
-       _dispc_set_vid_accu2_1(plane, 0x80, 0);
+       dispc_ovl_set_vid_accu2_0(plane, 0x80, 0);
+       dispc_ovl_set_vid_accu2_1(plane, 0x80, 0);
 }
 
-static void _dispc_set_scaling(enum omap_plane plane,
+static void dispc_ovl_set_scaling(enum omap_plane plane,
                u16 orig_width, u16 orig_height,
                u16 out_width, u16 out_height,
                bool ilace, bool five_taps,
@@ -1446,14 +1308,14 @@ static void _dispc_set_scaling(enum omap_plane plane,
 {
        BUG_ON(plane == OMAP_DSS_GFX);
 
-       _dispc_set_scaling_common(plane,
+       dispc_ovl_set_scaling_common(plane,
                        orig_width, orig_height,
                        out_width, out_height,
                        ilace, five_taps,
                        fieldmode, color_mode,
                        rotation);
 
-       _dispc_set_scaling_uv(plane,
+       dispc_ovl_set_scaling_uv(plane,
                orig_width, orig_height,
                out_width, out_height,
                ilace, five_taps,
@@ -1461,7 +1323,7 @@ static void _dispc_set_scaling(enum omap_plane plane,
                rotation);
 }
 
-static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
+static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation,
                bool mirroring, enum omap_color_mode color_mode)
 {
        bool row_repeat = false;
@@ -1789,12 +1651,11 @@ static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
                enum omap_color_mode color_mode)
 {
        u32 fclk = 0;
-       /* FIXME venc pclk? */
-       u64 tmp, pclk = dispc_pclk_rate(channel);
+       u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
 
        if (height > out_height) {
-               /* FIXME get real display PPL */
-               unsigned int ppl = 800;
+               struct omap_dss_device *dssdev = dispc_mgr_get_device(channel);
+               unsigned int ppl = dssdev->panel.timings.x_res;
 
                tmp = pclk * height * out_width;
                do_div(tmp, 2 * out_height * ppl);
@@ -1846,114 +1707,120 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
        else
                vf = 1;
 
-       /* FIXME venc pclk? */
-       return dispc_pclk_rate(channel) * vf * hf;
+       return dispc_mgr_pclk_rate(channel) * vf * hf;
 }
 
-int dispc_setup_plane(enum omap_plane plane,
-               u32 paddr, u16 screen_width,
-               u16 pos_x, u16 pos_y,
-               u16 width, u16 height,
+static int dispc_ovl_calc_scaling(enum omap_plane plane,
+               enum omap_channel channel, u16 width, u16 height,
                u16 out_width, u16 out_height,
-               enum omap_color_mode color_mode,
-               bool ilace,
-               enum omap_dss_rotation_type rotation_type,
-               u8 rotation, bool mirror,
-               u8 global_alpha, u8 pre_mult_alpha,
-               enum omap_channel channel, u32 puv_addr)
-{
-       const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
-       bool five_taps = 0;
-       bool fieldmode = 0;
-       int cconv = 0;
-       unsigned offset0, offset1;
-       s32 row_inc;
-       s32 pix_inc;
-       u16 frame_height = height;
-       unsigned int field_offset = 0;
+               enum omap_color_mode color_mode, bool *five_taps)
+{
+       struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+       const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+       unsigned long fclk = 0;
 
-       DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> "
-              "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n",
-              plane, paddr, screen_width, pos_x, pos_y,
-              width, height,
-              out_width, out_height,
-              ilace, color_mode,
-              rotation, mirror, channel);
+       if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
+               if (width != out_width || height != out_height)
+                       return -EINVAL;
+               else
+                       return 0;
+       }
 
-       if (paddr == 0)
+       if (out_width < width / maxdownscale ||
+                       out_width > width * 8)
                return -EINVAL;
 
-       if (ilace && height == out_height)
-               fieldmode = 1;
+       if (out_height < height / maxdownscale ||
+                       out_height > height * 8)
+               return -EINVAL;
 
-       if (ilace) {
-               if (fieldmode)
-                       height /= 2;
-               pos_y /= 2;
-               out_height /= 2;
+       /* Must use 5-tap filter? */
+       *five_taps = height > out_height * 2;
 
-               DSSDBG("adjusting for ilace: height %d, pos_y %d, "
-                               "out_height %d\n",
-                               height, pos_y, out_height);
+       if (!*five_taps) {
+               fclk = calc_fclk(channel, width, height, out_width,
+                               out_height);
+
+               /* Try 5-tap filter if 3-tap fclk is too high */
+               if (cpu_is_omap34xx() && height > out_height &&
+                               fclk > dispc_fclk_rate())
+                       *five_taps = true;
        }
 
-       if (!dss_feat_color_mode_supported(plane, color_mode))
+       if (width > (2048 >> *five_taps)) {
+               DSSERR("failed to set up scaling, fclk too low\n");
                return -EINVAL;
+       }
 
-       if (plane == OMAP_DSS_GFX) {
-               if (width != out_width || height != out_height)
-                       return -EINVAL;
-       } else {
-               /* video plane */
+       if (*five_taps)
+               fclk = calc_fclk_five_taps(channel, width, height,
+                               out_width, out_height, color_mode);
 
-               unsigned long fclk = 0;
+       DSSDBG("required fclk rate = %lu Hz\n", fclk);
+       DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
 
-               if (out_width < width / maxdownscale ||
-                  out_width > width * 8)
-                       return -EINVAL;
+       if (!fclk || fclk > dispc_fclk_rate()) {
+               DSSERR("failed to set up scaling, "
+                       "required fclk rate = %lu Hz, "
+                       "current fclk rate = %lu Hz\n",
+                       fclk, dispc_fclk_rate());
+               return -EINVAL;
+       }
 
-               if (out_height < height / maxdownscale ||
-                  out_height > height * 8)
-                       return -EINVAL;
+       return 0;
+}
 
-               if (color_mode == OMAP_DSS_COLOR_YUV2 ||
-                       color_mode == OMAP_DSS_COLOR_UYVY ||
-                       color_mode == OMAP_DSS_COLOR_NV12)
-                       cconv = 1;
+int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
+               bool ilace, enum omap_channel channel, bool replication,
+               u32 fifo_low, u32 fifo_high)
+{
+       struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+       bool five_taps = false;
+       bool fieldmode = 0;
+       int r, cconv = 0;
+       unsigned offset0, offset1;
+       s32 row_inc;
+       s32 pix_inc;
+       u16 frame_height = oi->height;
+       unsigned int field_offset = 0;
 
-               /* Must use 5-tap filter? */
-               five_taps = height > out_height * 2;
+       DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
+               "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d "
+               "fifo_low %d fifo high %d\n", plane, oi->paddr, oi->p_uv_addr,
+               oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
+               oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
+               oi->mirror, ilace, channel, replication, fifo_low, fifo_high);
 
-               if (!five_taps) {
-                       fclk = calc_fclk(channel, width, height, out_width,
-                                       out_height);
+       if (oi->paddr == 0)
+               return -EINVAL;
 
-                       /* Try 5-tap filter if 3-tap fclk is too high */
-                       if (cpu_is_omap34xx() && height > out_height &&
-                                       fclk > dispc_fclk_rate())
-                               five_taps = true;
-               }
+       if (ilace && oi->height == oi->out_height)
+               fieldmode = 1;
 
-               if (width > (2048 >> five_taps)) {
-                       DSSERR("failed to set up scaling, fclk too low\n");
-                       return -EINVAL;
-               }
+       if (ilace) {
+               if (fieldmode)
+                       oi->height /= 2;
+               oi->pos_y /= 2;
+               oi->out_height /= 2;
 
-               if (five_taps)
-                       fclk = calc_fclk_five_taps(channel, width, height,
-                                       out_width, out_height, color_mode);
+               DSSDBG("adjusting for ilace: height %d, pos_y %d, "
+                               "out_height %d\n",
+                               oi->height, oi->pos_y, oi->out_height);
+       }
 
-               DSSDBG("required fclk rate = %lu Hz\n", fclk);
-               DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
+       if (!dss_feat_color_mode_supported(plane, oi->color_mode))
+               return -EINVAL;
 
-               if (!fclk || fclk > dispc_fclk_rate()) {
-                       DSSERR("failed to set up scaling, "
-                                       "required fclk rate = %lu Hz, "
-                                       "current fclk rate = %lu Hz\n",
-                                       fclk, dispc_fclk_rate());
-                       return -EINVAL;
-               }
-       }
+       r = dispc_ovl_calc_scaling(plane, channel, oi->width, oi->height,
+                       oi->out_width, oi->out_height, oi->color_mode,
+                       &five_taps);
+       if (r)
+               return r;
+
+       if (oi->color_mode == OMAP_DSS_COLOR_YUV2 ||
+                       oi->color_mode == OMAP_DSS_COLOR_UYVY ||
+                       oi->color_mode == OMAP_DSS_COLOR_NV12)
+               cconv = 1;
 
        if (ilace && !fieldmode) {
                /*
@@ -1963,69 +1830,76 @@ int dispc_setup_plane(enum omap_plane plane,
                 * so the integer part must be added to the base address of the
                 * bottom field.
                 */
-               if (!height || height == out_height)
+               if (!oi->height || oi->height == oi->out_height)
                        field_offset = 0;
                else
-                       field_offset = height / out_height / 2;
+                       field_offset = oi->height / oi->out_height / 2;
        }
 
        /* Fields are independent but interleaved in memory. */
        if (fieldmode)
                field_offset = 1;
 
-       if (rotation_type == OMAP_DSS_ROT_DMA)
-               calc_dma_rotation_offset(rotation, mirror,
-                               screen_width, width, frame_height, color_mode,
-                               fieldmode, field_offset,
+       if (oi->rotation_type == OMAP_DSS_ROT_DMA)
+               calc_dma_rotation_offset(oi->rotation, oi->mirror,
+                               oi->screen_width, oi->width, frame_height,
+                               oi->color_mode, fieldmode, field_offset,
                                &offset0, &offset1, &row_inc, &pix_inc);
        else
-               calc_vrfb_rotation_offset(rotation, mirror,
-                               screen_width, width, frame_height, color_mode,
-                               fieldmode, field_offset,
+               calc_vrfb_rotation_offset(oi->rotation, oi->mirror,
+                               oi->screen_width, oi->width, frame_height,
+                               oi->color_mode, fieldmode, field_offset,
                                &offset0, &offset1, &row_inc, &pix_inc);
 
        DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
                        offset0, offset1, row_inc, pix_inc);
 
-       _dispc_set_color_mode(plane, color_mode);
+       dispc_ovl_set_color_mode(plane, oi->color_mode);
 
-       _dispc_set_plane_ba0(plane, paddr + offset0);
-       _dispc_set_plane_ba1(plane, paddr + offset1);
+       dispc_ovl_set_ba0(plane, oi->paddr + offset0);
+       dispc_ovl_set_ba1(plane, oi->paddr + offset1);
 
-       if (OMAP_DSS_COLOR_NV12 == color_mode) {
-               _dispc_set_plane_ba0_uv(plane, puv_addr + offset0);
-               _dispc_set_plane_ba1_uv(plane, puv_addr + offset1);
+       if (OMAP_DSS_COLOR_NV12 == oi->color_mode) {
+               dispc_ovl_set_ba0_uv(plane, oi->p_uv_addr + offset0);
+               dispc_ovl_set_ba1_uv(plane, oi->p_uv_addr + offset1);
        }
 
 
-       _dispc_set_row_inc(plane, row_inc);
-       _dispc_set_pix_inc(plane, pix_inc);
+       dispc_ovl_set_row_inc(plane, row_inc);
+       dispc_ovl_set_pix_inc(plane, pix_inc);
 
-       DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, width, height,
-                       out_width, out_height);
+       DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, oi->width,
+                       oi->height, oi->out_width, oi->out_height);
 
-       _dispc_set_plane_pos(plane, pos_x, pos_y);
+       dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y);
 
-       _dispc_set_pic_size(plane, width, height);
+       dispc_ovl_set_pic_size(plane, oi->width, oi->height);
 
-       if (plane != OMAP_DSS_GFX) {
-               _dispc_set_scaling(plane, width, height,
-                                  out_width, out_height,
+       if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
+               dispc_ovl_set_scaling(plane, oi->width, oi->height,
+                                  oi->out_width, oi->out_height,
                                   ilace, five_taps, fieldmode,
-                                  color_mode, rotation);
-               _dispc_set_vid_size(plane, out_width, out_height);
-               _dispc_set_vid_color_conv(plane, cconv);
+                                  oi->color_mode, oi->rotation);
+               dispc_ovl_set_vid_size(plane, oi->out_width, oi->out_height);
+               dispc_ovl_set_vid_color_conv(plane, cconv);
        }
 
-       _dispc_set_rotation_attrs(plane, rotation, mirror, color_mode);
+       dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror,
+                       oi->color_mode);
+
+       dispc_ovl_set_zorder(plane, oi->zorder);
+       dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
+       dispc_ovl_setup_global_alpha(plane, oi->global_alpha);
 
-       _dispc_set_pre_mult_alpha(plane, pre_mult_alpha);
-       _dispc_setup_global_alpha(plane, global_alpha);
+       dispc_ovl_set_channel_out(plane, channel);
+
+       dispc_ovl_enable_replication(plane, replication);
+       dispc_ovl_set_fifo_threshold(plane, fifo_low, fifo_high);
 
        return 0;
 }
 
-int dispc_enable_plane(enum omap_plane plane, bool enable)
+int dispc_ovl_enable(enum omap_plane plane, bool enable)
 {
        DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
 
@@ -2048,7 +1922,7 @@ static void _enable_lcd_out(enum omap_channel channel, bool enable)
                REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
 }
 
-static void dispc_enable_lcd_out(enum omap_channel channel, bool enable)
+static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
 {
        struct completion frame_done_completion;
        bool is_on;
@@ -2095,14 +1969,19 @@ static void _enable_digit_out(bool enable)
        REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
 }
 
-static void dispc_enable_digit_out(bool enable)
+static void dispc_mgr_enable_digit_out(bool enable)
 {
        struct completion frame_done_completion;
-       int r;
+       enum dss_hdmi_venc_clk_source_select src;
+       int r, i;
+       u32 irq_mask;
+       int num_irqs;
 
        if (REG_GET(DISPC_CONTROL, 1, 1) == enable)
                return;
 
+       src = dss_get_hdmi_venc_clk_source();
+
        if (enable) {
                unsigned long flags;
                /* When we enable digit output, we'll get an extra digit
@@ -2119,43 +1998,47 @@ static void dispc_enable_digit_out(bool enable)
         * wait for the extra sync losts */
        init_completion(&frame_done_completion);
 
+       if (src == DSS_HDMI_M_PCLK && enable == false) {
+               irq_mask = DISPC_IRQ_FRAMEDONETV;
+               num_irqs = 1;
+       } else {
+               irq_mask = DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
+               /* XXX I understand from TRM that we should only wait for the
+                * current field to complete. But it seems we have to wait for
+                * both fields */
+               num_irqs = 2;
+       }
+
        r = omap_dispc_register_isr(dispc_disable_isr, &frame_done_completion,
-                       DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD);
+                       irq_mask);
        if (r)
-               DSSERR("failed to register EVSYNC isr\n");
+               DSSERR("failed to register %x isr\n", irq_mask);
 
        _enable_digit_out(enable);
 
-       /* XXX I understand from TRM that we should only wait for the
-        * current field to complete. But it seems we have to wait
-        * for both fields */
-       if (!wait_for_completion_timeout(&frame_done_completion,
-                               msecs_to_jiffies(100)))
-               DSSERR("timeout waiting for EVSYNC\n");
-
-       if (!wait_for_completion_timeout(&frame_done_completion,
-                               msecs_to_jiffies(100)))
-               DSSERR("timeout waiting for EVSYNC\n");
+       for (i = 0; i < num_irqs; ++i) {
+               if (!wait_for_completion_timeout(&frame_done_completion,
+                                       msecs_to_jiffies(100)))
+                       DSSERR("timeout waiting for digit out to %s\n",
+                                       enable ? "start" : "stop");
+       }
 
-       r = omap_dispc_unregister_isr(dispc_disable_isr,
-                       &frame_done_completion,
-                       DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD);
+       r = omap_dispc_unregister_isr(dispc_disable_isr, &frame_done_completion,
+                       irq_mask);
        if (r)
-               DSSERR("failed to unregister EVSYNC isr\n");
+               DSSERR("failed to unregister %x isr\n", irq_mask);
 
        if (enable) {
                unsigned long flags;
                spin_lock_irqsave(&dispc.irq_lock, flags);
-               dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
-               if (dss_has_feature(FEAT_MGR_LCD2))
-                       dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
+               dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST_DIGIT;
                dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
                _omap_dispc_set_irqs();
                spin_unlock_irqrestore(&dispc.irq_lock, flags);
        }
 }
 
-bool dispc_is_channel_enabled(enum omap_channel channel)
+bool dispc_mgr_is_enabled(enum omap_channel channel)
 {
        if (channel == OMAP_DSS_CHANNEL_LCD)
                return !!REG_GET(DISPC_CONTROL, 0, 0);
@@ -2167,13 +2050,12 @@ bool dispc_is_channel_enabled(enum omap_channel channel)
                BUG();
 }
 
-void dispc_enable_channel(enum omap_channel channel, bool enable)
+void dispc_mgr_enable(enum omap_channel channel, bool enable)
 {
-       if (channel == OMAP_DSS_CHANNEL_LCD ||
-                       channel == OMAP_DSS_CHANNEL_LCD2)
-               dispc_enable_lcd_out(channel, enable);
+       if (dispc_mgr_is_lcd(channel))
+               dispc_mgr_enable_lcd_out(channel, enable);
        else if (channel == OMAP_DSS_CHANNEL_DIGIT)
-               dispc_enable_digit_out(enable);
+               dispc_mgr_enable_digit_out(enable);
        else
                BUG();
 }
@@ -2202,7 +2084,7 @@ void dispc_pck_free_enable(bool enable)
        REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
 }
 
-void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable)
+void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
 {
        if (channel == OMAP_DSS_CHANNEL_LCD2)
                REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16);
@@ -2211,7 +2093,7 @@ void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable)
 }
 
 
-void dispc_set_lcd_display_type(enum omap_channel channel,
+void dispc_mgr_set_lcd_display_type(enum omap_channel channel,
                enum omap_lcd_display_type type)
 {
        int mode;
@@ -2242,12 +2124,12 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode)
 }
 
 
-void dispc_set_default_color(enum omap_channel channel, u32 color)
+void dispc_mgr_set_default_color(enum omap_channel channel, u32 color)
 {
        dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
 }
 
-u32 dispc_get_default_color(enum omap_channel channel)
+u32 dispc_mgr_get_default_color(enum omap_channel channel)
 {
        u32 l;
 
@@ -2260,7 +2142,7 @@ u32 dispc_get_default_color(enum omap_channel channel)
        return l;
 }
 
-void dispc_set_trans_key(enum omap_channel ch,
+void dispc_mgr_set_trans_key(enum omap_channel ch,
                enum omap_dss_trans_key_type type,
                u32 trans_key)
 {
@@ -2274,7 +2156,7 @@ void dispc_set_trans_key(enum omap_channel ch,
        dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
 }
 
-void dispc_get_trans_key(enum omap_channel ch,
+void dispc_mgr_get_trans_key(enum omap_channel ch,
                enum omap_dss_trans_key_type *type,
                u32 *trans_key)
 {
@@ -2293,7 +2175,7 @@ void dispc_get_trans_key(enum omap_channel ch,
                *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
 }
 
-void dispc_enable_trans_key(enum omap_channel ch, bool enable)
+void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
 {
        if (ch == OMAP_DSS_CHANNEL_LCD)
                REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
@@ -2302,39 +2184,36 @@ void dispc_enable_trans_key(enum omap_channel ch, bool enable)
        else /* OMAP_DSS_CHANNEL_LCD2 */
                REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
 }
-void dispc_enable_alpha_blending(enum omap_channel ch, bool enable)
+
+void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable)
 {
-       if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
+       if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
                return;
 
        if (ch == OMAP_DSS_CHANNEL_LCD)
                REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18);
        else if (ch == OMAP_DSS_CHANNEL_DIGIT)
                REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
-       else /* OMAP_DSS_CHANNEL_LCD2 */
-               REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18);
 }
-bool dispc_alpha_blending_enabled(enum omap_channel ch)
+
+bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch)
 {
        bool enabled;
 
-       if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
+       if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
                return false;
 
        if (ch == OMAP_DSS_CHANNEL_LCD)
                enabled = REG_GET(DISPC_CONFIG, 18, 18);
        else if (ch == OMAP_DSS_CHANNEL_DIGIT)
                enabled = REG_GET(DISPC_CONFIG, 19, 19);
-       else if (ch == OMAP_DSS_CHANNEL_LCD2)
-               enabled = REG_GET(DISPC_CONFIG2, 18, 18);
        else
                BUG();
 
        return enabled;
 }
 
-
-bool dispc_trans_key_enabled(enum omap_channel ch)
+bool dispc_mgr_trans_key_enabled(enum omap_channel ch)
 {
        bool enabled;
 
@@ -2351,7 +2230,7 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
 }
 
 
-void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
+void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
 {
        int code;
 
@@ -2379,46 +2258,41 @@ void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
                REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
 }
 
-void dispc_set_parallel_interface_mode(enum omap_channel channel,
-               enum omap_parallel_interface_mode mode)
+void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
 {
        u32 l;
-       int stallmode;
-       int gpout0 = 1;
-       int gpout1;
+       int gpout0, gpout1;
 
        switch (mode) {
-       case OMAP_DSS_PARALLELMODE_BYPASS:
-               stallmode = 0;
-               gpout1 = 1;
+       case DSS_IO_PAD_MODE_RESET:
+               gpout0 = 0;
+               gpout1 = 0;
                break;
-
-       case OMAP_DSS_PARALLELMODE_RFBI:
-               stallmode = 1;
+       case DSS_IO_PAD_MODE_RFBI:
+               gpout0 = 1;
                gpout1 = 0;
                break;
-
-       case OMAP_DSS_PARALLELMODE_DSI:
-               stallmode = 1;
+       case DSS_IO_PAD_MODE_BYPASS:
+               gpout0 = 1;
                gpout1 = 1;
                break;
-
        default:
                BUG();
                return;
        }
 
-       if (channel == OMAP_DSS_CHANNEL_LCD2) {
-               l = dispc_read_reg(DISPC_CONTROL2);
-               l = FLD_MOD(l, stallmode, 11, 11);
-               dispc_write_reg(DISPC_CONTROL2, l);
-       } else {
-               l = dispc_read_reg(DISPC_CONTROL);
-               l = FLD_MOD(l, stallmode, 11, 11);
-               l = FLD_MOD(l, gpout0, 15, 15);
-               l = FLD_MOD(l, gpout1, 16, 16);
-               dispc_write_reg(DISPC_CONTROL, l);
-       }
+       l = dispc_read_reg(DISPC_CONTROL);
+       l = FLD_MOD(l, gpout0, 15, 15);
+       l = FLD_MOD(l, gpout1, 16, 16);
+       dispc_write_reg(DISPC_CONTROL, l);
+}
+
+void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
+{
+       if (channel == OMAP_DSS_CHANNEL_LCD2)
+               REG_FLD_MOD(DISPC_CONTROL2, enable, 11, 11);
+       else
+               REG_FLD_MOD(DISPC_CONTROL, enable, 11, 11);
 }
 
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
@@ -2452,7 +2326,7 @@ bool dispc_lcd_timings_ok(struct omap_video_timings *timings)
                        timings->vfp, timings->vbp);
 }
 
-static void _dispc_set_lcd_timings(enum omap_channel channel, int hsw,
+static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
                int hfp, int hbp, int vsw, int vfp, int vbp)
 {
        u32 timing_h, timing_v;
@@ -2476,7 +2350,7 @@ static void _dispc_set_lcd_timings(enum omap_channel channel, int hsw,
 }
 
 /* change name to mode? */
-void dispc_set_lcd_timings(enum omap_channel channel,
+void dispc_mgr_set_lcd_timings(enum omap_channel channel,
                struct omap_video_timings *timings)
 {
        unsigned xtot, ytot;
@@ -2487,11 +2361,11 @@ void dispc_set_lcd_timings(enum omap_channel channel,
                                timings->vfp, timings->vbp))
                BUG();
 
-       _dispc_set_lcd_timings(channel, timings->hsw, timings->hfp,
+       _dispc_mgr_set_lcd_timings(channel, timings->hsw, timings->hfp,
                        timings->hbp, timings->vsw, timings->vfp,
                        timings->vbp);
 
-       dispc_set_lcd_size(channel, timings->x_res, timings->y_res);
+       dispc_mgr_set_lcd_size(channel, timings->x_res, timings->y_res);
 
        xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp;
        ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp;
@@ -2509,17 +2383,17 @@ void dispc_set_lcd_timings(enum omap_channel channel,
        DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
 }
 
-static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
+static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
                u16 pck_div)
 {
        BUG_ON(lck_div < 1);
-       BUG_ON(pck_div < 2);
+       BUG_ON(pck_div < 1);
 
        dispc_write_reg(DISPC_DIVISORo(channel),
                        FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
 }
 
-static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
+static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div,
                int *pck_div)
 {
        u32 l;
@@ -2552,7 +2426,7 @@ unsigned long dispc_fclk_rate(void)
        return r;
 }
 
-unsigned long dispc_lclk_rate(enum omap_channel channel)
+unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
 {
        struct platform_device *dsidev;
        int lcd;
@@ -2582,19 +2456,34 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
        return r / lcd;
 }
 
-unsigned long dispc_pclk_rate(enum omap_channel channel)
+unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
 {
-       int pcd;
        unsigned long r;
-       u32 l;
 
-       l = dispc_read_reg(DISPC_DIVISORo(channel));
+       if (dispc_mgr_is_lcd(channel)) {
+               int pcd;
+               u32 l;
 
-       pcd = FLD_GET(l, 7, 0);
+               l = dispc_read_reg(DISPC_DIVISORo(channel));
 
-       r = dispc_lclk_rate(channel);
+               pcd = FLD_GET(l, 7, 0);
 
-       return r / pcd;
+               r = dispc_mgr_lclk_rate(channel);
+
+               return r / pcd;
+       } else {
+               struct omap_dss_device *dssdev =
+                       dispc_mgr_get_device(channel);
+
+               switch (dssdev->type) {
+               case OMAP_DISPLAY_TYPE_VENC:
+                       return venc_get_pixel_clock();
+               case OMAP_DISPLAY_TYPE_HDMI:
+                       return hdmi_get_pixel_clock();
+               default:
+                       BUG();
+               }
+       }
 }
 
 void dispc_dump_clocks(struct seq_file *s)
@@ -2631,12 +2520,12 @@ void dispc_dump_clocks(struct seq_file *s)
                dss_get_generic_clk_source_name(lcd_clk_src),
                dss_feat_get_clk_source_name(lcd_clk_src));
 
-       dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
+       dispc_mgr_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
 
        seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
-                       dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd);
+                       dispc_mgr_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd);
        seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
-                       dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd);
+                       dispc_mgr_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd);
        if (dss_has_feature(FEAT_MGR_LCD2)) {
                seq_printf(s, "- LCD2 -\n");
 
@@ -2646,12 +2535,12 @@ void dispc_dump_clocks(struct seq_file *s)
                        dss_get_generic_clk_source_name(lcd_clk_src),
                        dss_feat_get_clk_source_name(lcd_clk_src));
 
-               dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
+               dispc_mgr_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
 
                seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
-                               dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD2), lcd);
+                               dispc_mgr_lclk_rate(OMAP_DSS_CHANNEL_LCD2), lcd);
                seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
-                               dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd);
+                               dispc_mgr_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd);
        }
 
        dispc_runtime_put();
@@ -2692,6 +2581,10 @@ void dispc_dump_irqs(struct seq_file *s)
        PIS(VID1_END_WIN);
        PIS(VID2_FIFO_UNDERFLOW);
        PIS(VID2_END_WIN);
+       if (dss_feat_get_num_ovls() > 3) {
+               PIS(VID3_FIFO_UNDERFLOW);
+               PIS(VID3_END_WIN);
+       }
        PIS(SYNC_LOST);
        PIS(SYNC_LOST_DIGIT);
        PIS(WAKEUP);
@@ -2707,11 +2600,26 @@ void dispc_dump_irqs(struct seq_file *s)
 
 void dispc_dump_regs(struct seq_file *s)
 {
+       int i, j;
+       const char *mgr_names[] = {
+               [OMAP_DSS_CHANNEL_LCD]          = "LCD",
+               [OMAP_DSS_CHANNEL_DIGIT]        = "TV",
+               [OMAP_DSS_CHANNEL_LCD2]         = "LCD2",
+       };
+       const char *ovl_names[] = {
+               [OMAP_DSS_GFX]          = "GFX",
+               [OMAP_DSS_VIDEO1]       = "VID1",
+               [OMAP_DSS_VIDEO2]       = "VID2",
+               [OMAP_DSS_VIDEO3]       = "VID3",
+       };
+       const char **p_names;
+
 #define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r))
 
        if (dispc_runtime_get())
                return;
 
+       /* DISPC common registers */
        DUMPREG(DISPC_REVISION);
        DUMPREG(DISPC_SYSCONFIG);
        DUMPREG(DISPC_SYSSTATUS);
@@ -2720,247 +2628,139 @@ void dispc_dump_regs(struct seq_file *s)
        DUMPREG(DISPC_CONTROL);
        DUMPREG(DISPC_CONFIG);
        DUMPREG(DISPC_CAPABLE);
-       DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
-       DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
-       DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
-       DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
        DUMPREG(DISPC_LINE_STATUS);
        DUMPREG(DISPC_LINE_NUMBER);
-       DUMPREG(DISPC_TIMING_H(OMAP_DSS_CHANNEL_LCD));
-       DUMPREG(DISPC_TIMING_V(OMAP_DSS_CHANNEL_LCD));
-       DUMPREG(DISPC_POL_FREQ(OMAP_DSS_CHANNEL_LCD));
-       DUMPREG(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD));
-       if (dss_has_feature(FEAT_GLOBAL_ALPHA))
+       if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+                       dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
                DUMPREG(DISPC_GLOBAL_ALPHA);
-       DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
-       DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
        if (dss_has_feature(FEAT_MGR_LCD2)) {
                DUMPREG(DISPC_CONTROL2);
                DUMPREG(DISPC_CONFIG2);
-               DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
-               DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
-               DUMPREG(DISPC_TIMING_H(OMAP_DSS_CHANNEL_LCD2));
-               DUMPREG(DISPC_TIMING_V(OMAP_DSS_CHANNEL_LCD2));
-               DUMPREG(DISPC_POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
-               DUMPREG(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD2));
-               DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
-       }
-
-       DUMPREG(DISPC_OVL_BA0(OMAP_DSS_GFX));
-       DUMPREG(DISPC_OVL_BA1(OMAP_DSS_GFX));
-       DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_GFX));
-       DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_GFX));
-       DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_GFX));
-       DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_GFX));
-       DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_GFX));
-       DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_GFX));
-       DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_GFX));
-       DUMPREG(DISPC_OVL_WINDOW_SKIP(OMAP_DSS_GFX));
-       DUMPREG(DISPC_OVL_TABLE_BA(OMAP_DSS_GFX));
-
-       DUMPREG(DISPC_DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD));
-       DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
-       DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
-
-       if (dss_has_feature(FEAT_CPR)) {
-               DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
-               DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
-               DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
        }
-       if (dss_has_feature(FEAT_MGR_LCD2)) {
-               DUMPREG(DISPC_DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
-               DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
-               DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
+
+#undef DUMPREG
+
+#define DISPC_REG(i, name) name(i)
+#define DUMPREG(i, r) seq_printf(s, "%s(%s)%*s %08x\n", #r, p_names[i], \
+       48 - strlen(#r) - strlen(p_names[i]), " ", \
+       dispc_read_reg(DISPC_REG(i, r)))
+
+       p_names = mgr_names;
+
+       /* DISPC channel specific registers */
+       for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
+               DUMPREG(i, DISPC_DEFAULT_COLOR);
+               DUMPREG(i, DISPC_TRANS_COLOR);
+               DUMPREG(i, DISPC_SIZE_MGR);
+
+               if (i == OMAP_DSS_CHANNEL_DIGIT)
+                       continue;
+
+               DUMPREG(i, DISPC_DEFAULT_COLOR);
+               DUMPREG(i, DISPC_TRANS_COLOR);
+               DUMPREG(i, DISPC_TIMING_H);
+               DUMPREG(i, DISPC_TIMING_V);
+               DUMPREG(i, DISPC_POL_FREQ);
+               DUMPREG(i, DISPC_DIVISORo);
+               DUMPREG(i, DISPC_SIZE_MGR);
+
+               DUMPREG(i, DISPC_DATA_CYCLE1);
+               DUMPREG(i, DISPC_DATA_CYCLE2);
+               DUMPREG(i, DISPC_DATA_CYCLE3);
 
                if (dss_has_feature(FEAT_CPR)) {
-                       DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
-                       DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
-                       DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
+                       DUMPREG(i, DISPC_CPR_COEF_R);
+                       DUMPREG(i, DISPC_CPR_COEF_G);
+                       DUMPREG(i, DISPC_CPR_COEF_B);
+               }
+       }
+
+       p_names = ovl_names;
+
+       for (i = 0; i < dss_feat_get_num_ovls(); i++) {
+               DUMPREG(i, DISPC_OVL_BA0);
+               DUMPREG(i, DISPC_OVL_BA1);
+               DUMPREG(i, DISPC_OVL_POSITION);
+               DUMPREG(i, DISPC_OVL_SIZE);
+               DUMPREG(i, DISPC_OVL_ATTRIBUTES);
+               DUMPREG(i, DISPC_OVL_FIFO_THRESHOLD);
+               DUMPREG(i, DISPC_OVL_FIFO_SIZE_STATUS);
+               DUMPREG(i, DISPC_OVL_ROW_INC);
+               DUMPREG(i, DISPC_OVL_PIXEL_INC);
+               if (dss_has_feature(FEAT_PRELOAD))
+                       DUMPREG(i, DISPC_OVL_PRELOAD);
+
+               if (i == OMAP_DSS_GFX) {
+                       DUMPREG(i, DISPC_OVL_WINDOW_SKIP);
+                       DUMPREG(i, DISPC_OVL_TABLE_BA);
+                       continue;
+               }
+
+               DUMPREG(i, DISPC_OVL_FIR);
+               DUMPREG(i, DISPC_OVL_PICTURE_SIZE);
+               DUMPREG(i, DISPC_OVL_ACCU0);
+               DUMPREG(i, DISPC_OVL_ACCU1);
+               if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+                       DUMPREG(i, DISPC_OVL_BA0_UV);
+                       DUMPREG(i, DISPC_OVL_BA1_UV);
+                       DUMPREG(i, DISPC_OVL_FIR2);
+                       DUMPREG(i, DISPC_OVL_ACCU2_0);
+                       DUMPREG(i, DISPC_OVL_ACCU2_1);
                }
+               if (dss_has_feature(FEAT_ATTR2))
+                       DUMPREG(i, DISPC_OVL_ATTRIBUTES2);
+               if (dss_has_feature(FEAT_PRELOAD))
+                       DUMPREG(i, DISPC_OVL_PRELOAD);
        }
 
-       if (dss_has_feature(FEAT_PRELOAD))
-               DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_GFX));
-
-       DUMPREG(DISPC_OVL_BA0(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_BA1(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_FIR(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_ACCU0(OMAP_DSS_VIDEO1));
-       DUMPREG(DISPC_OVL_ACCU1(OMAP_DSS_VIDEO1));
-
-       DUMPREG(DISPC_OVL_BA0(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_BA1(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_FIR(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_ACCU0(OMAP_DSS_VIDEO2));
-       DUMPREG(DISPC_OVL_ACCU1(OMAP_DSS_VIDEO2));
-
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 0));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 1));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 2));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 3));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 4));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 5));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 6));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 7));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 0));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 1));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 2));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 3));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 4));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 5));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 6));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 7));
-       DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 0));
-       DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 1));
-       DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 2));
-       DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 3));
-       DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 4));
-       if (dss_has_feature(FEAT_FIR_COEF_V)) {
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 0));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 1));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 2));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 3));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 4));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 5));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 6));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 7));
-       }
-
-       if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
-               DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO1));
-               DUMPREG(DISPC_OVL_BA1_UV(OMAP_DSS_VIDEO1));
-               DUMPREG(DISPC_OVL_FIR2(OMAP_DSS_VIDEO1));
-               DUMPREG(DISPC_OVL_ACCU2_0(OMAP_DSS_VIDEO1));
-               DUMPREG(DISPC_OVL_ACCU2_1(OMAP_DSS_VIDEO1));
-
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 0));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 1));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 2));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 3));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 4));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 5));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 6));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 7));
-
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 0));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 1));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 2));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 3));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 4));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 5));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 6));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 7));
-
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 0));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 1));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 2));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 3));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 4));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 5));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 6));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 7));
-       }
-       if (dss_has_feature(FEAT_ATTR2))
-               DUMPREG(DISPC_OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
-
-
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 0));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 1));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 2));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 3));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 4));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 5));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 6));
-       DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 7));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 0));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 1));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 2));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 3));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 4));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 5));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 6));
-       DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 7));
-       DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 0));
-       DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 1));
-       DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 2));
-       DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 3));
-       DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 4));
-
-       if (dss_has_feature(FEAT_FIR_COEF_V)) {
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 0));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 1));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 2));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 3));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 4));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 5));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 6));
-               DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 7));
-       }
-
-       if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
-               DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO2));
-               DUMPREG(DISPC_OVL_BA1_UV(OMAP_DSS_VIDEO2));
-               DUMPREG(DISPC_OVL_FIR2(OMAP_DSS_VIDEO2));
-               DUMPREG(DISPC_OVL_ACCU2_0(OMAP_DSS_VIDEO2));
-               DUMPREG(DISPC_OVL_ACCU2_1(OMAP_DSS_VIDEO2));
-
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 0));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 1));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 2));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 3));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 4));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 5));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 6));
-               DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 7));
-
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 0));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 1));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 2));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 3));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 4));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 5));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 6));
-               DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 7));
-
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 0));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 1));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 2));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 3));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 4));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 5));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 6));
-               DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 7));
-       }
-       if (dss_has_feature(FEAT_ATTR2))
-               DUMPREG(DISPC_OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
-
-       if (dss_has_feature(FEAT_PRELOAD)) {
-               DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO1));
-               DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO2));
+#undef DISPC_REG
+#undef DUMPREG
+
+#define DISPC_REG(plane, name, i) name(plane, i)
+#define DUMPREG(plane, name, i) \
+       seq_printf(s, "%s_%d(%s)%*s %08x\n", #name, i, p_names[plane], \
+       46 - strlen(#name) - strlen(p_names[plane]), " ", \
+       dispc_read_reg(DISPC_REG(plane, name, i)))
+
+       /* Video pipeline coefficient registers */
+
+       /* start from OMAP_DSS_VIDEO1 */
+       for (i = 1; i < dss_feat_get_num_ovls(); i++) {
+               for (j = 0; j < 8; j++)
+                       DUMPREG(i, DISPC_OVL_FIR_COEF_H, j);
+
+               for (j = 0; j < 8; j++)
+                       DUMPREG(i, DISPC_OVL_FIR_COEF_HV, j);
+
+               for (j = 0; j < 5; j++)
+                       DUMPREG(i, DISPC_OVL_CONV_COEF, j);
+
+               if (dss_has_feature(FEAT_FIR_COEF_V)) {
+                       for (j = 0; j < 8; j++)
+                               DUMPREG(i, DISPC_OVL_FIR_COEF_V, j);
+               }
+
+               if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+                       for (j = 0; j < 8; j++)
+                               DUMPREG(i, DISPC_OVL_FIR_COEF_H2, j);
+
+                       for (j = 0; j < 8; j++)
+                               DUMPREG(i, DISPC_OVL_FIR_COEF_HV2, j);
+
+                       for (j = 0; j < 8; j++)
+                               DUMPREG(i, DISPC_OVL_FIR_COEF_V2, j);
+               }
        }
 
        dispc_runtime_put();
+
+#undef DISPC_REG
 #undef DUMPREG
 }
 
-static void _dispc_set_pol_freq(enum omap_channel channel, bool onoff, bool rf,
-               bool ieo, bool ipc, bool ihs, bool ivs, u8 acbi, u8 acb)
+static void _dispc_mgr_set_pol_freq(enum omap_channel channel, bool onoff,
+               bool rf, bool ieo, bool ipc, bool ihs, bool ivs, u8 acbi,
+               u8 acb)
 {
        u32 l = 0;
 
@@ -2979,10 +2779,10 @@ static void _dispc_set_pol_freq(enum omap_channel channel, bool onoff, bool rf,
        dispc_write_reg(DISPC_POL_FREQ(channel), l);
 }
 
-void dispc_set_pol_freq(enum omap_channel channel,
+void dispc_mgr_set_pol_freq(enum omap_channel channel,
                enum omap_panel_config config, u8 acbi, u8 acb)
 {
-       _dispc_set_pol_freq(channel, (config & OMAP_DSS_LCD_ONOFF) != 0,
+       _dispc_mgr_set_pol_freq(channel, (config & OMAP_DSS_LCD_ONOFF) != 0,
                        (config & OMAP_DSS_LCD_RF) != 0,
                        (config & OMAP_DSS_LCD_IEO) != 0,
                        (config & OMAP_DSS_LCD_IPC) != 0,
@@ -2995,11 +2795,17 @@ void dispc_set_pol_freq(enum omap_channel channel,
 void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
                struct dispc_clock_info *cinfo)
 {
-       u16 pcd_min = is_tft ? 2 : 3;
+       u16 pcd_min, pcd_max;
        unsigned long best_pck;
        u16 best_ld, cur_ld;
        u16 best_pd, cur_pd;
 
+       pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD);
+       pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD);
+
+       if (!is_tft)
+               pcd_min = 3;
+
        best_pck = 0;
        best_ld = 0;
        best_pd = 0;
@@ -3007,7 +2813,7 @@ void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
        for (cur_ld = 1; cur_ld <= 255; ++cur_ld) {
                unsigned long lck = fck / cur_ld;
 
-               for (cur_pd = pcd_min; cur_pd <= 255; ++cur_pd) {
+               for (cur_pd = pcd_min; cur_pd <= pcd_max; ++cur_pd) {
                        unsigned long pck = lck / cur_pd;
                        long old_delta = abs(best_pck - req_pck);
                        long new_delta = abs(pck - req_pck);
@@ -3042,7 +2848,7 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
 {
        if (cinfo->lck_div > 255 || cinfo->lck_div == 0)
                return -EINVAL;
-       if (cinfo->pck_div < 2 || cinfo->pck_div > 255)
+       if (cinfo->pck_div < 1 || cinfo->pck_div > 255)
                return -EINVAL;
 
        cinfo->lck = dispc_fclk_rate / cinfo->lck_div;
@@ -3051,18 +2857,18 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
        return 0;
 }
 
-int dispc_set_clock_div(enum omap_channel channel,
+int dispc_mgr_set_clock_div(enum omap_channel channel,
                struct dispc_clock_info *cinfo)
 {
        DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
        DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
 
-       dispc_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div);
+       dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div);
 
        return 0;
 }
 
-int dispc_get_clock_div(enum omap_channel channel,
+int dispc_mgr_get_clock_div(enum omap_channel channel,
                struct dispc_clock_info *cinfo)
 {
        unsigned long fck;
@@ -3207,6 +3013,8 @@ static void print_irq_status(u32 status)
        PIS(OCP_ERR);
        PIS(VID1_FIFO_UNDERFLOW);
        PIS(VID2_FIFO_UNDERFLOW);
+       if (dss_feat_get_num_ovls() > 3)
+               PIS(VID3_FIFO_UNDERFLOW);
        PIS(SYNC_LOST);
        PIS(SYNC_LOST_DIGIT);
        if (dss_has_feature(FEAT_MGR_LCD2))
@@ -3300,178 +3108,72 @@ static void dispc_error_worker(struct work_struct *work)
        int i;
        u32 errors;
        unsigned long flags;
+       static const unsigned fifo_underflow_bits[] = {
+               DISPC_IRQ_GFX_FIFO_UNDERFLOW,
+               DISPC_IRQ_VID1_FIFO_UNDERFLOW,
+               DISPC_IRQ_VID2_FIFO_UNDERFLOW,
+               DISPC_IRQ_VID3_FIFO_UNDERFLOW,
+       };
+
+       static const unsigned sync_lost_bits[] = {
+               DISPC_IRQ_SYNC_LOST,
+               DISPC_IRQ_SYNC_LOST_DIGIT,
+               DISPC_IRQ_SYNC_LOST2,
+       };
 
        spin_lock_irqsave(&dispc.irq_lock, flags);
        errors = dispc.error_irqs;
        dispc.error_irqs = 0;
        spin_unlock_irqrestore(&dispc.irq_lock, flags);
 
-       if (errors & DISPC_IRQ_GFX_FIFO_UNDERFLOW) {
-               DSSERR("GFX_FIFO_UNDERFLOW, disabling GFX\n");
-               for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
-                       struct omap_overlay *ovl;
-                       ovl = omap_dss_get_overlay(i);
-
-                       if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
-                               continue;
-
-                       if (ovl->id == 0) {
-                               dispc_enable_plane(ovl->id, 0);
-                               dispc_go(ovl->manager->id);
-                               mdelay(50);
-                               break;
-                       }
-               }
-       }
-
-       if (errors & DISPC_IRQ_VID1_FIFO_UNDERFLOW) {
-               DSSERR("VID1_FIFO_UNDERFLOW, disabling VID1\n");
-               for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
-                       struct omap_overlay *ovl;
-                       ovl = omap_dss_get_overlay(i);
-
-                       if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
-                               continue;
-
-                       if (ovl->id == 1) {
-                               dispc_enable_plane(ovl->id, 0);
-                               dispc_go(ovl->manager->id);
-                               mdelay(50);
-                               break;
-                       }
-               }
-       }
-
-       if (errors & DISPC_IRQ_VID2_FIFO_UNDERFLOW) {
-               DSSERR("VID2_FIFO_UNDERFLOW, disabling VID2\n");
-               for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
-                       struct omap_overlay *ovl;
-                       ovl = omap_dss_get_overlay(i);
-
-                       if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
-                               continue;
+       dispc_runtime_get();
 
-                       if (ovl->id == 2) {
-                               dispc_enable_plane(ovl->id, 0);
-                               dispc_go(ovl->manager->id);
-                               mdelay(50);
-                               break;
-                       }
-               }
-       }
-
-       if (errors & DISPC_IRQ_SYNC_LOST) {
-               struct omap_overlay_manager *manager = NULL;
-               bool enable = false;
+       for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+               struct omap_overlay *ovl;
+               unsigned bit;
 
-               DSSERR("SYNC_LOST, disabling LCD\n");
+               ovl = omap_dss_get_overlay(i);
+               bit = fifo_underflow_bits[i];
 
-               for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
-                       struct omap_overlay_manager *mgr;
-                       mgr = omap_dss_get_overlay_manager(i);
-
-                       if (mgr->id == OMAP_DSS_CHANNEL_LCD) {
-                               manager = mgr;
-                               enable = mgr->device->state ==
-                                               OMAP_DSS_DISPLAY_ACTIVE;
-                               mgr->device->driver->disable(mgr->device);
-                               break;
-                       }
-               }
-
-               if (manager) {
-                       struct omap_dss_device *dssdev = manager->device;
-                       for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
-                               struct omap_overlay *ovl;
-                               ovl = omap_dss_get_overlay(i);
-
-                               if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
-                                       continue;
-
-                               if (ovl->id != 0 && ovl->manager == manager)
-                                       dispc_enable_plane(ovl->id, 0);
-                       }
-
-                       dispc_go(manager->id);
+               if (bit & errors) {
+                       DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n",
+                                       ovl->name);
+                       dispc_ovl_enable(ovl->id, false);
+                       dispc_mgr_go(ovl->manager->id);
                        mdelay(50);
-                       if (enable)
-                               dssdev->driver->enable(dssdev);
                }
        }
 
-       if (errors & DISPC_IRQ_SYNC_LOST_DIGIT) {
-               struct omap_overlay_manager *manager = NULL;
-               bool enable = false;
+       for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
+               struct omap_overlay_manager *mgr;
+               unsigned bit;
 
-               DSSERR("SYNC_LOST_DIGIT, disabling TV\n");
+               mgr = omap_dss_get_overlay_manager(i);
+               bit = sync_lost_bits[i];
 
-               for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
-                       struct omap_overlay_manager *mgr;
-                       mgr = omap_dss_get_overlay_manager(i);
+               if (bit & errors) {
+                       struct omap_dss_device *dssdev = mgr->device;
+                       bool enable;
 
-                       if (mgr->id == OMAP_DSS_CHANNEL_DIGIT) {
-                               manager = mgr;
-                               enable = mgr->device->state ==
-                                               OMAP_DSS_DISPLAY_ACTIVE;
-                               mgr->device->driver->disable(mgr->device);
-                               break;
-                       }
-               }
+                       DSSERR("SYNC_LOST on channel %s, restarting the output "
+                                       "with video overlays disabled\n",
+                                       mgr->name);
 
-               if (manager) {
-                       struct omap_dss_device *dssdev = manager->device;
-                       for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
-                               struct omap_overlay *ovl;
-                               ovl = omap_dss_get_overlay(i);
-
-                               if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
-                                       continue;
-
-                               if (ovl->id != 0 && ovl->manager == manager)
-                                       dispc_enable_plane(ovl->id, 0);
-                       }
+                       enable = dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
+                       dssdev->driver->disable(dssdev);
 
-                       dispc_go(manager->id);
-                       mdelay(50);
-                       if (enable)
-                               dssdev->driver->enable(dssdev);
-               }
-       }
-
-       if (errors & DISPC_IRQ_SYNC_LOST2) {
-               struct omap_overlay_manager *manager = NULL;
-               bool enable = false;
-
-               DSSERR("SYNC_LOST for LCD2, disabling LCD2\n");
-
-               for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
-                       struct omap_overlay_manager *mgr;
-                       mgr = omap_dss_get_overlay_manager(i);
-
-                       if (mgr->id == OMAP_DSS_CHANNEL_LCD2) {
-                               manager = mgr;
-                               enable = mgr->device->state ==
-                                               OMAP_DSS_DISPLAY_ACTIVE;
-                               mgr->device->driver->disable(mgr->device);
-                               break;
-                       }
-               }
-
-               if (manager) {
-                       struct omap_dss_device *dssdev = manager->device;
                        for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
                                struct omap_overlay *ovl;
                                ovl = omap_dss_get_overlay(i);
 
-                               if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
-                                       continue;
-
-                               if (ovl->id != 0 && ovl->manager == manager)
-                                       dispc_enable_plane(ovl->id, 0);
+                               if (ovl->id != OMAP_DSS_GFX &&
+                                               ovl->manager == mgr)
+                                       dispc_ovl_enable(ovl->id, false);
                        }
 
-                       dispc_go(manager->id);
+                       dispc_mgr_go(mgr->id);
                        mdelay(50);
+
                        if (enable)
                                dssdev->driver->enable(dssdev);
                }
@@