]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge tag 'omapdss-for-3.8' of git://gitorious.org/linux-omap-dss2/linux into for...
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Thu, 13 Dec 2012 12:30:56 +0000 (14:30 +0200)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Thu, 13 Dec 2012 12:30:56 +0000 (14:30 +0200)
OMAPDSS changes for 3.8, including:
- use dynanic debug prints
- OMAP platform dependency removals
- Creation of compat-layer, helping us to improve omapdrm
- Misc cleanups, aiming to make omadss more in line with the upcoming common
  display framework

* tag 'omapdss-for-3.8' of git://gitorious.org/linux-omap-dss2/linux: (140 commits)
  OMAPDSS: fix TV-out issue with DSI PLL
  Revert "OMAPFB: simplify locking"
  OMAPFB: remove silly loop in fb2display()
  OMAPFB: fix error handling in omapfb_find_best_mode()
  OMAPFB: use devm_kzalloc to allocate omapfb2_device
  OMAPDSS: DISPC: remove dispc fck uses
  OMAPDSS: DISPC: get dss clock rate from dss driver
  OMAPDSS: use omapdss_compat_init() in other drivers
  OMAPDSS: export dispc functions
  OMAPDSS: export dss_feat functions
  OMAPDSS: export dss_mgr_ops functions
  OMAPDSS: separate compat files in the Makefile
  OMAPDSS: move display sysfs init to compat layer
  OMAPDSS: DPI: use dispc's check_timings
  OMAPDSS: DISPC: add dispc_ovl_check()
  OMAPDSS: move irq handling to dispc-compat
  OMAPDSS: move omap_dispc_wait_for_irq_interruptible_timeout to dispc-compat.c
  OMAPDSS: move blocking mgr enable/disable to compat layer
  OMAPDSS: manage framedone irq with mgr ops
  OMAPDSS: add manager ops
  ...

62 files changed:
Documentation/arm/OMAP/DSS
arch/arm/mach-omap2/board-rx51-video.c
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/sdrc.c
arch/arm/plat-omap/common.c
arch/arm/plat-omap/fb.c
arch/arm/plat-omap/include/plat/sdrc.h
arch/arm/plat-omap/include/plat/vram.h [deleted file]
drivers/media/platform/omap/omap_vout.c
drivers/media/platform/omap/omap_vout_vrfb.c
drivers/media/platform/omap/omap_voutdef.h
drivers/media/platform/omap/omap_voutlib.c
drivers/media/platform/omap/omap_voutlib.h
drivers/staging/omapdrm/omap_drv.c
drivers/video/omap2/Kconfig
drivers/video/omap2/Makefile
drivers/video/omap2/displays/panel-acx565akm.c
drivers/video/omap2/displays/panel-generic-dpi.c
drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
drivers/video/omap2/displays/panel-n8x0.c
drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
drivers/video/omap2/displays/panel-picodlp.c
drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
drivers/video/omap2/displays/panel-taal.c
drivers/video/omap2/displays/panel-tfp410.c
drivers/video/omap2/displays/panel-tpo-td043mtea1.c
drivers/video/omap2/dss/Kconfig
drivers/video/omap2/dss/Makefile
drivers/video/omap2/dss/apply.c
drivers/video/omap2/dss/core.c
drivers/video/omap2/dss/dispc-compat.c [new file with mode: 0644]
drivers/video/omap2/dss/dispc-compat.h [new file with mode: 0644]
drivers/video/omap2/dss/dispc.c
drivers/video/omap2/dss/display-sysfs.c [new file with mode: 0644]
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
drivers/video/omap2/dss/manager.c
drivers/video/omap2/dss/output.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
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
drivers/video/omap2/dss/venc.c
drivers/video/omap2/dss/venc_panel.c
drivers/video/omap2/omapfb/Kconfig
drivers/video/omap2/omapfb/omapfb-ioctl.c
drivers/video/omap2/omapfb/omapfb-main.c
drivers/video/omap2/omapfb/omapfb-sysfs.c
drivers/video/omap2/omapfb/omapfb.h
drivers/video/omap2/vram.c [deleted file]
drivers/video/omap2/vrfb.c
include/video/omapdss.h
include/video/omapvrfb.h [moved from arch/arm/plat-omap/include/plat/vrfb.h with 95% similarity]

index a564ceea9e98cc9f5f423f0e80f54c85fe7b0ef3..4484e021290e22480fceb1c4bae5b168ca4239c6 100644 (file)
@@ -285,7 +285,10 @@ FB0 +-- GFX  ---- LCD ---- LCD
 Misc notes
 ----------
 
-OMAP FB allocates the framebuffer memory using the OMAP VRAM allocator.
+OMAP FB allocates the framebuffer memory using the standard dma allocator. You
+can enable Contiguous Memory Allocator (CONFIG_CMA) to improve the dma
+allocator, and if CMA is enabled, you use "cma=" kernel parameter to increase
+the global memory area for CMA.
 
 Using DSI DPLL to generate pixel clock it is possible produce the pixel clock
 of 86.5MHz (max possible), and with that you get 1280x1024@57 output from DVI.
@@ -301,11 +304,6 @@ framebuffer parameters.
 Kernel boot arguments
 ---------------------
 
-vram=<size>[,<physaddr>]
-       - Amount of total VRAM to preallocate and optionally a physical start
-         memory address. For example, "10M". omapfb allocates memory for
-         framebuffers from VRAM.
-
 omapfb.mode=<display>:<mode>[,...]
        - Default video mode for specified displays. For example,
          "dvi:800x400MR-24@60".  See drivers/video/modedb.c.
index c22e111bcd00e2b17205bd5e764d46db6513ab2c..46f4fc982766e638b920c456114b58d94eab7888 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/mm.h>
 #include <asm/mach-types.h>
 #include <video/omapdss.h>
-#include <plat/vram.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 
 #include "board-rx51.h"
@@ -87,17 +86,4 @@ static int __init rx51_video_init(void)
 }
 
 subsys_initcall(rx51_video_init);
-
-void __init rx51_video_mem_init(void)
-{
-       /*
-        * GFX 864x480x32bpp
-        * VID1/2 1280x720x32bpp double buffered
-        */
-       omap_vram_set_sdram_vram(PAGE_ALIGN(864 * 480 * 4) +
-                       2 * PAGE_ALIGN(1280 * 720 * 4 * 2), 0);
-}
-
-#else
-void __init rx51_video_mem_init(void) { }
 #endif /* defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) */
index 7bbb05d9689b806534b6b83bed6b1a2c6e1dd9cb..6e0de6f83278e4106202331350de84b396ec7712 100644 (file)
@@ -34,8 +34,6 @@
 
 #define RX51_GPIO_SLEEP_IND 162
 
-extern void rx51_video_mem_init(void);
-
 static struct gpio_led gpio_leds[] = {
        {
                .name   = "sleep_ind",
@@ -112,7 +110,6 @@ static void __init rx51_init(void)
 
 static void __init rx51_reserve(void)
 {
-       rx51_video_mem_init();
        omap_reserve();
 }
 
index 1011995f150a60c8f4453832835f4b974dbdd000..282c814ea2e259b887ac809ef765b86ca33a11ac 100644 (file)
@@ -100,17 +100,20 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initconst = {
        { "dss_hdmi", "omapdss_hdmi", -1 },
 };
 
-static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
+static void __init omap4_tpd12s015_mux_pads(void)
 {
-       u32 reg;
-       u16 control_i2c_1;
-
        omap_mux_init_signal("hdmi_cec",
                        OMAP_PIN_INPUT_PULLUP);
        omap_mux_init_signal("hdmi_ddc_scl",
                        OMAP_PIN_INPUT_PULLUP);
        omap_mux_init_signal("hdmi_ddc_sda",
                        OMAP_PIN_INPUT_PULLUP);
+}
+
+static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
+{
+       u32 reg;
+       u16 control_i2c_1;
 
        /*
         * CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and
@@ -161,8 +164,10 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
 
 int __init omap_hdmi_init(enum omap_hdmi_flags flags)
 {
-       if (cpu_is_omap44xx())
+       if (cpu_is_omap44xx()) {
                omap4_hdmi_mux_pads(flags);
+               omap4_tpd12s015_mux_pads();
+       }
 
        return 0;
 }
@@ -284,6 +289,35 @@ err:
        return ERR_PTR(r);
 }
 
+static enum omapdss_version __init omap_display_get_version(void)
+{
+       if (cpu_is_omap24xx())
+               return OMAPDSS_VER_OMAP24xx;
+       else if (cpu_is_omap3630())
+               return OMAPDSS_VER_OMAP3630;
+       else if (cpu_is_omap34xx()) {
+               if (soc_is_am35xx()) {
+                       return OMAPDSS_VER_AM35xx;
+               } else {
+                       if (omap_rev() < OMAP3430_REV_ES3_0)
+                               return OMAPDSS_VER_OMAP34xx_ES1;
+                       else
+                               return OMAPDSS_VER_OMAP34xx_ES3;
+               }
+       } else if (omap_rev() == OMAP4430_REV_ES1_0)
+               return OMAPDSS_VER_OMAP4430_ES1;
+       else if (omap_rev() == OMAP4430_REV_ES2_0 ||
+                       omap_rev() == OMAP4430_REV_ES2_1 ||
+                       omap_rev() == OMAP4430_REV_ES2_2)
+               return OMAPDSS_VER_OMAP4430_ES2;
+       else if (cpu_is_omap44xx())
+               return OMAPDSS_VER_OMAP4;
+       else if (soc_is_omap54xx())
+               return OMAPDSS_VER_OMAP5;
+       else
+               return OMAPDSS_VER_UNKNOWN;
+}
+
 int __init omap_display_init(struct omap_dss_board_info *board_data)
 {
        int r = 0;
@@ -291,9 +325,18 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
        int i, oh_count;
        const struct omap_dss_hwmod_data *curr_dss_hwmod;
        struct platform_device *dss_pdev;
+       enum omapdss_version ver;
 
        /* create omapdss device */
 
+       ver = omap_display_get_version();
+
+       if (ver == OMAPDSS_VER_UNKNOWN) {
+               pr_err("DSS not supported on this SoC\n");
+               return -ENODEV;
+       }
+
+       board_data->version = ver;
        board_data->dsi_enable_pads = omap_dsi_enable_pads;
        board_data->dsi_disable_pads = omap_dsi_disable_pads;
        board_data->get_context_loss_count = omap_pm_get_dev_context_loss_count;
index e3d345f464094c0709382b9ab160ef70384f581d..4282e6e967d644f56a42ce7e76b7a4174567bf2c 100644 (file)
@@ -160,19 +160,3 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
        sdrc_write_reg(l, SDRC_POWER);
        omap2_sms_save_context();
 }
-
-void omap2_sms_write_rot_control(u32 val, unsigned ctx)
-{
-       sms_write_reg(val, SMS_ROT_CONTROL(ctx));
-}
-
-void omap2_sms_write_rot_size(u32 val, unsigned ctx)
-{
-       sms_write_reg(val, SMS_ROT_SIZE(ctx));
-}
-
-void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx)
-{
-       sms_write_reg(val, SMS_ROT_PHYSICAL_BA(ctx));
-}
-
index 111315a69354943450be64243490a697bb1e3f23..d21ed18355ae864991afd42c8e0a70c90e8bc610 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/dma-mapping.h>
 
 #include <plat/common.h>
-#include <plat/vram.h>
 #include <linux/platform_data/dsp-omap.h>
 #include <plat/dma.h>
 
@@ -25,7 +24,6 @@
 
 void __init omap_reserve(void)
 {
-       omap_vram_reserve_sdram_memblock();
        omap_dsp_reserve_sdram_memblock();
        omap_secure_ram_reserve_memblock();
        omap_barrier_reserve_memblock();
index bcbb9d5dc293e4066264dc6aba714af8aa6594f4..6df0c215fdb48b68c2ee3d9907d01033d5813c74 100644 (file)
 #include <linux/memblock.h>
 #include <linux/io.h>
 #include <linux/omapfb.h>
+#include <linux/dma-mapping.h>
 
 #include <mach/hardware.h>
 #include <asm/mach/map.h>
 
+#include <plat/cpu.h>
+
+#ifdef CONFIG_OMAP2_VRFB
+
+/*
+ * The first memory resource is the register region for VRFB,
+ * the rest are VRFB virtual memory areas for each VRFB context.
+ */
+
+static const struct resource omap2_vrfb_resources[] = {
+       DEFINE_RES_MEM_NAMED(0x68008000u, 0x40, "vrfb-regs"),
+       DEFINE_RES_MEM_NAMED(0x70000000u, 0x4000000, "vrfb-area-0"),
+       DEFINE_RES_MEM_NAMED(0x74000000u, 0x4000000, "vrfb-area-1"),
+       DEFINE_RES_MEM_NAMED(0x78000000u, 0x4000000, "vrfb-area-2"),
+       DEFINE_RES_MEM_NAMED(0x7c000000u, 0x4000000, "vrfb-area-3"),
+};
+
+static const struct resource omap3_vrfb_resources[] = {
+       DEFINE_RES_MEM_NAMED(0x6C000180u, 0xc0, "vrfb-regs"),
+       DEFINE_RES_MEM_NAMED(0x70000000u, 0x4000000, "vrfb-area-0"),
+       DEFINE_RES_MEM_NAMED(0x74000000u, 0x4000000, "vrfb-area-1"),
+       DEFINE_RES_MEM_NAMED(0x78000000u, 0x4000000, "vrfb-area-2"),
+       DEFINE_RES_MEM_NAMED(0x7c000000u, 0x4000000, "vrfb-area-3"),
+       DEFINE_RES_MEM_NAMED(0xe0000000u, 0x4000000, "vrfb-area-4"),
+       DEFINE_RES_MEM_NAMED(0xe4000000u, 0x4000000, "vrfb-area-5"),
+       DEFINE_RES_MEM_NAMED(0xe8000000u, 0x4000000, "vrfb-area-6"),
+       DEFINE_RES_MEM_NAMED(0xec000000u, 0x4000000, "vrfb-area-7"),
+       DEFINE_RES_MEM_NAMED(0xf0000000u, 0x4000000, "vrfb-area-8"),
+       DEFINE_RES_MEM_NAMED(0xf4000000u, 0x4000000, "vrfb-area-9"),
+       DEFINE_RES_MEM_NAMED(0xf8000000u, 0x4000000, "vrfb-area-10"),
+       DEFINE_RES_MEM_NAMED(0xfc000000u, 0x4000000, "vrfb-area-11"),
+};
+
+static int __init omap_init_vrfb(void)
+{
+       struct platform_device *pdev;
+       const struct resource *res;
+       unsigned int num_res;
+
+       if (cpu_is_omap24xx()) {
+               res = omap2_vrfb_resources;
+               num_res = ARRAY_SIZE(omap2_vrfb_resources);
+       } else if (cpu_is_omap34xx()) {
+               res = omap3_vrfb_resources;
+               num_res = ARRAY_SIZE(omap3_vrfb_resources);
+       } else {
+               return 0;
+       }
+
+       pdev = platform_device_register_resndata(NULL, "omapvrfb", -1,
+                       res, num_res, NULL, 0);
+
+       if (IS_ERR(pdev))
+               return PTR_ERR(pdev);
+       else
+               return 0;
+}
+
+arch_initcall(omap_init_vrfb);
+#endif
+
 #if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
 
 static bool omapfb_lcd_configured;
@@ -45,7 +107,7 @@ static struct platform_device omap_fb_device = {
        .id             = -1,
        .dev = {
                .dma_mask               = &omap_fb_dma_mask,
-               .coherent_dma_mask      = ~(u32)0,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
                .platform_data          = &omapfb_config,
        },
        .num_resources = 0,
@@ -81,7 +143,7 @@ static struct platform_device omap_fb_device = {
        .id             = -1,
        .dev = {
                .dma_mask               = &omap_fb_dma_mask,
-               .coherent_dma_mask      = ~(u32)0,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
                .platform_data          = &omapfb_config,
        },
        .num_resources = 0,
index 36d6a76662166d1e570afdc293252e0bcb39884a..c68bab29cfc5946771a3ffb6de288ccb1ba2f556 100644 (file)
@@ -94,9 +94,6 @@
 /* SMS register offsets - read/write with sms_{read,write}_reg() */
 
 #define SMS_SYSCONFIG                  0x010
-#define SMS_ROT_CONTROL(context)       (0x180 + 0x10 * context)
-#define SMS_ROT_SIZE(context)          (0x184 + 0x10 * context)
-#define SMS_ROT_PHYSICAL_BA(context)   (0x188 + 0x10 * context)
 /* REVISIT: fill in other SMS registers here */
 
 
@@ -137,10 +134,6 @@ int omap2_sdrc_get_params(unsigned long r,
 void omap2_sms_save_context(void);
 void omap2_sms_restore_context(void);
 
-void omap2_sms_write_rot_control(u32 val, unsigned ctx);
-void omap2_sms_write_rot_size(u32 val, unsigned ctx);
-void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx);
-
 #ifdef CONFIG_ARCH_OMAP2
 
 struct memory_timings {
diff --git a/arch/arm/plat-omap/include/plat/vram.h b/arch/arm/plat-omap/include/plat/vram.h
deleted file mode 100644 (file)
index 4d65b7d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * VRAM manager for OMAP
- *
- * Copyright (C) 2009 Nokia Corporation
- * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef __OMAP_VRAM_H__
-#define __OMAP_VRAM_H__
-
-#include <linux/types.h>
-
-extern int omap_vram_add_region(unsigned long paddr, size_t size);
-extern int omap_vram_free(unsigned long paddr, size_t size);
-extern int omap_vram_alloc(size_t size, unsigned long *paddr);
-extern int omap_vram_reserve(unsigned long paddr, size_t size);
-extern void omap_vram_get_info(unsigned long *vram, unsigned long *free_vram,
-               unsigned long *largest_free_block);
-
-#ifdef CONFIG_OMAP2_VRAM
-extern void omap_vram_set_sdram_vram(u32 size, u32 start);
-
-extern void omap_vram_reserve_sdram_memblock(void);
-#else
-static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { }
-
-static inline void omap_vram_reserve_sdram_memblock(void) { }
-#endif
-
-#endif
index a3b1a34c896db9257000f6c1a3e8fb8bb7cd7df0..e8cac9e55bc97676f5892345f2488f2849e35717 100644 (file)
@@ -44,9 +44,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 
-#include <plat/cpu.h>
-#include <plat/dma.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
 #include <video/omapdss.h>
 
 #include "omap_voutlib.h"
@@ -2064,7 +2062,7 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev)
                vout->vid_info.id = k + 1;
 
                /* Set VRFB as rotation_type for omap2 and omap3 */
-               if (cpu_is_omap24xx() || cpu_is_omap34xx())
+               if (omap_vout_dss_omap24xx() || omap_vout_dss_omap34xx())
                        vout->vid_info.rotation_type = VOUT_ROT_VRFB;
 
                /* Setup the default configuration for the video devices
@@ -2186,14 +2184,23 @@ static int __init omap_vout_probe(struct platform_device *pdev)
        struct omap_dss_device *def_display;
        struct omap2video_device *vid_dev = NULL;
 
+       ret = omapdss_compat_init();
+       if (ret) {
+               dev_err(&pdev->dev, "failed to init dss\n");
+               return ret;
+       }
+
        if (pdev->num_resources == 0) {
                dev_err(&pdev->dev, "probed for an unknown device\n");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto err_dss_init;
        }
 
        vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL);
-       if (vid_dev == NULL)
-               return -ENOMEM;
+       if (vid_dev == NULL) {
+               ret = -ENOMEM;
+               goto err_dss_init;
+       }
 
        vid_dev->num_displays = 0;
        for_each_dss_dev(dssdev) {
@@ -2288,6 +2295,8 @@ probe_err1:
        }
 probe_err0:
        kfree(vid_dev);
+err_dss_init:
+       omapdss_compat_uninit();
        return ret;
 }
 
index 4be26abf6cea7a323ef0b15e7e1cedf3177ab916..6c37f9240ddf19f090bb08976fd90dfd886f26f0 100644 (file)
@@ -17,7 +17,7 @@
 #include <media/v4l2-device.h>
 
 #include <plat/dma.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
 
 #include "omap_voutdef.h"
 #include "omap_voutlib.h"
index 27a95d23b913493db67d20b90857e37f621fdd10..9ccfe1f475a4dce9ec07bae935c3bbdce447f7de 100644 (file)
@@ -12,7 +12,7 @@
 #define OMAP_VOUTDEF_H
 
 #include <video/omapdss.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
 
 #define YUYV_BPP        2
 #define RGB565_BPP      2
index 115408b9274f0c40370321fd86daa5b576e5e5e7..80b0d88f125ce5a61b6da09473b1acb991faf4fc 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <linux/dma-mapping.h>
 
-#include <plat/cpu.h>
+#include <video/omapdss.h>
 
 #include "omap_voutlib.h"
 
@@ -124,7 +124,7 @@ int omap_vout_new_window(struct v4l2_rect *crop,
        win->chromakey = new_win->chromakey;
 
        /* Adjust the cropping window to allow for resizing limitation */
-       if (cpu_is_omap24xx()) {
+       if (omap_vout_dss_omap24xx()) {
                /* For 24xx limit is 8x to 1/2x scaling. */
                if ((crop->height/win->w.height) >= 2)
                        crop->height = win->w.height * 2;
@@ -140,7 +140,7 @@ int omap_vout_new_window(struct v4l2_rect *crop,
                        if (crop->height != win->w.height)
                                crop->width = 768;
                }
-       } else if (cpu_is_omap34xx()) {
+       } else if (omap_vout_dss_omap34xx()) {
                /* For 34xx limit is 8x to 1/4x scaling. */
                if ((crop->height/win->w.height) >= 4)
                        crop->height = win->w.height * 4;
@@ -196,7 +196,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
        if (try_crop.width <= 0 || try_crop.height <= 0)
                return -EINVAL;
 
-       if (cpu_is_omap24xx()) {
+       if (omap_vout_dss_omap24xx()) {
                if (try_crop.height != win->w.height) {
                        /* If we're resizing vertically, we can't support a
                         * crop width wider than 768 pixels.
@@ -207,9 +207,9 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
        }
        /* vertical resizing */
        vresize = (1024 * try_crop.height) / win->w.height;
-       if (cpu_is_omap24xx() && (vresize > 2048))
+       if (omap_vout_dss_omap24xx() && (vresize > 2048))
                vresize = 2048;
-       else if (cpu_is_omap34xx() && (vresize > 4096))
+       else if (omap_vout_dss_omap34xx() && (vresize > 4096))
                vresize = 4096;
 
        win->w.height = ((1024 * try_crop.height) / vresize) & ~1;
@@ -226,9 +226,9 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
        }
        /* horizontal resizing */
        hresize = (1024 * try_crop.width) / win->w.width;
-       if (cpu_is_omap24xx() && (hresize > 2048))
+       if (omap_vout_dss_omap24xx() && (hresize > 2048))
                hresize = 2048;
-       else if (cpu_is_omap34xx() && (hresize > 4096))
+       else if (omap_vout_dss_omap34xx() && (hresize > 4096))
                hresize = 4096;
 
        win->w.width = ((1024 * try_crop.width) / hresize) & ~1;
@@ -243,7 +243,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
                if (try_crop.width == 0)
                        try_crop.width = 2;
        }
-       if (cpu_is_omap24xx()) {
+       if (omap_vout_dss_omap24xx()) {
                if ((try_crop.height/win->w.height) >= 2)
                        try_crop.height = win->w.height * 2;
 
@@ -258,7 +258,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
                        if (try_crop.height != win->w.height)
                                try_crop.width = 768;
                }
-       } else if (cpu_is_omap34xx()) {
+       } else if (omap_vout_dss_omap34xx()) {
                if ((try_crop.height/win->w.height) >= 4)
                        try_crop.height = win->w.height * 4;
 
@@ -337,3 +337,21 @@ void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size)
        }
        free_pages((unsigned long) virtaddr, order);
 }
+
+bool omap_vout_dss_omap24xx(void)
+{
+       return omapdss_get_version() == OMAPDSS_VER_OMAP24xx;
+}
+
+bool omap_vout_dss_omap34xx(void)
+{
+       switch (omapdss_get_version()) {
+       case OMAPDSS_VER_OMAP34xx_ES1:
+       case OMAPDSS_VER_OMAP34xx_ES3:
+       case OMAPDSS_VER_OMAP3630:
+       case OMAPDSS_VER_AM35xx:
+               return true;
+       default:
+               return false;
+       }
+}
index e51750a597e3a426aabb0917c0b8920666b59d51..f9d1c0779f338723fe2256db7fa66162c0b337ab 100644 (file)
@@ -32,5 +32,8 @@ void omap_vout_new_format(struct v4l2_pix_format *pix,
                struct v4l2_window *win);
 unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr);
 void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size);
+
+bool omap_vout_dss_omap24xx(void);
+bool omap_vout_dss_omap34xx(void);
 #endif /* #ifndef OMAP_VOUTLIB_H */
 
index ebdb0b676737c27bd8d5d4dc87c41abcc78940ab..2bf72591817a9023d390e117a6e3105d803c308b 100644 (file)
@@ -572,6 +572,14 @@ static int dev_load(struct drm_device *dev, unsigned long flags)
 
        dev->dev_private = priv;
 
+       ret = omapdss_compat_init();
+       if (ret) {
+               dev_err(dev->dev, "coult not init omapdss\n");
+               dev->dev_private = NULL;
+               kfree(priv);
+               return ret;
+       }
+
        priv->wq = alloc_ordered_workqueue("omapdrm", 0);
 
        INIT_LIST_HEAD(&priv->obj_list);
@@ -583,6 +591,7 @@ static int dev_load(struct drm_device *dev, unsigned long flags)
                dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret);
                dev->dev_private = NULL;
                kfree(priv);
+               omapdss_compat_uninit();
                return ret;
        }
 
@@ -618,6 +627,8 @@ static int dev_unload(struct drm_device *dev)
        flush_workqueue(priv->wq);
        destroy_workqueue(priv->wq);
 
+       omapdss_compat_uninit();
+
        kfree(dev->dev_private);
        dev->dev_private = NULL;
 
index d877c361abdaa02405133cd12b9d23288aa82662..346d67d6cf4d5a24c6465388e4e7d166356dc5b3 100644 (file)
@@ -1,6 +1,3 @@
-config OMAP2_VRAM
-       bool
-
 config OMAP2_VRFB
        bool
 
index 5ddef129f79826e8fadda55cb052204b220cb041..5ea7cb9aed17b9d666bfdba808b889d745fa8ffb 100644 (file)
@@ -1,4 +1,3 @@
-obj-$(CONFIG_OMAP2_VRAM) += vram.o
 obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
 
 obj-$(CONFIG_OMAP2_DSS) += dss/
index c835aa70f96fb64829e7b7a8f8a328a64dd720e3..65eb76c840a113765ba6afdae85428c2f24e478f 100644 (file)
@@ -710,27 +710,6 @@ static void acx_panel_disable(struct omap_dss_device *dssdev)
        dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
-static int acx_panel_suspend(struct omap_dss_device *dssdev)
-{
-       dev_dbg(&dssdev->dev, "%s\n", __func__);
-       acx_panel_power_off(dssdev);
-       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-       return 0;
-}
-
-static int acx_panel_resume(struct omap_dss_device *dssdev)
-{
-       int r;
-
-       dev_dbg(&dssdev->dev, "%s\n", __func__);
-       r = acx_panel_power_on(dssdev);
-       if (r)
-               return r;
-
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-       return 0;
-}
-
 static void acx_panel_set_timings(struct omap_dss_device *dssdev,
                struct omap_video_timings *timings)
 {
@@ -752,8 +731,6 @@ static struct omap_dss_driver acx_panel_driver = {
 
        .enable         = acx_panel_enable,
        .disable        = acx_panel_disable,
-       .suspend        = acx_panel_suspend,
-       .resume         = acx_panel_resume,
 
        .set_timings    = acx_panel_set_timings,
        .check_timings  = acx_panel_check_timings,
index 88295c526815e76a628e1e5641902e1ceac0b07d..54ca8ae21078c971496911443a110b89e32cae80 100644 (file)
@@ -688,40 +688,6 @@ static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
        mutex_unlock(&drv_data->lock);
 }
 
-static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
-{
-       struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
-
-       mutex_lock(&drv_data->lock);
-
-       generic_dpi_panel_power_off(dssdev);
-
-       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
-       mutex_unlock(&drv_data->lock);
-
-       return 0;
-}
-
-static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
-{
-       struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
-       int r;
-
-       mutex_lock(&drv_data->lock);
-
-       r = generic_dpi_panel_power_on(dssdev);
-       if (r)
-               goto err;
-
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-err:
-       mutex_unlock(&drv_data->lock);
-
-       return r;
-}
-
 static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
                struct omap_video_timings *timings)
 {
@@ -769,8 +735,6 @@ static struct omap_dss_driver dpi_driver = {
 
        .enable         = generic_dpi_panel_enable,
        .disable        = generic_dpi_panel_disable,
-       .suspend        = generic_dpi_panel_suspend,
-       .resume         = generic_dpi_panel_resume,
 
        .set_timings    = generic_dpi_panel_set_timings,
        .get_timings    = generic_dpi_panel_get_timings,
index 90c1cabf244e183ea7572b083a3a2b9a9fa3cc69..ace419b801eb6c302fadb26757ffcde8f78fba09 100644 (file)
@@ -143,46 +143,12 @@ static void lb035q02_panel_disable(struct omap_dss_device *dssdev)
        mutex_unlock(&ld->lock);
 }
 
-static int lb035q02_panel_suspend(struct omap_dss_device *dssdev)
-{
-       struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
-
-       mutex_lock(&ld->lock);
-
-       lb035q02_panel_power_off(dssdev);
-       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
-       mutex_unlock(&ld->lock);
-       return 0;
-}
-
-static int lb035q02_panel_resume(struct omap_dss_device *dssdev)
-{
-       struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
-       int r;
-
-       mutex_lock(&ld->lock);
-
-       r = lb035q02_panel_power_on(dssdev);
-       if (r)
-               goto err;
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-       mutex_unlock(&ld->lock);
-       return 0;
-err:
-       mutex_unlock(&ld->lock);
-       return r;
-}
-
 static struct omap_dss_driver lb035q02_driver = {
        .probe          = lb035q02_panel_probe,
        .remove         = lb035q02_panel_remove,
 
        .enable         = lb035q02_panel_enable,
        .disable        = lb035q02_panel_disable,
-       .suspend        = lb035q02_panel_suspend,
-       .resume         = lb035q02_panel_resume,
 
        .driver         = {
                .name   = "lgphilips_lb035q02_panel",
index 3fc5ad081a212906c92c69497436ddbe08a8807f..d1cb722fcdbcea123247b6530d296d5539e3cc9e 100644 (file)
@@ -574,54 +574,6 @@ static void n8x0_panel_disable(struct omap_dss_device *dssdev)
        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_resolution(struct omap_dss_device *dssdev,
                u16 *xres, u16 *yres)
 {
@@ -683,8 +635,6 @@ static struct omap_dss_driver n8x0_panel_driver = {
 
        .enable         = n8x0_panel_enable,
        .disable        = n8x0_panel_disable,
-       .suspend        = n8x0_panel_suspend,
-       .resume         = n8x0_panel_resume,
 
        .update         = n8x0_panel_update,
        .sync           = n8x0_panel_sync,
@@ -702,18 +652,25 @@ static struct omap_dss_driver n8x0_panel_driver = {
 
 static int mipid_spi_probe(struct spi_device *spi)
 {
+       int r;
+
        dev_dbg(&spi->dev, "mipid_spi_probe\n");
 
        spi->mode = SPI_MODE_0;
 
        s_drv_data.spidev = spi;
 
-       return 0;
+       r = omap_dss_register_driver(&n8x0_panel_driver);
+       if (r)
+               pr_err("n8x0_panel: dss driver registration failed\n");
+
+       return r;
 }
 
 static int mipid_spi_remove(struct spi_device *spi)
 {
        dev_dbg(&spi->dev, "mipid_spi_remove\n");
+       omap_dss_unregister_driver(&n8x0_panel_driver);
        return 0;
 }
 
@@ -725,34 +682,6 @@ static struct spi_driver mipid_spi_driver = {
        .probe  = mipid_spi_probe,
        .remove = __devexit_p(mipid_spi_remove),
 };
+module_spi_driver(mipid_spi_driver);
 
-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");
index 908fd268f3dc90fd98b3eb4827166a5f5e94214f..2a79c283bebe471b3b9410b2649857b6ec2fe0d0 100644 (file)
@@ -236,28 +236,6 @@ static void nec_8048_panel_disable(struct omap_dss_device *dssdev)
        dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
-static int nec_8048_panel_suspend(struct omap_dss_device *dssdev)
-{
-       nec_8048_panel_power_off(dssdev);
-
-       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
-       return 0;
-}
-
-static int nec_8048_panel_resume(struct omap_dss_device *dssdev)
-{
-       int r;
-
-       r = nec_8048_panel_power_on(dssdev);
-       if (r)
-               return r;
-
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-       return 0;
-}
-
 static int nec_8048_recommended_bpp(struct omap_dss_device *dssdev)
 {
        return 16;
@@ -268,8 +246,6 @@ static struct omap_dss_driver nec_8048_driver = {
        .remove                 = nec_8048_panel_remove,
        .enable                 = nec_8048_panel_enable,
        .disable                = nec_8048_panel_disable,
-       .suspend                = nec_8048_panel_suspend,
-       .resume                 = nec_8048_panel_resume,
        .get_recommended_bpp    = nec_8048_recommended_bpp,
 
        .driver         = {
index 9df87640ddd2b0ed574d93e30c69492756167628..1b94018aac3e0c840f7c7f59e419c5e7eee993bb 100644 (file)
@@ -50,6 +50,7 @@ struct picodlp_i2c_data {
 
 static struct i2c_device_id picodlp_i2c_id[] = {
        { "picodlp_i2c_driver", 0 },
+       { }
 };
 
 struct picodlp_i2c_command {
@@ -503,47 +504,6 @@ static void picodlp_panel_disable(struct omap_dss_device *dssdev)
        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)
 {
@@ -560,9 +520,6 @@ static struct omap_dss_driver picodlp_driver = {
 
        .get_resolution = picodlp_get_resolution,
 
-       .suspend        = picodlp_panel_suspend,
-       .resume         = picodlp_panel_resume,
-
        .driver         = {
                .name   = "picodlp_panel",
                .owner  = THIS_MODULE,
index 1ec3b277ff155edca2861be48f3d013b01334aa1..cada8c621e01bd2f4724c82f61b2557dce9237f5 100644 (file)
@@ -194,29 +194,12 @@ static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
        dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
-static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev)
-{
-       sharp_ls_power_off(dssdev);
-       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-       return 0;
-}
-
-static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
-{
-       int r;
-       r = sharp_ls_power_on(dssdev);
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-       return r;
-}
-
 static struct omap_dss_driver sharp_ls_driver = {
        .probe          = sharp_ls_panel_probe,
        .remove         = __exit_p(sharp_ls_panel_remove),
 
        .enable         = sharp_ls_panel_enable,
        .disable        = sharp_ls_panel_disable,
-       .suspend        = sharp_ls_panel_suspend,
-       .resume         = sharp_ls_panel_resume,
 
        .driver         = {
                .name   = "sharp_ls_panel",
index f2f644680ca8dfe2262fac39c42fcd50766982f0..a32407a5735af59b123c8865c6dcf2ec3220db7a 100644 (file)
@@ -1245,76 +1245,6 @@ static void taal_disable(struct omap_dss_device *dssdev)
        mutex_unlock(&td->lock);
 }
 
-static int taal_suspend(struct omap_dss_device *dssdev)
-{
-       struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-       int r;
-
-       dev_dbg(&dssdev->dev, "suspend\n");
-
-       mutex_lock(&td->lock);
-
-       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
-               r = -EINVAL;
-               goto err;
-       }
-
-       taal_cancel_ulps_work(dssdev);
-       taal_cancel_esd_work(dssdev);
-
-       dsi_bus_lock(dssdev);
-
-       r = taal_wake_up(dssdev);
-       if (!r)
-               taal_power_off(dssdev);
-
-       dsi_bus_unlock(dssdev);
-
-       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
-       mutex_unlock(&td->lock);
-
-       return 0;
-err:
-       mutex_unlock(&td->lock);
-       return r;
-}
-
-static int taal_resume(struct omap_dss_device *dssdev)
-{
-       struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-       int r;
-
-       dev_dbg(&dssdev->dev, "resume\n");
-
-       mutex_lock(&td->lock);
-
-       if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
-               r = -EINVAL;
-               goto err;
-       }
-
-       dsi_bus_lock(dssdev);
-
-       r = taal_power_on(dssdev);
-
-       dsi_bus_unlock(dssdev);
-
-       if (r) {
-               dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-       } else {
-               dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-               taal_queue_esd_work(dssdev);
-       }
-
-       mutex_unlock(&td->lock);
-
-       return r;
-err:
-       mutex_unlock(&td->lock);
-       return r;
-}
-
 static void taal_framedone_cb(int err, void *data)
 {
        struct omap_dss_device *dssdev = data;
@@ -1818,8 +1748,6 @@ static struct omap_dss_driver taal_driver = {
 
        .enable         = taal_enable,
        .disable        = taal_disable,
-       .suspend        = taal_suspend,
-       .resume         = taal_resume,
 
        .update         = taal_update,
        .sync           = taal_sync,
index 383811cf8648bfb199847b9d183d5b50b562cd23..8281baafe1efd39127a628c70ecb3b720034d6f1 100644 (file)
@@ -189,37 +189,6 @@ static void tfp410_disable(struct omap_dss_device *dssdev)
        mutex_unlock(&ddata->lock);
 }
 
-static int tfp410_suspend(struct omap_dss_device *dssdev)
-{
-       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
-
-       mutex_lock(&ddata->lock);
-
-       tfp410_power_off(dssdev);
-
-       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
-       mutex_unlock(&ddata->lock);
-
-       return 0;
-}
-
-static int tfp410_resume(struct omap_dss_device *dssdev)
-{
-       struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
-       int r;
-
-       mutex_lock(&ddata->lock);
-
-       r = tfp410_power_on(dssdev);
-       if (r == 0)
-               dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-       mutex_unlock(&ddata->lock);
-
-       return r;
-}
-
 static void tfp410_set_timings(struct omap_dss_device *dssdev,
                struct omap_video_timings *timings)
 {
@@ -355,8 +324,6 @@ static struct omap_dss_driver tfp410_driver = {
 
        .enable         = tfp410_enable,
        .disable        = tfp410_disable,
-       .suspend        = tfp410_suspend,
-       .resume         = tfp410_resume,
 
        .set_timings    = tfp410_set_timings,
        .get_timings    = tfp410_get_timings,
index b5e6dbc59f0a654c79d9d3b6b40eaba955680c2a..316b3da6d2cb99e356332b3ef218cf3f822c7ab0 100644 (file)
@@ -401,24 +401,6 @@ static void tpo_td043_disable(struct omap_dss_device *dssdev)
        dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
-static int tpo_td043_suspend(struct omap_dss_device *dssdev)
-{
-       dev_dbg(&dssdev->dev, "suspend\n");
-
-       tpo_td043_disable_dss(dssdev);
-
-       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-
-       return 0;
-}
-
-static int tpo_td043_resume(struct omap_dss_device *dssdev)
-{
-       dev_dbg(&dssdev->dev, "resume\n");
-
-       return tpo_td043_enable_dss(dssdev);
-}
-
 static int tpo_td043_probe(struct omap_dss_device *dssdev)
 {
        struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
@@ -500,8 +482,6 @@ static struct omap_dss_driver tpo_td043_driver = {
 
        .enable         = tpo_td043_enable,
        .disable        = tpo_td043_disable,
-       .suspend        = tpo_td043_suspend,
-       .resume         = tpo_td043_resume,
        .set_mirror     = tpo_td043_set_hmirror,
        .get_mirror     = tpo_td043_get_hmirror,
 
index 80f5390aa1368984266071f21e15e6dca859b0e3..cb0f145c7077897721dce128aa0369ce4f6953c8 100644 (file)
@@ -1,33 +1,30 @@
 menuconfig OMAP2_DSS
         tristate "OMAP2+ Display Subsystem support"
-        depends on ARCH_OMAP2PLUS
         help
          OMAP2+ Display Subsystem support.
 
 if OMAP2_DSS
 
-config OMAP2_VRAM_SIZE
-       int "VRAM size (MB)"
-       range 0 32
-       default 0
+config OMAP2_DSS_DEBUG
+       bool "Debug support"
+       default n
        help
-         The amount of SDRAM to reserve at boot time for video RAM use.
-         This VRAM will be used by omapfb and other drivers that need
-         large continuous RAM area for video use.
+         This enables printing of debug messages. Alternatively, debug messages
+         can also be enabled by setting CONFIG_DYNAMIC_DEBUG and then setting
+         appropriate flags in <debugfs>/dynamic_debug/control.
 
-         You can also set this with "vram=<bytes>" kernel argument, or
-         in the board file.
-
-config OMAP2_DSS_DEBUG_SUPPORT
-        bool "Debug support"
-       default y
+config OMAP2_DSS_DEBUGFS
+       bool "Debugfs filesystem support"
+       depends on DEBUG_FS
+       default n
        help
-         This enables debug messages. You need to enable printing
-         with 'debug' module parameter.
+         This enables debugfs for OMAPDSS at <debugfs>/omapdss. This enables
+         querying about clock configuration and register configuration of dss,
+         dispc, dsi, hdmi and rfbi.
 
 config OMAP2_DSS_COLLECT_IRQ_STATS
        bool "Collect DSS IRQ statistics"
-       depends on OMAP2_DSS_DEBUG_SUPPORT
+       depends on OMAP2_DSS_DEBUGFS
        default n
        help
          Collect DSS IRQ statistics, printable via debugfs.
@@ -62,7 +59,6 @@ config OMAP2_DSS_VENC
 
 config OMAP4_DSS_HDMI
        bool "HDMI support"
-       depends on ARCH_OMAP4
         default y
        help
          HDMI Interface. This adds the High Definition Multimedia Interface.
@@ -70,11 +66,9 @@ config OMAP4_DSS_HDMI
 
 config OMAP4_DSS_HDMI_AUDIO
        bool
-       depends on OMAP4_DSS_HDMI
 
 config OMAP2_DSS_SDI
        bool "SDI support"
-       depends on ARCH_OMAP3
         default n
        help
          SDI (Serial Display Interface) support.
@@ -84,7 +78,6 @@ config OMAP2_DSS_SDI
 
 config OMAP2_DSS_DSI
        bool "DSI support"
-       depends on ARCH_OMAP3 || ARCH_OMAP4 || ARCH_OMAP5
         default n
        help
          MIPI DSI (Display Serial Interface) support.
index 4549869bfe1a75ef6ffb1262409d918295151754..61949ff7940cf4257d7d2c489eb6fe4960436b15 100644 (file)
@@ -1,6 +1,10 @@
 obj-$(CONFIG_OMAP2_DSS) += omapdss.o
+# Core DSS files
 omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
-       manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o
+       output.o
+# DSS compat layer files
+omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \
+       dispc-compat.o display-sysfs.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
 omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
@@ -8,3 +12,4 @@ omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
 omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
 omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
                                    hdmi_panel.o ti_hdmi_4xxx_ip.o
+ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG
index 19d66f471b4bae9eafe0331b511a24265f4717ee..d446bdfc4c821fc4a26caf401716cc843cef370a 100644 (file)
@@ -18,6 +18,7 @@
 #define DSS_SUBSYS_NAME "APPLY"
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/jiffies.h>
@@ -26,6 +27,7 @@
 
 #include "dss.h"
 #include "dss_features.h"
+#include "dispc-compat.h"
 
 /*
  * We have 4 levels of cache for the dispc settings. First two are in SW and
@@ -70,7 +72,6 @@ struct ovl_priv_data {
        bool shadow_extra_info_dirty;
 
        bool enabled;
-       enum omap_channel channel;
        u32 fifo_low, fifo_high;
 
        /*
@@ -105,6 +106,9 @@ struct mgr_priv_data {
 
        struct omap_video_timings timings;
        struct dss_lcd_mgr_config lcd_config;
+
+       void (*framedone_handler)(void *);
+       void *framedone_handler_data;
 };
 
 static struct {
@@ -132,7 +136,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
        return &dss_data.mgr_priv_data_array[mgr->id];
 }
 
-void dss_apply_init(void)
+static void apply_init_priv(void)
 {
        const int num_ovls = dss_feat_get_num_ovls();
        struct mgr_priv_data *mp;
@@ -414,11 +418,46 @@ static void wait_pending_extra_info_updates(void)
        r = wait_for_completion_timeout(&extra_updated_completion, t);
        if (r == 0)
                DSSWARN("timeout in wait_pending_extra_info_updates\n");
-       else if (r < 0)
-               DSSERR("wait_pending_extra_info_updates failed: %d\n", r);
 }
 
-int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
+static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
+{
+       return ovl->manager ?
+               (ovl->manager->output ? ovl->manager->output->device : NULL) :
+               NULL;
+}
+
+static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
+{
+       return mgr->output ? mgr->output->device : NULL;
+}
+
+static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
+{
+       unsigned long timeout = msecs_to_jiffies(500);
+       struct omap_dss_device *dssdev = mgr->get_device(mgr);
+       u32 irq;
+       int r;
+
+       r = dispc_runtime_get();
+       if (r)
+               return r;
+
+       if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
+               irq = DISPC_IRQ_EVSYNC_ODD;
+       else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
+               irq = DISPC_IRQ_EVSYNC_EVEN;
+       else
+               irq = dispc_mgr_get_vsync_irq(mgr->id);
+
+       r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
+
+       dispc_runtime_put();
+
+       return r;
+}
+
+static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
 {
        unsigned long timeout = msecs_to_jiffies(500);
        struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -488,7 +527,7 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
        return r;
 }
 
-int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
+static int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
 {
        unsigned long timeout = msecs_to_jiffies(500);
        struct ovl_priv_data *op;
@@ -573,7 +612,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
        struct mgr_priv_data *mp;
        int r;
 
-       DSSDBGF("%d", ovl->id);
+       DSSDBG("writing ovl %d regs", ovl->id);
 
        if (!op->enabled || !op->info_dirty)
                return;
@@ -608,7 +647,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
        struct ovl_priv_data *op = get_ovl_priv(ovl);
        struct mgr_priv_data *mp;
 
-       DSSDBGF("%d", ovl->id);
+       DSSDBG("writing ovl %d regs extra", ovl->id);
 
        if (!op->extra_info_dirty)
                return;
@@ -617,7 +656,6 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
         * disabled */
 
        dispc_ovl_enable(ovl->id, op->enabled);
-       dispc_ovl_set_channel_out(ovl->id, op->channel);
        dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
 
        mp = get_mgr_priv(ovl->manager);
@@ -632,7 +670,7 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
        struct mgr_priv_data *mp = get_mgr_priv(mgr);
        struct omap_overlay *ovl;
 
-       DSSDBGF("%d", mgr->id);
+       DSSDBG("writing mgr %d regs", mgr->id);
 
        if (!mp->enabled)
                return;
@@ -658,7 +696,7 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
 {
        struct mgr_priv_data *mp = get_mgr_priv(mgr);
 
-       DSSDBGF("%d", mgr->id);
+       DSSDBG("writing mgr %d regs extra", mgr->id);
 
        if (!mp->extra_info_dirty)
                return;
@@ -666,22 +704,8 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
        dispc_mgr_set_timings(mgr->id, &mp->timings);
 
        /* lcd_config parameters */
-       if (dss_mgr_is_lcd(mgr->id)) {
-               dispc_mgr_set_io_pad_mode(mp->lcd_config.io_pad_mode);
-
-               dispc_mgr_enable_stallmode(mgr->id, mp->lcd_config.stallmode);
-               dispc_mgr_enable_fifohandcheck(mgr->id,
-                       mp->lcd_config.fifohandcheck);
-
-               dispc_mgr_set_clock_div(mgr->id, &mp->lcd_config.clock_info);
-
-               dispc_mgr_set_tft_data_lines(mgr->id,
-                       mp->lcd_config.video_port_width);
-
-               dispc_lcd_enable_signal_polarity(mp->lcd_config.lcden_sig_polarity);
-
-               dispc_mgr_set_lcd_type_tft(mgr->id);
-       }
+       if (dss_mgr_is_lcd(mgr->id))
+               dispc_mgr_set_lcd_config(mgr->id, &mp->lcd_config);
 
        mp->extra_info_dirty = false;
        if (mp->updating)
@@ -761,7 +785,7 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
        }
 }
 
-void dss_mgr_start_update(struct omap_overlay_manager *mgr)
+static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr)
 {
        struct mgr_priv_data *mp = get_mgr_priv(mgr);
        unsigned long flags;
@@ -786,9 +810,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
        if (!dss_data.irq_enabled && need_isr())
                dss_register_vsync_isr();
 
-       dispc_mgr_enable(mgr->id, true);
-
-       mgr_clear_shadow_dirty(mgr);
+       dispc_mgr_enable_sync(mgr->id);
 
        spin_unlock_irqrestore(&data_lock, flags);
 }
@@ -845,7 +867,6 @@ static void dss_apply_irq_handler(void *data, u32 mask)
        for (i = 0; i < num_mgrs; i++) {
                struct omap_overlay_manager *mgr;
                struct mgr_priv_data *mp;
-               bool was_updating;
 
                mgr = omap_dss_get_overlay_manager(i);
                mp = get_mgr_priv(mgr);
@@ -853,7 +874,6 @@ static void dss_apply_irq_handler(void *data, u32 mask)
                if (!mp->enabled)
                        continue;
 
-               was_updating = mp->updating;
                mp->updating = dispc_mgr_is_enabled(i);
 
                if (!mgr_manual_update(mgr)) {
@@ -872,6 +892,21 @@ static void dss_apply_irq_handler(void *data, u32 mask)
        if (!extra_updating)
                complete_all(&extra_updated_completion);
 
+       /* call framedone handlers for manual update displays */
+       for (i = 0; i < num_mgrs; i++) {
+               struct omap_overlay_manager *mgr;
+               struct mgr_priv_data *mp;
+
+               mgr = omap_dss_get_overlay_manager(i);
+               mp = get_mgr_priv(mgr);
+
+               if (!mgr_manual_update(mgr) || !mp->framedone_handler)
+                       continue;
+
+               if (mask & dispc_mgr_get_framedone_irq(i))
+                       mp->framedone_handler(mp->framedone_handler_data);
+       }
+
        if (!need_isr())
                dss_unregister_vsync_isr();
 
@@ -906,7 +941,7 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
        mp->info = mp->user_info;
 }
 
-int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
 {
        unsigned long flags;
        struct omap_overlay *ovl;
@@ -1005,7 +1040,7 @@ static void dss_setup_fifos(void)
        }
 }
 
-int dss_mgr_enable(struct omap_overlay_manager *mgr)
+static int dss_mgr_enable_compat(struct omap_overlay_manager *mgr)
 {
        struct mgr_priv_data *mp = get_mgr_priv(mgr);
        unsigned long flags;
@@ -1035,10 +1070,13 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
        if (!mgr_manual_update(mgr))
                mp->updating = true;
 
+       if (!dss_data.irq_enabled && need_isr())
+               dss_register_vsync_isr();
+
        spin_unlock_irqrestore(&data_lock, flags);
 
        if (!mgr_manual_update(mgr))
-               dispc_mgr_enable(mgr->id, true);
+               dispc_mgr_enable_sync(mgr->id);
 
 out:
        mutex_unlock(&apply_lock);
@@ -1052,7 +1090,7 @@ err:
        return r;
 }
 
-void dss_mgr_disable(struct omap_overlay_manager *mgr)
+static void dss_mgr_disable_compat(struct omap_overlay_manager *mgr)
 {
        struct mgr_priv_data *mp = get_mgr_priv(mgr);
        unsigned long flags;
@@ -1063,7 +1101,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
                goto out;
 
        if (!mgr_manual_update(mgr))
-               dispc_mgr_enable(mgr->id, false);
+               dispc_mgr_disable_sync(mgr->id);
 
        spin_lock_irqsave(&data_lock, flags);
 
@@ -1076,7 +1114,7 @@ out:
        mutex_unlock(&apply_lock);
 }
 
-int dss_mgr_set_info(struct omap_overlay_manager *mgr,
+static int dss_mgr_set_info(struct omap_overlay_manager *mgr,
                struct omap_overlay_manager_info *info)
 {
        struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1097,7 +1135,7 @@ int dss_mgr_set_info(struct omap_overlay_manager *mgr,
        return 0;
 }
 
-void dss_mgr_get_info(struct omap_overlay_manager *mgr,
+static void dss_mgr_get_info(struct omap_overlay_manager *mgr,
                struct omap_overlay_manager_info *info)
 {
        struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1110,7 +1148,7 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
        spin_unlock_irqrestore(&data_lock, flags);
 }
 
-int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+static int dss_mgr_set_output(struct omap_overlay_manager *mgr,
                struct omap_dss_output *output)
 {
        int r;
@@ -1142,7 +1180,7 @@ err:
        return r;
 }
 
-int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
+static int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
 {
        int r;
        struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -1189,7 +1227,7 @@ static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
        mp->extra_info_dirty = true;
 }
 
-void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
+static void dss_mgr_set_timings_compat(struct omap_overlay_manager *mgr,
                const struct omap_video_timings *timings)
 {
        unsigned long flags;
@@ -1217,7 +1255,7 @@ static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
        mp->extra_info_dirty = true;
 }
 
-void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
+static void dss_mgr_set_lcd_config_compat(struct omap_overlay_manager *mgr,
                const struct dss_lcd_mgr_config *config)
 {
        unsigned long flags;
@@ -1236,7 +1274,7 @@ out:
        spin_unlock_irqrestore(&data_lock, flags);
 }
 
-int dss_ovl_set_info(struct omap_overlay *ovl,
+static int dss_ovl_set_info(struct omap_overlay *ovl,
                struct omap_overlay_info *info)
 {
        struct ovl_priv_data *op = get_ovl_priv(ovl);
@@ -1257,7 +1295,7 @@ int dss_ovl_set_info(struct omap_overlay *ovl,
        return 0;
 }
 
-void dss_ovl_get_info(struct omap_overlay *ovl,
+static void dss_ovl_get_info(struct omap_overlay *ovl,
                struct omap_overlay_info *info)
 {
        struct ovl_priv_data *op = get_ovl_priv(ovl);
@@ -1270,7 +1308,7 @@ void dss_ovl_get_info(struct omap_overlay *ovl,
        spin_unlock_irqrestore(&data_lock, flags);
 }
 
-int dss_ovl_set_manager(struct omap_overlay *ovl,
+static int dss_ovl_set_manager(struct omap_overlay *ovl,
                struct omap_overlay_manager *mgr)
 {
        struct ovl_priv_data *op = get_ovl_priv(ovl);
@@ -1289,45 +1327,40 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
                goto err;
        }
 
+       r = dispc_runtime_get();
+       if (r)
+               goto err;
+
        spin_lock_irqsave(&data_lock, flags);
 
        if (op->enabled) {
                spin_unlock_irqrestore(&data_lock, flags);
                DSSERR("overlay has to be disabled to change the manager\n");
                r = -EINVAL;
-               goto err;
+               goto err1;
        }
 
-       op->channel = mgr->id;
-       op->extra_info_dirty = true;
+       dispc_ovl_set_channel_out(ovl->id, mgr->id);
 
        ovl->manager = mgr;
        list_add_tail(&ovl->list, &mgr->overlays);
 
        spin_unlock_irqrestore(&data_lock, flags);
 
-       /* XXX: When there is an overlay on a DSI manual update display, and
-        * the overlay is first disabled, then moved to tv, and enabled, we
-        * seem to get SYNC_LOST_DIGIT error.
-        *
-        * Waiting doesn't seem to help, but updating the manual update display
-        * after disabling the overlay seems to fix this. This hints that the
-        * overlay is perhaps somehow tied to the LCD output until the output
-        * is updated.
-        *
-        * Userspace workaround for this is to update the LCD after disabling
-        * the overlay, but before moving the overlay to TV.
-        */
+       dispc_runtime_put();
 
        mutex_unlock(&apply_lock);
 
        return 0;
+
+err1:
+       dispc_runtime_put();
 err:
        mutex_unlock(&apply_lock);
        return r;
 }
 
-int dss_ovl_unset_manager(struct omap_overlay *ovl)
+static int dss_ovl_unset_manager(struct omap_overlay *ovl)
 {
        struct ovl_priv_data *op = get_ovl_priv(ovl);
        unsigned long flags;
@@ -1355,9 +1388,24 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
        /* wait for pending extra_info updates to ensure the ovl is disabled */
        wait_pending_extra_info_updates();
 
+       /*
+        * For a manual update display, there is no guarantee that the overlay
+        * is really disabled in HW, we may need an extra update from this
+        * manager before the configurations can go in. Return an error if the
+        * overlay needed an update from the manager.
+        *
+        * TODO: Instead of returning an error, try to do a dummy manager update
+        * here to disable the overlay in hardware. Use the *GATED fields in
+        * the DISPC_CONFIG registers to do a dummy update.
+        */
        spin_lock_irqsave(&data_lock, flags);
 
-       op->channel = -1;
+       if (ovl_manual_update(ovl) && op->extra_info_dirty) {
+               spin_unlock_irqrestore(&data_lock, flags);
+               DSSERR("need an update to change the manager\n");
+               r = -EINVAL;
+               goto err;
+       }
 
        ovl->manager = NULL;
        list_del(&ovl->list);
@@ -1372,7 +1420,7 @@ err:
        return r;
 }
 
-bool dss_ovl_is_enabled(struct omap_overlay *ovl)
+static bool dss_ovl_is_enabled(struct omap_overlay *ovl)
 {
        struct ovl_priv_data *op = get_ovl_priv(ovl);
        unsigned long flags;
@@ -1387,7 +1435,7 @@ bool dss_ovl_is_enabled(struct omap_overlay *ovl)
        return e;
 }
 
-int dss_ovl_enable(struct omap_overlay *ovl)
+static int dss_ovl_enable(struct omap_overlay *ovl)
 {
        struct ovl_priv_data *op = get_ovl_priv(ovl);
        unsigned long flags;
@@ -1437,7 +1485,7 @@ err1:
        return r;
 }
 
-int dss_ovl_disable(struct omap_overlay *ovl)
+static int dss_ovl_disable(struct omap_overlay *ovl)
 {
        struct ovl_priv_data *op = get_ovl_priv(ovl);
        unsigned long flags;
@@ -1472,3 +1520,152 @@ err:
        return r;
 }
 
+static int dss_mgr_register_framedone_handler_compat(struct omap_overlay_manager *mgr,
+               void (*handler)(void *), void *data)
+{
+       struct mgr_priv_data *mp = get_mgr_priv(mgr);
+
+       if (mp->framedone_handler)
+               return -EBUSY;
+
+       mp->framedone_handler = handler;
+       mp->framedone_handler_data = data;
+
+       return 0;
+}
+
+static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_manager *mgr,
+               void (*handler)(void *), void *data)
+{
+       struct mgr_priv_data *mp = get_mgr_priv(mgr);
+
+       WARN_ON(mp->framedone_handler != handler ||
+                       mp->framedone_handler_data != data);
+
+       mp->framedone_handler = NULL;
+       mp->framedone_handler_data = NULL;
+}
+
+static const struct dss_mgr_ops apply_mgr_ops = {
+       .start_update = dss_mgr_start_update_compat,
+       .enable = dss_mgr_enable_compat,
+       .disable = dss_mgr_disable_compat,
+       .set_timings = dss_mgr_set_timings_compat,
+       .set_lcd_config = dss_mgr_set_lcd_config_compat,
+       .register_framedone_handler = dss_mgr_register_framedone_handler_compat,
+       .unregister_framedone_handler = dss_mgr_unregister_framedone_handler_compat,
+};
+
+static int compat_refcnt;
+static DEFINE_MUTEX(compat_init_lock);
+
+int omapdss_compat_init(void)
+{
+       struct platform_device *pdev = dss_get_core_pdev();
+       struct omap_dss_device *dssdev = NULL;
+       int i, r;
+
+       mutex_lock(&compat_init_lock);
+
+       if (compat_refcnt++ > 0)
+               goto out;
+
+       apply_init_priv();
+
+       dss_init_overlay_managers(pdev);
+       dss_init_overlays(pdev);
+
+       for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
+               struct omap_overlay_manager *mgr;
+
+               mgr = omap_dss_get_overlay_manager(i);
+
+               mgr->set_output = &dss_mgr_set_output;
+               mgr->unset_output = &dss_mgr_unset_output;
+               mgr->apply = &omap_dss_mgr_apply;
+               mgr->set_manager_info = &dss_mgr_set_info;
+               mgr->get_manager_info = &dss_mgr_get_info;
+               mgr->wait_for_go = &dss_mgr_wait_for_go;
+               mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
+               mgr->get_device = &dss_mgr_get_device;
+       }
+
+       for (i = 0; i < omap_dss_get_num_overlays(); i++) {
+               struct omap_overlay *ovl = omap_dss_get_overlay(i);
+
+               ovl->is_enabled = &dss_ovl_is_enabled;
+               ovl->enable = &dss_ovl_enable;
+               ovl->disable = &dss_ovl_disable;
+               ovl->set_manager = &dss_ovl_set_manager;
+               ovl->unset_manager = &dss_ovl_unset_manager;
+               ovl->set_overlay_info = &dss_ovl_set_info;
+               ovl->get_overlay_info = &dss_ovl_get_info;
+               ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
+               ovl->get_device = &dss_ovl_get_device;
+       }
+
+       r = dss_install_mgr_ops(&apply_mgr_ops);
+       if (r)
+               goto err_mgr_ops;
+
+       for_each_dss_dev(dssdev) {
+               r = display_init_sysfs(pdev, dssdev);
+               /* XXX uninit sysfs files on error */
+               if (r)
+                       goto err_disp_sysfs;
+       }
+
+       dispc_runtime_get();
+
+       r = dss_dispc_initialize_irq();
+       if (r)
+               goto err_init_irq;
+
+       dispc_runtime_put();
+
+out:
+       mutex_unlock(&compat_init_lock);
+
+       return 0;
+
+err_init_irq:
+       dispc_runtime_put();
+
+err_disp_sysfs:
+       dss_uninstall_mgr_ops();
+
+err_mgr_ops:
+       dss_uninit_overlay_managers(pdev);
+       dss_uninit_overlays(pdev);
+
+       compat_refcnt--;
+
+       mutex_unlock(&compat_init_lock);
+
+       return r;
+}
+EXPORT_SYMBOL(omapdss_compat_init);
+
+void omapdss_compat_uninit(void)
+{
+       struct platform_device *pdev = dss_get_core_pdev();
+       struct omap_dss_device *dssdev = NULL;
+
+       mutex_lock(&compat_init_lock);
+
+       if (--compat_refcnt > 0)
+               goto out;
+
+       dss_dispc_uninitialize_irq();
+
+       for_each_dss_dev(dssdev)
+               display_uninit_sysfs(pdev, dssdev);
+
+       dss_uninstall_mgr_ops();
+
+       dss_uninit_overlay_managers(pdev);
+       dss_uninit_overlays(pdev);
+out:
+       mutex_unlock(&compat_init_lock);
+}
+EXPORT_SYMBOL(omapdss_compat_uninit);
index b2af72dc20bdb2cf0cc5f880008916fb85d09826..f8779d4750ba63f98908492f2b11b9bfe7cf4ea8 100644 (file)
@@ -53,15 +53,23 @@ static char *def_disp_name;
 module_param_named(def_disp, def_disp_name, charp, 0);
 MODULE_PARM_DESC(def_disp, "default display name");
 
-#ifdef DEBUG
-bool dss_debug;
-module_param_named(debug, dss_debug, bool, 0644);
-#endif
-
-const char *dss_get_default_display_name(void)
+const char *omapdss_get_default_display_name(void)
 {
        return core.default_display_name;
 }
+EXPORT_SYMBOL(omapdss_get_default_display_name);
+
+enum omapdss_version omapdss_get_version(void)
+{
+       struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
+       return pdata->version;
+}
+EXPORT_SYMBOL(omapdss_get_version);
+
+struct platform_device *dss_get_core_pdev(void)
+{
+       return core.pdev;
+}
 
 /* REGULATORS */
 
@@ -93,21 +101,6 @@ struct regulator *dss_get_vdds_sdi(void)
        return reg;
 }
 
-int dss_get_ctx_loss_count(struct device *dev)
-{
-       struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
-       int cnt;
-
-       if (!board_data->get_context_loss_count)
-               return -ENOENT;
-
-       cnt = board_data->get_context_loss_count(dev);
-
-       WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt);
-
-       return cnt;
-}
-
 int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask)
 {
        struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
@@ -122,7 +115,7 @@ void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask)
 {
        struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
 
-       if (!board_data->dsi_enable_pads)
+       if (!board_data->dsi_disable_pads)
                return;
 
        return board_data->dsi_disable_pads(dsi_id, lane_mask);
@@ -138,7 +131,7 @@ int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
                return 0;
 }
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
 static int dss_debug_show(struct seq_file *s, void *unused)
 {
        void (*func)(struct seq_file *) = s->private;
@@ -193,7 +186,7 @@ int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
 
        return 0;
 }
-#else /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */
+#else /* CONFIG_OMAP2_DSS_DEBUGFS */
 static inline int dss_initialize_debugfs(void)
 {
        return 0;
@@ -205,7 +198,7 @@ int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
 {
        return 0;
 }
-#endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */
+#endif /* CONFIG_OMAP2_DSS_DEBUGFS */
 
 /* PLATFORM DEVICE */
 static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)
@@ -237,12 +230,7 @@ static int __init omap_dss_probe(struct platform_device *pdev)
 
        core.pdev = pdev;
 
-       dss_features_init();
-
-       dss_apply_init();
-
-       dss_init_overlay_managers(pdev);
-       dss_init_overlays(pdev);
+       dss_features_init(omapdss_get_version());
 
        r = dss_initialize_debugfs();
        if (r)
@@ -268,9 +256,6 @@ static int omap_dss_remove(struct platform_device *pdev)
 
        dss_uninitialize_debugfs();
 
-       dss_uninit_overlays(pdev);
-       dss_uninit_overlay_managers(pdev);
-
        return 0;
 }
 
@@ -358,15 +343,10 @@ static int dss_driver_probe(struct device *dev)
                                dev_name(dev), dssdev->driver_name,
                                dssdrv->driver.name);
 
-       r = dss_init_device(core.pdev, dssdev);
-       if (r)
-               return r;
-
        r = dssdrv->probe(dssdev);
 
        if (r) {
                DSSERR("driver probe failed: %d\n", r);
-               dss_uninit_device(core.pdev, dssdev);
                return r;
        }
 
@@ -387,8 +367,6 @@ static int dss_driver_remove(struct device *dev)
 
        dssdrv->remove(dssdev);
 
-       dss_uninit_device(core.pdev, dssdev);
-
        dssdev->driver = NULL;
 
        return 0;
@@ -507,6 +485,9 @@ static int __init omap_dss_bus_register(void)
 
 /* INIT */
 static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
+#ifdef CONFIG_OMAP2_DSS_DSI
+       dsi_init_platform_driver,
+#endif
 #ifdef CONFIG_OMAP2_DSS_DPI
        dpi_init_platform_driver,
 #endif
@@ -519,15 +500,15 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
 #ifdef CONFIG_OMAP2_DSS_VENC
        venc_init_platform_driver,
 #endif
-#ifdef CONFIG_OMAP2_DSS_DSI
-       dsi_init_platform_driver,
-#endif
 #ifdef CONFIG_OMAP4_DSS_HDMI
        hdmi_init_platform_driver,
 #endif
 };
 
 static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = {
+#ifdef CONFIG_OMAP2_DSS_DSI
+       dsi_uninit_platform_driver,
+#endif
 #ifdef CONFIG_OMAP2_DSS_DPI
        dpi_uninit_platform_driver,
 #endif
@@ -540,9 +521,6 @@ static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = {
 #ifdef CONFIG_OMAP2_DSS_VENC
        venc_uninit_platform_driver,
 #endif
-#ifdef CONFIG_OMAP2_DSS_DSI
-       dsi_uninit_platform_driver,
-#endif
 #ifdef CONFIG_OMAP4_DSS_HDMI
        hdmi_uninit_platform_driver,
 #endif
diff --git a/drivers/video/omap2/dss/dispc-compat.c b/drivers/video/omap2/dss/dispc-compat.c
new file mode 100644 (file)
index 0000000..928884c
--- /dev/null
@@ -0,0 +1,667 @@
+/*
+ * Copyright (C) 2012 Texas Instruments
+ * 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/>.
+ */
+
+#define DSS_SUBSYS_NAME "APPLY"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/seq_file.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+#include "dss_features.h"
+#include "dispc-compat.h"
+
+#define DISPC_IRQ_MASK_ERROR            (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
+                                        DISPC_IRQ_OCP_ERR | \
+                                        DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
+                                        DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
+                                        DISPC_IRQ_SYNC_LOST | \
+                                        DISPC_IRQ_SYNC_LOST_DIGIT)
+
+#define DISPC_MAX_NR_ISRS              8
+
+struct omap_dispc_isr_data {
+       omap_dispc_isr_t        isr;
+       void                    *arg;
+       u32                     mask;
+};
+
+struct dispc_irq_stats {
+       unsigned long last_reset;
+       unsigned irq_count;
+       unsigned irqs[32];
+};
+
+static struct {
+       spinlock_t irq_lock;
+       u32 irq_error_mask;
+       struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
+       u32 error_irqs;
+       struct work_struct error_work;
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+       spinlock_t irq_stats_lock;
+       struct dispc_irq_stats irq_stats;
+#endif
+} dispc_compat;
+
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+static void dispc_dump_irqs(struct seq_file *s)
+{
+       unsigned long flags;
+       struct dispc_irq_stats stats;
+
+       spin_lock_irqsave(&dispc_compat.irq_stats_lock, flags);
+
+       stats = dispc_compat.irq_stats;
+       memset(&dispc_compat.irq_stats, 0, sizeof(dispc_compat.irq_stats));
+       dispc_compat.irq_stats.last_reset = jiffies;
+
+       spin_unlock_irqrestore(&dispc_compat.irq_stats_lock, flags);
+
+       seq_printf(s, "period %u ms\n",
+                       jiffies_to_msecs(jiffies - stats.last_reset));
+
+       seq_printf(s, "irqs %d\n", stats.irq_count);
+#define PIS(x) \
+       seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]);
+
+       PIS(FRAMEDONE);
+       PIS(VSYNC);
+       PIS(EVSYNC_EVEN);
+       PIS(EVSYNC_ODD);
+       PIS(ACBIAS_COUNT_STAT);
+       PIS(PROG_LINE_NUM);
+       PIS(GFX_FIFO_UNDERFLOW);
+       PIS(GFX_END_WIN);
+       PIS(PAL_GAMMA_MASK);
+       PIS(OCP_ERR);
+       PIS(VID1_FIFO_UNDERFLOW);
+       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);
+       if (dss_has_feature(FEAT_MGR_LCD2)) {
+               PIS(FRAMEDONE2);
+               PIS(VSYNC2);
+               PIS(ACBIAS_COUNT_STAT2);
+               PIS(SYNC_LOST2);
+       }
+       if (dss_has_feature(FEAT_MGR_LCD3)) {
+               PIS(FRAMEDONE3);
+               PIS(VSYNC3);
+               PIS(ACBIAS_COUNT_STAT3);
+               PIS(SYNC_LOST3);
+       }
+#undef PIS
+}
+#endif
+
+/* dispc.irq_lock has to be locked by the caller */
+static void _omap_dispc_set_irqs(void)
+{
+       u32 mask;
+       int i;
+       struct omap_dispc_isr_data *isr_data;
+
+       mask = dispc_compat.irq_error_mask;
+
+       for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+               isr_data = &dispc_compat.registered_isr[i];
+
+               if (isr_data->isr == NULL)
+                       continue;
+
+               mask |= isr_data->mask;
+       }
+
+       dispc_write_irqenable(mask);
+}
+
+int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+{
+       int i;
+       int ret;
+       unsigned long flags;
+       struct omap_dispc_isr_data *isr_data;
+
+       if (isr == NULL)
+               return -EINVAL;
+
+       spin_lock_irqsave(&dispc_compat.irq_lock, flags);
+
+       /* check for duplicate entry */
+       for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+               isr_data = &dispc_compat.registered_isr[i];
+               if (isr_data->isr == isr && isr_data->arg == arg &&
+                               isr_data->mask == mask) {
+                       ret = -EINVAL;
+                       goto err;
+               }
+       }
+
+       isr_data = NULL;
+       ret = -EBUSY;
+
+       for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+               isr_data = &dispc_compat.registered_isr[i];
+
+               if (isr_data->isr != NULL)
+                       continue;
+
+               isr_data->isr = isr;
+               isr_data->arg = arg;
+               isr_data->mask = mask;
+               ret = 0;
+
+               break;
+       }
+
+       if (ret)
+               goto err;
+
+       _omap_dispc_set_irqs();
+
+       spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
+
+       return 0;
+err:
+       spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(omap_dispc_register_isr);
+
+int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+{
+       int i;
+       unsigned long flags;
+       int ret = -EINVAL;
+       struct omap_dispc_isr_data *isr_data;
+
+       spin_lock_irqsave(&dispc_compat.irq_lock, flags);
+
+       for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+               isr_data = &dispc_compat.registered_isr[i];
+               if (isr_data->isr != isr || isr_data->arg != arg ||
+                               isr_data->mask != mask)
+                       continue;
+
+               /* found the correct isr */
+
+               isr_data->isr = NULL;
+               isr_data->arg = NULL;
+               isr_data->mask = 0;
+
+               ret = 0;
+               break;
+       }
+
+       if (ret == 0)
+               _omap_dispc_set_irqs();
+
+       spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(omap_dispc_unregister_isr);
+
+static void print_irq_status(u32 status)
+{
+       if ((status & dispc_compat.irq_error_mask) == 0)
+               return;
+
+#define PIS(x) (status & DISPC_IRQ_##x) ? (#x " ") : ""
+
+       pr_debug("DISPC IRQ: 0x%x: %s%s%s%s%s%s%s%s%s\n",
+               status,
+               PIS(OCP_ERR),
+               PIS(GFX_FIFO_UNDERFLOW),
+               PIS(VID1_FIFO_UNDERFLOW),
+               PIS(VID2_FIFO_UNDERFLOW),
+               dss_feat_get_num_ovls() > 3 ? PIS(VID3_FIFO_UNDERFLOW) : "",
+               PIS(SYNC_LOST),
+               PIS(SYNC_LOST_DIGIT),
+               dss_has_feature(FEAT_MGR_LCD2) ? PIS(SYNC_LOST2) : "",
+               dss_has_feature(FEAT_MGR_LCD3) ? PIS(SYNC_LOST3) : "");
+#undef PIS
+}
+
+/* Called from dss.c. Note that we don't touch clocks here,
+ * but we presume they are on because we got an IRQ. However,
+ * an irq handler may turn the clocks off, so we may not have
+ * clock later in the function. */
+static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
+{
+       int i;
+       u32 irqstatus, irqenable;
+       u32 handledirqs = 0;
+       u32 unhandled_errors;
+       struct omap_dispc_isr_data *isr_data;
+       struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
+
+       spin_lock(&dispc_compat.irq_lock);
+
+       irqstatus = dispc_read_irqstatus();
+       irqenable = dispc_read_irqenable();
+
+       /* IRQ is not for us */
+       if (!(irqstatus & irqenable)) {
+               spin_unlock(&dispc_compat.irq_lock);
+               return IRQ_NONE;
+       }
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+       spin_lock(&dispc_compat.irq_stats_lock);
+       dispc_compat.irq_stats.irq_count++;
+       dss_collect_irq_stats(irqstatus, dispc_compat.irq_stats.irqs);
+       spin_unlock(&dispc_compat.irq_stats_lock);
+#endif
+
+       print_irq_status(irqstatus);
+
+       /* Ack the interrupt. Do it here before clocks are possibly turned
+        * off */
+       dispc_clear_irqstatus(irqstatus);
+       /* flush posted write */
+       dispc_read_irqstatus();
+
+       /* make a copy and unlock, so that isrs can unregister
+        * themselves */
+       memcpy(registered_isr, dispc_compat.registered_isr,
+                       sizeof(registered_isr));
+
+       spin_unlock(&dispc_compat.irq_lock);
+
+       for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
+               isr_data = &registered_isr[i];
+
+               if (!isr_data->isr)
+                       continue;
+
+               if (isr_data->mask & irqstatus) {
+                       isr_data->isr(isr_data->arg, irqstatus);
+                       handledirqs |= isr_data->mask;
+               }
+       }
+
+       spin_lock(&dispc_compat.irq_lock);
+
+       unhandled_errors = irqstatus & ~handledirqs & dispc_compat.irq_error_mask;
+
+       if (unhandled_errors) {
+               dispc_compat.error_irqs |= unhandled_errors;
+
+               dispc_compat.irq_error_mask &= ~unhandled_errors;
+               _omap_dispc_set_irqs();
+
+               schedule_work(&dispc_compat.error_work);
+       }
+
+       spin_unlock(&dispc_compat.irq_lock);
+
+       return IRQ_HANDLED;
+}
+
+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,
+       };
+
+       spin_lock_irqsave(&dispc_compat.irq_lock, flags);
+       errors = dispc_compat.error_irqs;
+       dispc_compat.error_irqs = 0;
+       spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
+
+       dispc_runtime_get();
+
+       for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+               struct omap_overlay *ovl;
+               unsigned bit;
+
+               ovl = omap_dss_get_overlay(i);
+               bit = fifo_underflow_bits[i];
+
+               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);
+                       msleep(50);
+               }
+       }
+
+       for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
+               struct omap_overlay_manager *mgr;
+               unsigned bit;
+
+               mgr = omap_dss_get_overlay_manager(i);
+               bit = dispc_mgr_get_sync_lost_irq(i);
+
+               if (bit & errors) {
+                       int j;
+
+                       DSSERR("SYNC_LOST on channel %s, restarting the output "
+                                       "with video overlays disabled\n",
+                                       mgr->name);
+
+                       dss_mgr_disable(mgr);
+
+                       for (j = 0; j < omap_dss_get_num_overlays(); ++j) {
+                               struct omap_overlay *ovl;
+                               ovl = omap_dss_get_overlay(j);
+
+                               if (ovl->id != OMAP_DSS_GFX &&
+                                               ovl->manager == mgr)
+                                       ovl->disable(ovl);
+                       }
+
+                       dss_mgr_enable(mgr);
+               }
+       }
+
+       if (errors & DISPC_IRQ_OCP_ERR) {
+               DSSERR("OCP_ERR\n");
+               for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
+                       struct omap_overlay_manager *mgr;
+
+                       mgr = omap_dss_get_overlay_manager(i);
+                       dss_mgr_disable(mgr);
+               }
+       }
+
+       spin_lock_irqsave(&dispc_compat.irq_lock, flags);
+       dispc_compat.irq_error_mask |= errors;
+       _omap_dispc_set_irqs();
+       spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
+
+       dispc_runtime_put();
+}
+
+int dss_dispc_initialize_irq(void)
+{
+       int r;
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+       spin_lock_init(&dispc_compat.irq_stats_lock);
+       dispc_compat.irq_stats.last_reset = jiffies;
+       dss_debugfs_create_file("dispc_irq", dispc_dump_irqs);
+#endif
+
+       spin_lock_init(&dispc_compat.irq_lock);
+
+       memset(dispc_compat.registered_isr, 0,
+                       sizeof(dispc_compat.registered_isr));
+
+       dispc_compat.irq_error_mask = DISPC_IRQ_MASK_ERROR;
+       if (dss_has_feature(FEAT_MGR_LCD2))
+               dispc_compat.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
+       if (dss_has_feature(FEAT_MGR_LCD3))
+               dispc_compat.irq_error_mask |= DISPC_IRQ_SYNC_LOST3;
+       if (dss_feat_get_num_ovls() > 3)
+               dispc_compat.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
+
+       /*
+        * there's SYNC_LOST_DIGIT waiting after enabling the DSS,
+        * so clear it
+        */
+       dispc_clear_irqstatus(dispc_read_irqstatus());
+
+       INIT_WORK(&dispc_compat.error_work, dispc_error_worker);
+
+       _omap_dispc_set_irqs();
+
+       r = dispc_request_irq(omap_dispc_irq_handler, &dispc_compat);
+       if (r) {
+               DSSERR("dispc_request_irq failed\n");
+               return r;
+       }
+
+       return 0;
+}
+
+void dss_dispc_uninitialize_irq(void)
+{
+       dispc_free_irq(&dispc_compat);
+}
+
+static void dispc_mgr_disable_isr(void *data, u32 mask)
+{
+       struct completion *compl = data;
+       complete(compl);
+}
+
+static void dispc_mgr_enable_lcd_out(enum omap_channel channel)
+{
+       dispc_mgr_enable(channel, true);
+}
+
+static void dispc_mgr_disable_lcd_out(enum omap_channel channel)
+{
+       DECLARE_COMPLETION_ONSTACK(framedone_compl);
+       int r;
+       u32 irq;
+
+       if (dispc_mgr_is_enabled(channel) == false)
+               return;
+
+       /*
+        * When we disable LCD output, we need to wait for FRAMEDONE to know
+        * that DISPC has finished with the LCD output.
+        */
+
+       irq = dispc_mgr_get_framedone_irq(channel);
+
+       r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
+                       irq);
+       if (r)
+               DSSERR("failed to register FRAMEDONE isr\n");
+
+       dispc_mgr_enable(channel, false);
+
+       /* if we couldn't register for framedone, just sleep and exit */
+       if (r) {
+               msleep(100);
+               return;
+       }
+
+       if (!wait_for_completion_timeout(&framedone_compl,
+                               msecs_to_jiffies(100)))
+               DSSERR("timeout waiting for FRAME DONE\n");
+
+       r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
+                       irq);
+       if (r)
+               DSSERR("failed to unregister FRAMEDONE isr\n");
+}
+
+static void dispc_digit_out_enable_isr(void *data, u32 mask)
+{
+       struct completion *compl = data;
+
+       /* ignore any sync lost interrupts */
+       if (mask & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD))
+               complete(compl);
+}
+
+static void dispc_mgr_enable_digit_out(void)
+{
+       DECLARE_COMPLETION_ONSTACK(vsync_compl);
+       int r;
+       u32 irq_mask;
+
+       if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == true)
+               return;
+
+       /*
+        * Digit output produces some sync lost interrupts during the first
+        * frame when enabling. Those need to be ignored, so we register for the
+        * sync lost irq to prevent the error handler from triggering.
+        */
+
+       irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT) |
+               dispc_mgr_get_sync_lost_irq(OMAP_DSS_CHANNEL_DIGIT);
+
+       r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl,
+                       irq_mask);
+       if (r) {
+               DSSERR("failed to register %x isr\n", irq_mask);
+               return;
+       }
+
+       dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, true);
+
+       /* wait for the first evsync */
+       if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100)))
+               DSSERR("timeout waiting for digit out to start\n");
+
+       r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl,
+                       irq_mask);
+       if (r)
+               DSSERR("failed to unregister %x isr\n", irq_mask);
+}
+
+static void dispc_mgr_disable_digit_out(void)
+{
+       DECLARE_COMPLETION_ONSTACK(framedone_compl);
+       int r, i;
+       u32 irq_mask;
+       int num_irqs;
+
+       if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == false)
+               return;
+
+       /*
+        * When we disable the digit output, we need to wait for FRAMEDONE to
+        * know that DISPC has finished with the output.
+        */
+
+       irq_mask = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_DIGIT);
+       num_irqs = 1;
+
+       if (!irq_mask) {
+               /*
+                * omap 2/3 don't have framedone irq for TV, so we need to use
+                * vsyncs for this.
+                */
+
+               irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT);
+               /*
+                * We need to wait for both even and odd vsyncs. Note that this
+                * is not totally reliable, as we could get a vsync interrupt
+                * before we disable the output, which leads to timeout in the
+                * wait_for_completion.
+                */
+               num_irqs = 2;
+       }
+
+       r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
+                       irq_mask);
+       if (r)
+               DSSERR("failed to register %x isr\n", irq_mask);
+
+       dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, false);
+
+       /* if we couldn't register the irq, just sleep and exit */
+       if (r) {
+               msleep(100);
+               return;
+       }
+
+       for (i = 0; i < num_irqs; ++i) {
+               if (!wait_for_completion_timeout(&framedone_compl,
+                                       msecs_to_jiffies(100)))
+                       DSSERR("timeout waiting for digit out to stop\n");
+       }
+
+       r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
+                       irq_mask);
+       if (r)
+               DSSERR("failed to unregister %x isr\n", irq_mask);
+}
+
+void dispc_mgr_enable_sync(enum omap_channel channel)
+{
+       if (dss_mgr_is_lcd(channel))
+               dispc_mgr_enable_lcd_out(channel);
+       else if (channel == OMAP_DSS_CHANNEL_DIGIT)
+               dispc_mgr_enable_digit_out();
+       else
+               WARN_ON(1);
+}
+
+void dispc_mgr_disable_sync(enum omap_channel channel)
+{
+       if (dss_mgr_is_lcd(channel))
+               dispc_mgr_disable_lcd_out(channel);
+       else if (channel == OMAP_DSS_CHANNEL_DIGIT)
+               dispc_mgr_disable_digit_out();
+       else
+               WARN_ON(1);
+}
+
+int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
+               unsigned long timeout)
+{
+       void dispc_irq_wait_handler(void *data, u32 mask)
+       {
+               complete((struct completion *)data);
+       }
+
+       int r;
+       DECLARE_COMPLETION_ONSTACK(completion);
+
+       r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
+                       irqmask);
+
+       if (r)
+               return r;
+
+       timeout = wait_for_completion_interruptible_timeout(&completion,
+                       timeout);
+
+       omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
+
+       if (timeout == 0)
+               return -ETIMEDOUT;
+
+       if (timeout == -ERESTARTSYS)
+               return -ERESTARTSYS;
+
+       return 0;
+}
diff --git a/drivers/video/omap2/dss/dispc-compat.h b/drivers/video/omap2/dss/dispc-compat.h
new file mode 100644 (file)
index 0000000..14a69b3
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 Texas Instruments
+ * 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/>.
+ */
+
+#ifndef __OMAP2_DSS_DISPC_COMPAT_H
+#define __OMAP2_DSS_DISPC_COMPAT_H
+
+void dispc_mgr_enable_sync(enum omap_channel channel);
+void dispc_mgr_disable_sync(enum omap_channel channel);
+
+int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
+               unsigned long timeout);
+
+int dss_dispc_initialize_irq(void);
+void dss_dispc_uninitialize_irq(void);
+
+#endif
index b43477a5fae869e5e8981faaea48f51c15827e49..05ff2b91d9e8a49ee1e11c3c957b634eb4698393 100644 (file)
 #include <linux/delay.h>
 #include <linux/workqueue.h>
 #include <linux/hardirq.h>
-#include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-
-#include <plat/cpu.h>
+#include <linux/sizes.h>
 
 #include <video/omapdss.h>
 
 /* DISPC */
 #define DISPC_SZ_REGS                  SZ_4K
 
-#define DISPC_IRQ_MASK_ERROR            (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
-                                        DISPC_IRQ_OCP_ERR | \
-                                        DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
-                                        DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
-                                        DISPC_IRQ_SYNC_LOST | \
-                                        DISPC_IRQ_SYNC_LOST_DIGIT)
-
-#define DISPC_MAX_NR_ISRS              8
-
-struct omap_dispc_isr_data {
-       omap_dispc_isr_t        isr;
-       void                    *arg;
-       u32                     mask;
-};
-
 enum omap_burst_size {
        BURST_SIZE_X2 = 0,
        BURST_SIZE_X4 = 1,
@@ -75,12 +58,6 @@ enum omap_burst_size {
 #define REG_FLD_MOD(idx, val, start, end)                              \
        dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
 
-struct dispc_irq_stats {
-       unsigned long last_reset;
-       unsigned irq_count;
-       unsigned irqs[32];
-};
-
 struct dispc_features {
        u8 sw_start;
        u8 fp_start;
@@ -88,19 +65,26 @@ struct dispc_features {
        u16 sw_max;
        u16 vp_max;
        u16 hp_max;
-       int (*calc_scaling) (enum omap_plane plane,
+       u8 mgr_width_start;
+       u8 mgr_height_start;
+       u16 mgr_width_max;
+       u16 mgr_height_max;
+       int (*calc_scaling) (unsigned long pclk, unsigned long lclk,
                const struct omap_video_timings *mgr_timings,
                u16 width, u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode, bool *five_taps,
                int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
                u16 pos_x, unsigned long *core_clk, bool mem_to_mem);
-       unsigned long (*calc_core_clk) (enum omap_plane plane,
+       unsigned long (*calc_core_clk) (unsigned long pclk,
                u16 width, u16 height, u16 out_width, u16 out_height,
                bool mem_to_mem);
        u8 num_fifos;
 
        /* swap GFX & WB fifos */
        bool gfx_fifo_workaround:1;
+
+       /* no DISPC_IRQ_FRAMEDONETV on this SoC */
+       bool no_framedone_tv:1;
 };
 
 #define DISPC_MAX_NR_FIFOS 5
@@ -112,27 +96,15 @@ static struct {
        int             ctx_loss_cnt;
 
        int irq;
-       struct clk *dss_clk;
 
        u32 fifo_size[DISPC_MAX_NR_FIFOS];
        /* maps which plane is using a fifo. fifo-id -> plane-id */
        int fifo_assignment[DISPC_MAX_NR_FIFOS];
 
-       spinlock_t irq_lock;
-       u32 irq_error_mask;
-       struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
-       u32 error_irqs;
-       struct work_struct error_work;
-
        bool            ctx_valid;
        u32             ctx[DISPC_SZ_REGS / sizeof(u32)];
 
        const struct dispc_features *feat;
-
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-       spinlock_t irq_stats_lock;
-       struct dispc_irq_stats irq_stats;
-#endif
 } dispc;
 
 enum omap_color_component {
@@ -188,7 +160,7 @@ static const struct {
        [OMAP_DSS_CHANNEL_DIGIT] = {
                .name           = "DIGIT",
                .vsync_irq      = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN,
-               .framedone_irq  = 0,
+               .framedone_irq  = DISPC_IRQ_FRAMEDONETV,
                .sync_lost_irq  = DISPC_IRQ_SYNC_LOST_DIGIT,
                .reg_desc       = {
                        [DISPC_MGR_FLD_ENABLE]          = { DISPC_CONTROL,  1,  1 },
@@ -243,7 +215,6 @@ struct color_conv_coef {
        int full_range;
 };
 
-static void _omap_dispc_set_irqs(void);
 static unsigned long dispc_plane_pclk_rate(enum omap_plane plane);
 static unsigned long dispc_plane_lclk_rate(enum omap_plane plane);
 
@@ -376,7 +347,7 @@ static void dispc_save_context(void)
        if (dss_has_feature(FEAT_CORE_CLK_DIV))
                SR(DIVISOR);
 
-       dispc.ctx_loss_cnt = dss_get_ctx_loss_count(&dispc.pdev->dev);
+       dispc.ctx_loss_cnt = dss_get_ctx_loss_count();
        dispc.ctx_valid = true;
 
        DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt);
@@ -391,7 +362,7 @@ static void dispc_restore_context(void)
        if (!dispc.ctx_valid)
                return;
 
-       ctx = dss_get_ctx_loss_count(&dispc.pdev->dev);
+       ctx = dss_get_ctx_loss_count();
 
        if (ctx >= 0 && ctx == dispc.ctx_loss_cnt)
                return;
@@ -498,7 +469,7 @@ static void dispc_restore_context(void)
        if (dss_has_feature(FEAT_MGR_LCD3))
                RR(CONTROL3);
        /* clear spurious SYNC_LOST_DIGIT interrupts */
-       dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
+       dispc_clear_irqstatus(DISPC_IRQ_SYNC_LOST_DIGIT);
 
        /*
         * enable last so IRQs won't trigger before
@@ -522,6 +493,7 @@ int dispc_runtime_get(void)
        WARN_ON(r < 0);
        return r < 0 ? r : 0;
 }
+EXPORT_SYMBOL(dispc_runtime_get);
 
 void dispc_runtime_put(void)
 {
@@ -532,16 +504,28 @@ void dispc_runtime_put(void)
        r = pm_runtime_put_sync(&dispc.pdev->dev);
        WARN_ON(r < 0 && r != -ENOSYS);
 }
+EXPORT_SYMBOL(dispc_runtime_put);
 
 u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
 {
        return mgr_desc[channel].vsync_irq;
 }
+EXPORT_SYMBOL(dispc_mgr_get_vsync_irq);
 
 u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
 {
+       if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc.feat->no_framedone_tv)
+               return 0;
+
        return mgr_desc[channel].framedone_irq;
 }
+EXPORT_SYMBOL(dispc_mgr_get_framedone_irq);
+
+u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel)
+{
+       return mgr_desc[channel].sync_lost_irq;
+}
+EXPORT_SYMBOL(dispc_mgr_get_sync_lost_irq);
 
 u32 dispc_wb_get_framedone_irq(void)
 {
@@ -552,28 +536,18 @@ bool dispc_mgr_go_busy(enum omap_channel channel)
 {
        return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
 }
+EXPORT_SYMBOL(dispc_mgr_go_busy);
 
 void dispc_mgr_go(enum omap_channel channel)
 {
-       bool enable_bit, go_bit;
-
-       /* if the channel is not enabled, we don't need GO */
-       enable_bit = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE) == 1;
-
-       if (!enable_bit)
-               return;
-
-       go_bit = mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
-
-       if (go_bit) {
-               DSSERR("GO bit not down for channel %d\n", channel);
-               return;
-       }
+       WARN_ON(dispc_mgr_is_enabled(channel) == false);
+       WARN_ON(dispc_mgr_go_busy(channel));
 
        DSSDBG("GO %s\n", mgr_desc[channel].name);
 
        mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1);
 }
+EXPORT_SYMBOL(dispc_mgr_go);
 
 bool dispc_wb_go_busy(void)
 {
@@ -977,6 +951,7 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
        }
        dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
 }
+EXPORT_SYMBOL(dispc_ovl_set_channel_out);
 
 static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
 {
@@ -1042,7 +1017,7 @@ static void dispc_configure_burst_sizes(void)
        const int burst_size = BURST_SIZE_X8;
 
        /* Configure burst size always to maximum size */
-       for (i = 0; i < omap_dss_get_num_overlays(); ++i)
+       for (i = 0; i < dss_feat_get_num_ovls(); ++i)
                dispc_ovl_set_burst_size(i, burst_size);
 }
 
@@ -1076,7 +1051,7 @@ static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
 }
 
 static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
-               struct omap_dss_cpr_coefs *coefs)
+               const struct omap_dss_cpr_coefs *coefs)
 {
        u32 coef_r, coef_g, coef_b;
 
@@ -1124,7 +1099,9 @@ static void dispc_mgr_set_size(enum omap_channel channel, u16 width,
 {
        u32 val;
 
-       val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
+       val = FLD_VAL(height - 1, dispc.feat->mgr_height_start, 16) |
+               FLD_VAL(width - 1, dispc.feat->mgr_width_start, 0);
+
        dispc_write_reg(DISPC_SIZE_MGR(channel), val);
 }
 
@@ -1246,7 +1223,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
 
        if (use_fifomerge) {
                total_fifo_size = 0;
-               for (i = 0; i < omap_dss_get_num_overlays(); ++i)
+               for (i = 0; i < dss_feat_get_num_ovls(); ++i)
                        total_fifo_size += dispc_ovl_get_fifo_size(i);
        } else {
                total_fifo_size = ovl_fifo_size;
@@ -1991,16 +1968,14 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width,
  * This function is used to avoid synclosts in OMAP3, because of some
  * undocumented horizontal position and timing related limitations.
  */
-static int check_horiz_timing_omap3(enum omap_plane plane,
+static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk,
                const struct omap_video_timings *t, u16 pos_x,
                u16 width, u16 height, u16 out_width, u16 out_height)
 {
-       int DS = DIV_ROUND_UP(height, out_height);
+       const int ds = DIV_ROUND_UP(height, out_height);
        unsigned long nonactive;
        static const u8 limits[3] = { 8, 10, 20 };
        u64 val, blank;
-       unsigned long pclk = dispc_plane_pclk_rate(plane);
-       unsigned long lclk = dispc_plane_lclk_rate(plane);
        int i;
 
        nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
@@ -2022,8 +1997,8 @@ static int check_horiz_timing_omap3(enum omap_plane plane,
         */
        val = div_u64((u64)(nonactive - pos_x) * lclk, pclk);
        DSSDBG("(nonactive - pos_x) * pcd = %llu max(0, DS - 2) * width = %d\n",
-               val, max(0, DS - 2) * width);
-       if (val < max(0, DS - 2) * width)
+               val, max(0, ds - 2) * width);
+       if (val < max(0, ds - 2) * width)
                return -EINVAL;
 
        /*
@@ -2033,21 +2008,20 @@ static int check_horiz_timing_omap3(enum omap_plane plane,
         */
        val =  div_u64((u64)nonactive * lclk, pclk);
        DSSDBG("nonactive * pcd  = %llu, max(0, DS - 1) * width = %d\n",
-               val, max(0, DS - 1) * width);
-       if (val < max(0, DS - 1) * width)
+               val, max(0, ds - 1) * width);
+       if (val < max(0, ds - 1) * width)
                return -EINVAL;
 
        return 0;
 }
 
-static unsigned long calc_core_clk_five_taps(enum omap_plane plane,
+static unsigned long calc_core_clk_five_taps(unsigned long pclk,
                const struct omap_video_timings *mgr_timings, u16 width,
                u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode)
 {
        u32 core_clk = 0;
        u64 tmp;
-       unsigned long pclk = dispc_plane_pclk_rate(plane);
 
        if (height <= out_height && width <= out_width)
                return (unsigned long) pclk;
@@ -2081,22 +2055,19 @@ static unsigned long calc_core_clk_five_taps(enum omap_plane plane,
        return core_clk;
 }
 
-static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width,
+static unsigned long calc_core_clk_24xx(unsigned long pclk, u16 width,
                u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
 {
-       unsigned long pclk = dispc_plane_pclk_rate(plane);
-
        if (height > out_height && width > out_width)
                return pclk * 4;
        else
                return pclk * 2;
 }
 
-static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width,
+static unsigned long calc_core_clk_34xx(unsigned long pclk, u16 width,
                u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
 {
        unsigned int hf, vf;
-       unsigned long pclk = dispc_plane_pclk_rate(plane);
 
        /*
         * FIXME how to determine the 'A' factor
@@ -2119,11 +2090,9 @@ static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width,
        return pclk * vf * hf;
 }
 
-static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width,
+static unsigned long calc_core_clk_44xx(unsigned long pclk, u16 width,
                u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
 {
-       unsigned long pclk;
-
        /*
         * If the overlay/writeback is in mem to mem mode, there are no
         * downscaling limitations with respect to pixel clock, return 1 as
@@ -2133,15 +2102,13 @@ static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width,
        if (mem_to_mem)
                return 1;
 
-       pclk = dispc_plane_pclk_rate(plane);
-
        if (width > out_width)
                return DIV_ROUND_UP(pclk, out_width) * width;
        else
                return pclk;
 }
 
-static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
+static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk,
                const struct omap_video_timings *mgr_timings,
                u16 width, u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode, bool *five_taps,
@@ -2159,7 +2126,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
        do {
                in_height = DIV_ROUND_UP(height, *decim_y);
                in_width = DIV_ROUND_UP(width, *decim_x);
-               *core_clk = dispc.feat->calc_core_clk(plane, in_width,
+               *core_clk = dispc.feat->calc_core_clk(pclk, in_width,
                                in_height, out_width, out_height, mem_to_mem);
                error = (in_width > maxsinglelinewidth || !*core_clk ||
                        *core_clk > dispc_core_clk_rate());
@@ -2182,7 +2149,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
        return 0;
 }
 
-static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
+static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
                const struct omap_video_timings *mgr_timings,
                u16 width, u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode, bool *five_taps,
@@ -2198,10 +2165,10 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
        do {
                in_height = DIV_ROUND_UP(height, *decim_y);
                in_width = DIV_ROUND_UP(width, *decim_x);
-               *core_clk = calc_core_clk_five_taps(plane, mgr_timings,
+               *core_clk = calc_core_clk_five_taps(pclk, mgr_timings,
                        in_width, in_height, out_width, out_height, color_mode);
 
-               error = check_horiz_timing_omap3(plane, mgr_timings,
+               error = check_horiz_timing_omap3(pclk, lclk, mgr_timings,
                                pos_x, in_width, in_height, out_width,
                                out_height);
 
@@ -2210,7 +2177,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
                                                in_height < out_height * 2)
                                *five_taps = false;
                if (!*five_taps)
-                       *core_clk = dispc.feat->calc_core_clk(plane, in_width,
+                       *core_clk = dispc.feat->calc_core_clk(pclk, in_width,
                                        in_height, out_width, out_height,
                                        mem_to_mem);
 
@@ -2229,8 +2196,8 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
                }
        } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
 
-       if (check_horiz_timing_omap3(plane, mgr_timings, pos_x, width, height,
-               out_width, out_height)){
+       if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, width,
+                               height, out_width, out_height)){
                        DSSERR("horizontal timing too tight\n");
                        return -EINVAL;
        }
@@ -2248,7 +2215,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
        return 0;
 }
 
-static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
+static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,
                const struct omap_video_timings *mgr_timings,
                u16 width, u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode, bool *five_taps,
@@ -2260,14 +2227,14 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
        u16 in_height = DIV_ROUND_UP(height, *decim_y);
        const int maxsinglelinewidth =
                                dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
-       unsigned long pclk = dispc_plane_pclk_rate(plane);
        const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
 
-       if (mem_to_mem)
-               in_width_max = DIV_ROUND_UP(out_width, maxdownscale);
-       else
+       if (mem_to_mem) {
+               in_width_max = out_width * maxdownscale;
+       } else {
                in_width_max = dispc_core_clk_rate() /
                                        DIV_ROUND_UP(pclk, out_width);
+       }
 
        *decim_x = DIV_ROUND_UP(width, in_width_max);
 
@@ -2285,12 +2252,12 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
                return -EINVAL;
        }
 
-       *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height,
+       *core_clk = dispc.feat->calc_core_clk(pclk, in_width, in_height,
                                out_width, out_height, mem_to_mem);
        return 0;
 }
 
-static int dispc_ovl_calc_scaling(enum omap_plane plane,
+static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
                enum omap_overlay_caps caps,
                const struct omap_video_timings *mgr_timings,
                u16 width, u16 height, u16 out_width, u16 out_height,
@@ -2309,9 +2276,14 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
        if ((caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
                return -EINVAL;
 
-       *x_predecim = max_decim_limit;
-       *y_predecim = (rotation_type == OMAP_DSS_ROT_TILER &&
-                       dss_has_feature(FEAT_BURST_2D)) ? 2 : max_decim_limit;
+       if (mem_to_mem) {
+               *x_predecim = *y_predecim = 1;
+       } else {
+               *x_predecim = max_decim_limit;
+               *y_predecim = (rotation_type == OMAP_DSS_ROT_TILER &&
+                               dss_has_feature(FEAT_BURST_2D)) ?
+                               2 : max_decim_limit;
+       }
 
        if (color_mode == OMAP_DSS_COLOR_CLUT1 ||
            color_mode == OMAP_DSS_COLOR_CLUT2 ||
@@ -2332,7 +2304,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
        if (decim_y > *y_predecim || out_height > height * 8)
                return -EINVAL;
 
-       ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height,
+       ret = dispc.feat->calc_scaling(pclk, lclk, mgr_timings, width, height,
                out_width, out_height, color_mode, five_taps,
                x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk,
                mem_to_mem);
@@ -2355,6 +2327,47 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
        return 0;
 }
 
+int dispc_ovl_check(enum omap_plane plane, enum omap_channel channel,
+               const struct omap_overlay_info *oi,
+               const struct omap_video_timings *timings,
+               int *x_predecim, int *y_predecim)
+{
+       enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
+       bool five_taps = true;
+       bool fieldmode = 0;
+       u16 in_height = oi->height;
+       u16 in_width = oi->width;
+       bool ilace = timings->interlace;
+       u16 out_width, out_height;
+       int pos_x = oi->pos_x;
+       unsigned long pclk = dispc_mgr_pclk_rate(channel);
+       unsigned long lclk = dispc_mgr_lclk_rate(channel);
+
+       out_width = oi->out_width == 0 ? oi->width : oi->out_width;
+       out_height = oi->out_height == 0 ? oi->height : oi->out_height;
+
+       if (ilace && oi->height == out_height)
+               fieldmode = 1;
+
+       if (ilace) {
+               if (fieldmode)
+                       in_height /= 2;
+               out_height /= 2;
+
+               DSSDBG("adjusting for ilace: height %d, out_height %d\n",
+                               in_height, out_height);
+       }
+
+       if (!dss_feat_color_mode_supported(plane, oi->color_mode))
+               return -EINVAL;
+
+       return dispc_ovl_calc_scaling(pclk, lclk, caps, timings, in_width,
+                       in_height, out_width, out_height, oi->color_mode,
+                       &five_taps, x_predecim, y_predecim, pos_x,
+                       oi->rotation_type, false);
+}
+EXPORT_SYMBOL(dispc_ovl_check);
+
 static int dispc_ovl_setup_common(enum omap_plane plane,
                enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr,
                u16 screen_width, int pos_x, int pos_y, u16 width, u16 height,
@@ -2370,12 +2383,14 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
        unsigned offset0, offset1;
        s32 row_inc;
        s32 pix_inc;
-       u16 frame_height = height;
+       u16 frame_width, frame_height;
        unsigned int field_offset = 0;
        u16 in_height = height;
        u16 in_width = width;
        int x_predecim = 1, y_predecim = 1;
        bool ilace = mgr_timings->interlace;
+       unsigned long pclk = dispc_plane_pclk_rate(plane);
+       unsigned long lclk = dispc_plane_lclk_rate(plane);
 
        if (paddr == 0)
                return -EINVAL;
@@ -2400,7 +2415,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
        if (!dss_feat_color_mode_supported(plane, color_mode))
                return -EINVAL;
 
-       r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width,
+       r = dispc_ovl_calc_scaling(pclk, lclk, caps, mgr_timings, in_width,
                        in_height, out_width, out_height, color_mode,
                        &five_taps, &x_predecim, &y_predecim, pos_x,
                        rotation_type, mem_to_mem);
@@ -2438,20 +2453,28 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
        row_inc = 0;
        pix_inc = 0;
 
+       if (plane == OMAP_DSS_WB) {
+               frame_width = out_width;
+               frame_height = out_height;
+       } else {
+               frame_width = in_width;
+               frame_height = height;
+       }
+
        if (rotation_type == OMAP_DSS_ROT_TILER)
-               calc_tiler_rotation_offset(screen_width, in_width,
+               calc_tiler_rotation_offset(screen_width, frame_width,
                                color_mode, fieldmode, field_offset,
                                &offset0, &offset1, &row_inc, &pix_inc,
                                x_predecim, y_predecim);
        else if (rotation_type == OMAP_DSS_ROT_DMA)
-               calc_dma_rotation_offset(rotation, mirror,
-                               screen_width, in_width, frame_height,
+               calc_dma_rotation_offset(rotation, mirror, screen_width,
+                               frame_width, frame_height,
                                color_mode, fieldmode, field_offset,
                                &offset0, &offset1, &row_inc, &pix_inc,
                                x_predecim, y_predecim);
        else
                calc_vrfb_rotation_offset(rotation, mirror,
-                               screen_width, in_width, frame_height,
+                               screen_width, frame_width, frame_height,
                                color_mode, fieldmode, field_offset,
                                &offset0, &offset1, &row_inc, &pix_inc,
                                x_predecim, y_predecim);
@@ -2505,7 +2528,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
                bool mem_to_mem)
 {
        int r;
-       struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+       enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
        enum omap_channel channel;
 
        channel = dispc_ovl_get_channel_out(plane);
@@ -2516,7 +2539,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
                oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,
                oi->color_mode, oi->rotation, oi->mirror, channel, replication);
 
-       r = dispc_ovl_setup_common(plane, ovl->caps, oi->paddr, oi->p_uv_addr,
+       r = dispc_ovl_setup_common(plane, caps, 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, oi->zorder, oi->pre_mult_alpha, oi->global_alpha,
@@ -2524,6 +2547,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
 
        return r;
 }
+EXPORT_SYMBOL(dispc_ovl_setup);
 
 int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
                bool mem_to_mem, const struct omap_video_timings *mgr_timings)
@@ -2584,192 +2608,39 @@ int dispc_ovl_enable(enum omap_plane plane, bool enable)
 
        return 0;
 }
+EXPORT_SYMBOL(dispc_ovl_enable);
 
-static void dispc_disable_isr(void *data, u32 mask)
+bool dispc_ovl_enabled(enum omap_plane plane)
 {
-       struct completion *compl = data;
-       complete(compl);
+       return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
 }
+EXPORT_SYMBOL(dispc_ovl_enabled);
 
-static void _enable_lcd_out(enum omap_channel channel, bool enable)
+void dispc_mgr_enable(enum omap_channel channel, bool enable)
 {
        mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable);
        /* flush posted write */
        mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
 }
-
-static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
-{
-       struct completion frame_done_completion;
-       bool is_on;
-       int r;
-       u32 irq;
-
-       /* When we disable LCD output, we need to wait until frame is done.
-        * Otherwise the DSS is still working, and turning off the clocks
-        * prevents DSS from going to OFF mode */
-       is_on = mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
-
-       irq = mgr_desc[channel].framedone_irq;
-
-       if (!enable && is_on) {
-               init_completion(&frame_done_completion);
-
-               r = omap_dispc_register_isr(dispc_disable_isr,
-                               &frame_done_completion, irq);
-
-               if (r)
-                       DSSERR("failed to register FRAMEDONE isr\n");
-       }
-
-       _enable_lcd_out(channel, enable);
-
-       if (!enable && is_on) {
-               if (!wait_for_completion_timeout(&frame_done_completion,
-                                       msecs_to_jiffies(100)))
-                       DSSERR("timeout waiting for FRAME DONE\n");
-
-               r = omap_dispc_unregister_isr(dispc_disable_isr,
-                               &frame_done_completion, irq);
-
-               if (r)
-                       DSSERR("failed to unregister FRAMEDONE isr\n");
-       }
-}
-
-static void _enable_digit_out(bool enable)
-{
-       REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
-       /* flush posted write */
-       dispc_read_reg(DISPC_CONTROL);
-}
-
-static void dispc_mgr_enable_digit_out(bool enable)
-{
-       struct completion frame_done_completion;
-       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
-                * sync lost interrupt, that we need to ignore */
-               spin_lock_irqsave(&dispc.irq_lock, flags);
-               dispc.irq_error_mask &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
-               _omap_dispc_set_irqs();
-               spin_unlock_irqrestore(&dispc.irq_lock, flags);
-       }
-
-       /* When we disable digit output, we need to wait until fields are done.
-        * Otherwise the DSS is still working, and turning off the clocks
-        * prevents DSS from going to OFF mode. And when enabling, we need to
-        * 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,
-                       irq_mask);
-       if (r)
-               DSSERR("failed to register %x isr\n", irq_mask);
-
-       _enable_digit_out(enable);
-
-       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,
-                       irq_mask);
-       if (r)
-               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_SYNC_LOST_DIGIT;
-               dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
-               _omap_dispc_set_irqs();
-               spin_unlock_irqrestore(&dispc.irq_lock, flags);
-       }
-}
+EXPORT_SYMBOL(dispc_mgr_enable);
 
 bool dispc_mgr_is_enabled(enum omap_channel channel)
 {
        return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
 }
-
-void dispc_mgr_enable(enum omap_channel channel, bool enable)
-{
-       if (dss_mgr_is_lcd(channel))
-               dispc_mgr_enable_lcd_out(channel, enable);
-       else if (channel == OMAP_DSS_CHANNEL_DIGIT)
-               dispc_mgr_enable_digit_out(enable);
-       else
-               BUG();
-}
+EXPORT_SYMBOL(dispc_mgr_is_enabled);
 
 void dispc_wb_enable(bool enable)
 {
-       enum omap_plane plane = OMAP_DSS_WB;
-       struct completion frame_done_completion;
-       bool is_on;
-       int r;
-       u32 irq;
-
-       is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
-       irq = DISPC_IRQ_FRAMEDONEWB;
-
-       if (!enable && is_on) {
-               init_completion(&frame_done_completion);
-
-               r = omap_dispc_register_isr(dispc_disable_isr,
-                               &frame_done_completion, irq);
-               if (r)
-                       DSSERR("failed to register FRAMEDONEWB isr\n");
-       }
-
-       REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0);
-
-       if (!enable && is_on) {
-               if (!wait_for_completion_timeout(&frame_done_completion,
-                                       msecs_to_jiffies(100)))
-                       DSSERR("timeout waiting for FRAMEDONEWB\n");
-
-               r = omap_dispc_unregister_isr(dispc_disable_isr,
-                               &frame_done_completion, irq);
-               if (r)
-                       DSSERR("failed to unregister FRAMEDONEWB isr\n");
-       }
+       dispc_ovl_enable(OMAP_DSS_WB, enable);
 }
 
 bool dispc_wb_is_enabled(void)
 {
-       enum omap_plane plane = OMAP_DSS_WB;
-
-       return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
+       return dispc_ovl_enabled(OMAP_DSS_WB);
 }
 
-void dispc_lcd_enable_signal_polarity(bool act_high)
+static void dispc_lcd_enable_signal_polarity(bool act_high)
 {
        if (!dss_has_feature(FEAT_LCDENABLEPOL))
                return;
@@ -2793,13 +2664,13 @@ void dispc_pck_free_enable(bool enable)
        REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
 }
 
-void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
+static void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
 {
        mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable);
 }
 
 
-void dispc_mgr_set_lcd_type_tft(enum omap_channel channel)
+static void dispc_mgr_set_lcd_type_tft(enum omap_channel channel)
 {
        mgr_fld_write(channel, DISPC_MGR_FLD_STNTFT, 1);
 }
@@ -2842,7 +2713,7 @@ static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
 }
 
 void dispc_mgr_setup(enum omap_channel channel,
-               struct omap_overlay_manager_info *info)
+               const struct omap_overlay_manager_info *info)
 {
        dispc_mgr_set_default_color(channel, info->default_color);
        dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key);
@@ -2854,8 +2725,9 @@ void dispc_mgr_setup(enum omap_channel channel,
                dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs);
        }
 }
+EXPORT_SYMBOL(dispc_mgr_setup);
 
-void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
+static void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
 {
        int code;
 
@@ -2880,7 +2752,7 @@ void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
        mgr_fld_write(channel, DISPC_MGR_FLD_TFTDATALINES, code);
 }
 
-void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
+static void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
 {
        u32 l;
        int gpout0, gpout1;
@@ -2909,15 +2781,33 @@ void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
        dispc_write_reg(DISPC_CONTROL, l);
 }
 
-void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
+static void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
 {
        mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable);
 }
 
+void dispc_mgr_set_lcd_config(enum omap_channel channel,
+               const struct dss_lcd_mgr_config *config)
+{
+       dispc_mgr_set_io_pad_mode(config->io_pad_mode);
+
+       dispc_mgr_enable_stallmode(channel, config->stallmode);
+       dispc_mgr_enable_fifohandcheck(channel, config->fifohandcheck);
+
+       dispc_mgr_set_clock_div(channel, &config->clock_info);
+
+       dispc_mgr_set_tft_data_lines(channel, config->video_port_width);
+
+       dispc_lcd_enable_signal_polarity(config->lcden_sig_polarity);
+
+       dispc_mgr_set_lcd_type_tft(channel);
+}
+EXPORT_SYMBOL(dispc_mgr_set_lcd_config);
+
 static bool _dispc_mgr_size_ok(u16 width, u16 height)
 {
-       return width <= dss_feat_get_param_max(FEAT_PARAM_MGR_WIDTH) &&
-               height <= dss_feat_get_param_max(FEAT_PARAM_MGR_HEIGHT);
+       return width <= dispc.feat->mgr_width_max &&
+               height <= dispc.feat->mgr_height_max;
 }
 
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
@@ -3012,7 +2902,7 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 
 /* change name to mode? */
 void dispc_mgr_set_timings(enum omap_channel channel,
-               struct omap_video_timings *timings)
+               const struct omap_video_timings *timings)
 {
        unsigned xtot, ytot;
        unsigned long ht, vt;
@@ -3051,6 +2941,7 @@ void dispc_mgr_set_timings(enum omap_channel channel,
 
        dispc_mgr_set_size(channel, t.x_res, t.y_res);
 }
+EXPORT_SYMBOL(dispc_mgr_set_timings);
 
 static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
                u16 pck_div)
@@ -3078,7 +2969,7 @@ unsigned long dispc_fclk_rate(void)
 
        switch (dss_get_dispc_clk_source()) {
        case OMAP_DSS_CLK_SRC_FCK:
-               r = clk_get_rate(dispc.dss_clk);
+               r = dss_get_dispc_clk_rate();
                break;
        case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
                dsidev = dsi_get_dsidev_from_id(0);
@@ -3103,28 +2994,32 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
        unsigned long r;
        u32 l;
 
-       l = dispc_read_reg(DISPC_DIVISORo(channel));
+       if (dss_mgr_is_lcd(channel)) {
+               l = dispc_read_reg(DISPC_DIVISORo(channel));
 
-       lcd = FLD_GET(l, 23, 16);
+               lcd = FLD_GET(l, 23, 16);
 
-       switch (dss_get_lcd_clk_source(channel)) {
-       case OMAP_DSS_CLK_SRC_FCK:
-               r = clk_get_rate(dispc.dss_clk);
-               break;
-       case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
-               dsidev = dsi_get_dsidev_from_id(0);
-               r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
-               break;
-       case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
-               dsidev = dsi_get_dsidev_from_id(1);
-               r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
-               break;
-       default:
-               BUG();
-               return 0;
-       }
+               switch (dss_get_lcd_clk_source(channel)) {
+               case OMAP_DSS_CLK_SRC_FCK:
+                       r = dss_get_dispc_clk_rate();
+                       break;
+               case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
+                       dsidev = dsi_get_dsidev_from_id(0);
+                       r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
+                       break;
+               case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
+                       dsidev = dsi_get_dsidev_from_id(1);
+                       r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
+                       break;
+               default:
+                       BUG();
+                       return 0;
+               }
 
-       return r / lcd;
+               return r / lcd;
+       } else {
+               return dispc_fclk_rate();
+       }
 }
 
 unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
@@ -3174,21 +3069,28 @@ unsigned long dispc_core_clk_rate(void)
 
 static unsigned long dispc_plane_pclk_rate(enum omap_plane plane)
 {
-       enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+       enum omap_channel channel;
+
+       if (plane == OMAP_DSS_WB)
+               return 0;
+
+       channel = dispc_ovl_get_channel_out(plane);
 
        return dispc_mgr_pclk_rate(channel);
 }
 
 static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
 {
-       enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+       enum omap_channel channel;
 
-       if (dss_mgr_is_lcd(channel))
-               return dispc_mgr_lclk_rate(channel);
-       else
-               return dispc_fclk_rate();
+       if (plane == OMAP_DSS_WB)
+               return 0;
+
+       channel = dispc_ovl_get_channel_out(plane);
 
+       return dispc_mgr_lclk_rate(channel);
 }
+
 static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
 {
        int lcd, pcd;
@@ -3246,64 +3148,6 @@ void dispc_dump_clocks(struct seq_file *s)
        dispc_runtime_put();
 }
 
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-void dispc_dump_irqs(struct seq_file *s)
-{
-       unsigned long flags;
-       struct dispc_irq_stats stats;
-
-       spin_lock_irqsave(&dispc.irq_stats_lock, flags);
-
-       stats = dispc.irq_stats;
-       memset(&dispc.irq_stats, 0, sizeof(dispc.irq_stats));
-       dispc.irq_stats.last_reset = jiffies;
-
-       spin_unlock_irqrestore(&dispc.irq_stats_lock, flags);
-
-       seq_printf(s, "period %u ms\n",
-                       jiffies_to_msecs(jiffies - stats.last_reset));
-
-       seq_printf(s, "irqs %d\n", stats.irq_count);
-#define PIS(x) \
-       seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]);
-
-       PIS(FRAMEDONE);
-       PIS(VSYNC);
-       PIS(EVSYNC_EVEN);
-       PIS(EVSYNC_ODD);
-       PIS(ACBIAS_COUNT_STAT);
-       PIS(PROG_LINE_NUM);
-       PIS(GFX_FIFO_UNDERFLOW);
-       PIS(GFX_END_WIN);
-       PIS(PAL_GAMMA_MASK);
-       PIS(OCP_ERR);
-       PIS(VID1_FIFO_UNDERFLOW);
-       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);
-       if (dss_has_feature(FEAT_MGR_LCD2)) {
-               PIS(FRAMEDONE2);
-               PIS(VSYNC2);
-               PIS(ACBIAS_COUNT_STAT2);
-               PIS(SYNC_LOST2);
-       }
-       if (dss_has_feature(FEAT_MGR_LCD3)) {
-               PIS(FRAMEDONE3);
-               PIS(VSYNC3);
-               PIS(ACBIAS_COUNT_STAT3);
-               PIS(SYNC_LOST3);
-       }
-#undef PIS
-}
-#endif
-
 static void dispc_dump_regs(struct seq_file *s)
 {
        int i, j;
@@ -3353,7 +3197,7 @@ static void dispc_dump_regs(struct seq_file *s)
 
 #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]), " ", \
+       (int)(48 - strlen(#r) - strlen(p_names[i])), " ", \
        dispc_read_reg(DISPC_REG(i, r)))
 
        p_names = mgr_names;
@@ -3430,7 +3274,7 @@ static void dispc_dump_regs(struct seq_file *s)
 #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]), " ", \
+       (int)(46 - strlen(#name) - strlen(p_names[plane])), " ", \
        dispc_read_reg(DISPC_REG(plane, name, i)))
 
        /* Video pipeline coefficient registers */
@@ -3533,7 +3377,7 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
 }
 
 void dispc_mgr_set_clock_div(enum omap_channel channel,
-               struct dispc_clock_info *cinfo)
+               const 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);
@@ -3557,403 +3401,34 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
        return 0;
 }
 
-/* dispc.irq_lock has to be locked by the caller */
-static void _omap_dispc_set_irqs(void)
+u32 dispc_read_irqstatus(void)
 {
-       u32 mask;
-       u32 old_mask;
-       int i;
-       struct omap_dispc_isr_data *isr_data;
-
-       mask = dispc.irq_error_mask;
-
-       for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
-               isr_data = &dispc.registered_isr[i];
-
-               if (isr_data->isr == NULL)
-                       continue;
-
-               mask |= isr_data->mask;
-       }
-
-       old_mask = dispc_read_reg(DISPC_IRQENABLE);
-       /* clear the irqstatus for newly enabled irqs */
-       dispc_write_reg(DISPC_IRQSTATUS, (mask ^ old_mask) & mask);
-
-       dispc_write_reg(DISPC_IRQENABLE, mask);
-}
-
-int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
-{
-       int i;
-       int ret;
-       unsigned long flags;
-       struct omap_dispc_isr_data *isr_data;
-
-       if (isr == NULL)
-               return -EINVAL;
-
-       spin_lock_irqsave(&dispc.irq_lock, flags);
-
-       /* check for duplicate entry */
-       for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
-               isr_data = &dispc.registered_isr[i];
-               if (isr_data->isr == isr && isr_data->arg == arg &&
-                               isr_data->mask == mask) {
-                       ret = -EINVAL;
-                       goto err;
-               }
-       }
-
-       isr_data = NULL;
-       ret = -EBUSY;
-
-       for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
-               isr_data = &dispc.registered_isr[i];
-
-               if (isr_data->isr != NULL)
-                       continue;
-
-               isr_data->isr = isr;
-               isr_data->arg = arg;
-               isr_data->mask = mask;
-               ret = 0;
-
-               break;
-       }
-
-       if (ret)
-               goto err;
-
-       _omap_dispc_set_irqs();
-
-       spin_unlock_irqrestore(&dispc.irq_lock, flags);
-
-       return 0;
-err:
-       spin_unlock_irqrestore(&dispc.irq_lock, flags);
-
-       return ret;
+       return dispc_read_reg(DISPC_IRQSTATUS);
 }
-EXPORT_SYMBOL(omap_dispc_register_isr);
+EXPORT_SYMBOL(dispc_read_irqstatus);
 
-int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+void dispc_clear_irqstatus(u32 mask)
 {
-       int i;
-       unsigned long flags;
-       int ret = -EINVAL;
-       struct omap_dispc_isr_data *isr_data;
-
-       spin_lock_irqsave(&dispc.irq_lock, flags);
-
-       for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
-               isr_data = &dispc.registered_isr[i];
-               if (isr_data->isr != isr || isr_data->arg != arg ||
-                               isr_data->mask != mask)
-                       continue;
-
-               /* found the correct isr */
-
-               isr_data->isr = NULL;
-               isr_data->arg = NULL;
-               isr_data->mask = 0;
-
-               ret = 0;
-               break;
-       }
-
-       if (ret == 0)
-               _omap_dispc_set_irqs();
-
-       spin_unlock_irqrestore(&dispc.irq_lock, flags);
-
-       return ret;
+       dispc_write_reg(DISPC_IRQSTATUS, mask);
 }
-EXPORT_SYMBOL(omap_dispc_unregister_isr);
+EXPORT_SYMBOL(dispc_clear_irqstatus);
 
-#ifdef DEBUG
-static void print_irq_status(u32 status)
+u32 dispc_read_irqenable(void)
 {
-       if ((status & dispc.irq_error_mask) == 0)
-               return;
-
-       printk(KERN_DEBUG "DISPC IRQ: 0x%x: ", status);
-
-#define PIS(x) \
-       if (status & DISPC_IRQ_##x) \
-               printk(#x " ");
-       PIS(GFX_FIFO_UNDERFLOW);
-       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))
-               PIS(SYNC_LOST2);
-       if (dss_has_feature(FEAT_MGR_LCD3))
-               PIS(SYNC_LOST3);
-#undef PIS
-
-       printk("\n");
+       return dispc_read_reg(DISPC_IRQENABLE);
 }
-#endif
+EXPORT_SYMBOL(dispc_read_irqenable);
 
-/* Called from dss.c. Note that we don't touch clocks here,
- * but we presume they are on because we got an IRQ. However,
- * an irq handler may turn the clocks off, so we may not have
- * clock later in the function. */
-static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
+void dispc_write_irqenable(u32 mask)
 {
-       int i;
-       u32 irqstatus, irqenable;
-       u32 handledirqs = 0;
-       u32 unhandled_errors;
-       struct omap_dispc_isr_data *isr_data;
-       struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
-
-       spin_lock(&dispc.irq_lock);
-
-       irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
-       irqenable = dispc_read_reg(DISPC_IRQENABLE);
-
-       /* IRQ is not for us */
-       if (!(irqstatus & irqenable)) {
-               spin_unlock(&dispc.irq_lock);
-               return IRQ_NONE;
-       }
-
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-       spin_lock(&dispc.irq_stats_lock);
-       dispc.irq_stats.irq_count++;
-       dss_collect_irq_stats(irqstatus, dispc.irq_stats.irqs);
-       spin_unlock(&dispc.irq_stats_lock);
-#endif
-
-#ifdef DEBUG
-       if (dss_debug)
-               print_irq_status(irqstatus);
-#endif
-       /* Ack the interrupt. Do it here before clocks are possibly turned
-        * off */
-       dispc_write_reg(DISPC_IRQSTATUS, irqstatus);
-       /* flush posted write */
-       dispc_read_reg(DISPC_IRQSTATUS);
-
-       /* make a copy and unlock, so that isrs can unregister
-        * themselves */
-       memcpy(registered_isr, dispc.registered_isr,
-                       sizeof(registered_isr));
-
-       spin_unlock(&dispc.irq_lock);
-
-       for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
-               isr_data = &registered_isr[i];
-
-               if (!isr_data->isr)
-                       continue;
-
-               if (isr_data->mask & irqstatus) {
-                       isr_data->isr(isr_data->arg, irqstatus);
-                       handledirqs |= isr_data->mask;
-               }
-       }
-
-       spin_lock(&dispc.irq_lock);
-
-       unhandled_errors = irqstatus & ~handledirqs & dispc.irq_error_mask;
-
-       if (unhandled_errors) {
-               dispc.error_irqs |= unhandled_errors;
-
-               dispc.irq_error_mask &= ~unhandled_errors;
-               _omap_dispc_set_irqs();
-
-               schedule_work(&dispc.error_work);
-       }
-
-       spin_unlock(&dispc.irq_lock);
-
-       return IRQ_HANDLED;
-}
-
-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,
-       };
-
-       spin_lock_irqsave(&dispc.irq_lock, flags);
-       errors = dispc.error_irqs;
-       dispc.error_irqs = 0;
-       spin_unlock_irqrestore(&dispc.irq_lock, flags);
-
-       dispc_runtime_get();
-
-       for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
-               struct omap_overlay *ovl;
-               unsigned bit;
-
-               ovl = omap_dss_get_overlay(i);
-               bit = fifo_underflow_bits[i];
-
-               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);
-                       msleep(50);
-               }
-       }
-
-       for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
-               struct omap_overlay_manager *mgr;
-               unsigned bit;
-
-               mgr = omap_dss_get_overlay_manager(i);
-               bit = mgr_desc[i].sync_lost_irq;
-
-               if (bit & errors) {
-                       struct omap_dss_device *dssdev = mgr->get_device(mgr);
-                       bool enable;
-
-                       DSSERR("SYNC_LOST on channel %s, restarting the output "
-                                       "with video overlays disabled\n",
-                                       mgr->name);
-
-                       enable = dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
-                       dssdev->driver->disable(dssdev);
-
-                       for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
-                               struct omap_overlay *ovl;
-                               ovl = omap_dss_get_overlay(i);
-
-                               if (ovl->id != OMAP_DSS_GFX &&
-                                               ovl->manager == mgr)
-                                       dispc_ovl_enable(ovl->id, false);
-                       }
-
-                       dispc_mgr_go(mgr->id);
-                       msleep(50);
-
-                       if (enable)
-                               dssdev->driver->enable(dssdev);
-               }
-       }
-
-       if (errors & DISPC_IRQ_OCP_ERR) {
-               DSSERR("OCP_ERR\n");
-               for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
-                       struct omap_overlay_manager *mgr;
-                       struct omap_dss_device *dssdev;
+       u32 old_mask = dispc_read_reg(DISPC_IRQENABLE);
 
-                       mgr = omap_dss_get_overlay_manager(i);
-                       dssdev = mgr->get_device(mgr);
-
-                       if (dssdev && dssdev->driver)
-                               dssdev->driver->disable(dssdev);
-               }
-       }
-
-       spin_lock_irqsave(&dispc.irq_lock, flags);
-       dispc.irq_error_mask |= errors;
-       _omap_dispc_set_irqs();
-       spin_unlock_irqrestore(&dispc.irq_lock, flags);
-
-       dispc_runtime_put();
-}
-
-int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout)
-{
-       void dispc_irq_wait_handler(void *data, u32 mask)
-       {
-               complete((struct completion *)data);
-       }
-
-       int r;
-       DECLARE_COMPLETION_ONSTACK(completion);
-
-       r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
-                       irqmask);
-
-       if (r)
-               return r;
-
-       timeout = wait_for_completion_timeout(&completion, timeout);
-
-       omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
-
-       if (timeout == 0)
-               return -ETIMEDOUT;
-
-       if (timeout == -ERESTARTSYS)
-               return -ERESTARTSYS;
-
-       return 0;
-}
-
-int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
-               unsigned long timeout)
-{
-       void dispc_irq_wait_handler(void *data, u32 mask)
-       {
-               complete((struct completion *)data);
-       }
-
-       int r;
-       DECLARE_COMPLETION_ONSTACK(completion);
-
-       r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
-                       irqmask);
-
-       if (r)
-               return r;
-
-       timeout = wait_for_completion_interruptible_timeout(&completion,
-                       timeout);
-
-       omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
-
-       if (timeout == 0)
-               return -ETIMEDOUT;
-
-       if (timeout == -ERESTARTSYS)
-               return -ERESTARTSYS;
-
-       return 0;
-}
-
-static void _omap_dispc_initialize_irq(void)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&dispc.irq_lock, flags);
-
-       memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr));
-
-       dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
-       if (dss_has_feature(FEAT_MGR_LCD2))
-               dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
-       if (dss_has_feature(FEAT_MGR_LCD3))
-               dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST3;
-       if (dss_feat_get_num_ovls() > 3)
-               dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
-
-       /* there's SYNC_LOST_DIGIT waiting after enabling the DSS,
-        * so clear it */
-       dispc_write_reg(DISPC_IRQSTATUS, dispc_read_reg(DISPC_IRQSTATUS));
-
-       _omap_dispc_set_irqs();
+       /* clear the irqstatus for newly enabled irqs */
+       dispc_clear_irqstatus((mask ^ old_mask) & mask);
 
-       spin_unlock_irqrestore(&dispc.irq_lock, flags);
+       dispc_write_reg(DISPC_IRQENABLE, mask);
 }
+EXPORT_SYMBOL(dispc_write_irqenable);
 
 void dispc_enable_sidle(void)
 {
@@ -4000,9 +3475,14 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
        .sw_max                 =       64,
        .vp_max                 =       255,
        .hp_max                 =       256,
+       .mgr_width_start        =       10,
+       .mgr_height_start       =       26,
+       .mgr_width_max          =       2048,
+       .mgr_height_max         =       2048,
        .calc_scaling           =       dispc_ovl_calc_scaling_24xx,
        .calc_core_clk          =       calc_core_clk_24xx,
        .num_fifos              =       3,
+       .no_framedone_tv        =       true,
 };
 
 static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
@@ -4012,9 +3492,14 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
        .sw_max                 =       64,
        .vp_max                 =       255,
        .hp_max                 =       256,
+       .mgr_width_start        =       10,
+       .mgr_height_start       =       26,
+       .mgr_width_max          =       2048,
+       .mgr_height_max         =       2048,
        .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
        .calc_core_clk          =       calc_core_clk_34xx,
        .num_fifos              =       3,
+       .no_framedone_tv        =       true,
 };
 
 static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
@@ -4024,9 +3509,14 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
        .sw_max                 =       256,
        .vp_max                 =       4095,
        .hp_max                 =       4096,
+       .mgr_width_start        =       10,
+       .mgr_height_start       =       26,
+       .mgr_width_max          =       2048,
+       .mgr_height_max         =       2048,
        .calc_scaling           =       dispc_ovl_calc_scaling_34xx,
        .calc_core_clk          =       calc_core_clk_34xx,
        .num_fifos              =       3,
+       .no_framedone_tv        =       true,
 };
 
 static const struct dispc_features omap44xx_dispc_feats __initconst = {
@@ -4036,35 +3526,70 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
        .sw_max                 =       256,
        .vp_max                 =       4095,
        .hp_max                 =       4096,
+       .mgr_width_start        =       10,
+       .mgr_height_start       =       26,
+       .mgr_width_max          =       2048,
+       .mgr_height_max         =       2048,
+       .calc_scaling           =       dispc_ovl_calc_scaling_44xx,
+       .calc_core_clk          =       calc_core_clk_44xx,
+       .num_fifos              =       5,
+       .gfx_fifo_workaround    =       true,
+};
+
+static const struct dispc_features omap54xx_dispc_feats __initconst = {
+       .sw_start               =       7,
+       .fp_start               =       19,
+       .bp_start               =       31,
+       .sw_max                 =       256,
+       .vp_max                 =       4095,
+       .hp_max                 =       4096,
+       .mgr_width_start        =       11,
+       .mgr_height_start       =       27,
+       .mgr_width_max          =       4096,
+       .mgr_height_max         =       4096,
        .calc_scaling           =       dispc_ovl_calc_scaling_44xx,
        .calc_core_clk          =       calc_core_clk_44xx,
        .num_fifos              =       5,
        .gfx_fifo_workaround    =       true,
 };
 
-static int __init dispc_init_features(struct device *dev)
+static int __init dispc_init_features(struct platform_device *pdev)
 {
        const struct dispc_features *src;
        struct dispc_features *dst;
 
-       dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+       dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
        if (!dst) {
-               dev_err(dev, "Failed to allocate DISPC Features\n");
+               dev_err(&pdev->dev, "Failed to allocate DISPC Features\n");
                return -ENOMEM;
        }
 
-       if (cpu_is_omap24xx()) {
+       switch (omapdss_get_version()) {
+       case OMAPDSS_VER_OMAP24xx:
                src = &omap24xx_dispc_feats;
-       } else if (cpu_is_omap34xx()) {
-               if (omap_rev() < OMAP3430_REV_ES3_0)
-                       src = &omap34xx_rev1_0_dispc_feats;
-               else
-                       src = &omap34xx_rev3_0_dispc_feats;
-       } else if (cpu_is_omap44xx()) {
-               src = &omap44xx_dispc_feats;
-       } else if (soc_is_omap54xx()) {
+               break;
+
+       case OMAPDSS_VER_OMAP34xx_ES1:
+               src = &omap34xx_rev1_0_dispc_feats;
+               break;
+
+       case OMAPDSS_VER_OMAP34xx_ES3:
+       case OMAPDSS_VER_OMAP3630:
+       case OMAPDSS_VER_AM35xx:
+               src = &omap34xx_rev3_0_dispc_feats;
+               break;
+
+       case OMAPDSS_VER_OMAP4430_ES1:
+       case OMAPDSS_VER_OMAP4430_ES2:
+       case OMAPDSS_VER_OMAP4:
                src = &omap44xx_dispc_feats;
-       } else {
+               break;
+
+       case OMAPDSS_VER_OMAP5:
+               src = &omap54xx_dispc_feats;
+               break;
+
+       default:
                return -ENODEV;
        }
 
@@ -4074,29 +3599,32 @@ static int __init dispc_init_features(struct device *dev)
        return 0;
 }
 
+int dispc_request_irq(irq_handler_t handler, void *dev_id)
+{
+       return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler,
+                            IRQF_SHARED, "OMAP DISPC", dev_id);
+}
+EXPORT_SYMBOL(dispc_request_irq);
+
+void dispc_free_irq(void *dev_id)
+{
+       devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id);
+}
+EXPORT_SYMBOL(dispc_free_irq);
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
        u32 rev;
        int r = 0;
        struct resource *dispc_mem;
-       struct clk *clk;
 
        dispc.pdev = pdev;
 
-       r = dispc_init_features(&dispc.pdev->dev);
+       r = dispc_init_features(dispc.pdev);
        if (r)
                return r;
 
-       spin_lock_init(&dispc.irq_lock);
-
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-       spin_lock_init(&dispc.irq_stats_lock);
-       dispc.irq_stats.last_reset = jiffies;
-#endif
-
-       INIT_WORK(&dispc.error_work, dispc_error_worker);
-
        dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
        if (!dispc_mem) {
                DSSERR("can't get IORESOURCE_MEM DISPC\n");
@@ -4116,22 +3644,6 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       r = devm_request_irq(&pdev->dev, dispc.irq, omap_dispc_irq_handler,
-                            IRQF_SHARED, "OMAP DISPC", dispc.pdev);
-       if (r < 0) {
-               DSSERR("request_irq failed\n");
-               return r;
-       }
-
-       clk = clk_get(&pdev->dev, "fck");
-       if (IS_ERR(clk)) {
-               DSSERR("can't get fck\n");
-               r = PTR_ERR(clk);
-               return r;
-       }
-
-       dispc.dss_clk = clk;
-
        pm_runtime_enable(&pdev->dev);
 
        r = dispc_runtime_get();
@@ -4140,8 +3652,6 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
        _omap_dispc_initial_config();
 
-       _omap_dispc_initialize_irq();
-
        rev = dispc_read_reg(DISPC_REVISION);
        dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
               FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
@@ -4150,14 +3660,10 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
        dss_debugfs_create_file("dispc", dispc_dump_regs);
 
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-       dss_debugfs_create_file("dispc_irq", dispc_dump_irqs);
-#endif
        return 0;
 
 err_runtime_get:
        pm_runtime_disable(&pdev->dev);
-       clk_put(dispc.dss_clk);
        return r;
 }
 
@@ -4165,8 +3671,6 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
 {
        pm_runtime_disable(&pdev->dev);
 
-       clk_put(dispc.dss_clk);
-
        return 0;
 }
 
diff --git a/drivers/video/omap2/dss/display-sysfs.c b/drivers/video/omap2/dss/display-sysfs.c
new file mode 100644 (file)
index 0000000..18211a9
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * 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/>.
+ */
+
+#define DSS_SUBSYS_NAME "DISPLAY"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+
+#include <video/omapdss.h>
+#include "dss.h"
+#include "dss_features.h"
+
+static ssize_t display_enabled_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED;
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", enabled);
+}
+
+static ssize_t display_enabled_store(struct device *dev,
+               struct device_attribute *attr,
+               const char *buf, size_t size)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       int r;
+       bool enabled;
+
+       r = strtobool(buf, &enabled);
+       if (r)
+               return r;
+
+       if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
+               if (enabled) {
+                       r = dssdev->driver->enable(dssdev);
+                       if (r)
+                               return r;
+               } else {
+                       dssdev->driver->disable(dssdev);
+               }
+       }
+
+       return size;
+}
+
+static ssize_t display_tear_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       return snprintf(buf, PAGE_SIZE, "%d\n",
+                       dssdev->driver->get_te ?
+                       dssdev->driver->get_te(dssdev) : 0);
+}
+
+static ssize_t display_tear_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t size)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       int r;
+       bool te;
+
+       if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
+               return -ENOENT;
+
+       r = strtobool(buf, &te);
+       if (r)
+               return r;
+
+       r = dssdev->driver->enable_te(dssdev, te);
+       if (r)
+               return r;
+
+       return size;
+}
+
+static ssize_t display_timings_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       struct omap_video_timings t;
+
+       if (!dssdev->driver->get_timings)
+               return -ENOENT;
+
+       dssdev->driver->get_timings(dssdev, &t);
+
+       return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
+                       t.pixel_clock,
+                       t.x_res, t.hfp, t.hbp, t.hsw,
+                       t.y_res, t.vfp, t.vbp, t.vsw);
+}
+
+static ssize_t display_timings_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t size)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       struct omap_video_timings t = dssdev->panel.timings;
+       int r, found;
+
+       if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
+               return -ENOENT;
+
+       found = 0;
+#ifdef CONFIG_OMAP2_DSS_VENC
+       if (strncmp("pal", buf, 3) == 0) {
+               t = omap_dss_pal_timings;
+               found = 1;
+       } else if (strncmp("ntsc", buf, 4) == 0) {
+               t = omap_dss_ntsc_timings;
+               found = 1;
+       }
+#endif
+       if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
+                               &t.pixel_clock,
+                               &t.x_res, &t.hfp, &t.hbp, &t.hsw,
+                               &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
+               return -EINVAL;
+
+       r = dssdev->driver->check_timings(dssdev, &t);
+       if (r)
+               return r;
+
+       dssdev->driver->disable(dssdev);
+       dssdev->driver->set_timings(dssdev, &t);
+       r = dssdev->driver->enable(dssdev);
+       if (r)
+               return r;
+
+       return size;
+}
+
+static ssize_t display_rotate_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       int rotate;
+       if (!dssdev->driver->get_rotate)
+               return -ENOENT;
+       rotate = dssdev->driver->get_rotate(dssdev);
+       return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
+}
+
+static ssize_t display_rotate_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t size)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       int rot, r;
+
+       if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
+               return -ENOENT;
+
+       r = kstrtoint(buf, 0, &rot);
+       if (r)
+               return r;
+
+       r = dssdev->driver->set_rotate(dssdev, rot);
+       if (r)
+               return r;
+
+       return size;
+}
+
+static ssize_t display_mirror_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       int mirror;
+       if (!dssdev->driver->get_mirror)
+               return -ENOENT;
+       mirror = dssdev->driver->get_mirror(dssdev);
+       return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
+}
+
+static ssize_t display_mirror_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t size)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       int r;
+       bool mirror;
+
+       if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
+               return -ENOENT;
+
+       r = strtobool(buf, &mirror);
+       if (r)
+               return r;
+
+       r = dssdev->driver->set_mirror(dssdev, mirror);
+       if (r)
+               return r;
+
+       return size;
+}
+
+static ssize_t display_wss_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       unsigned int wss;
+
+       if (!dssdev->driver->get_wss)
+               return -ENOENT;
+
+       wss = dssdev->driver->get_wss(dssdev);
+
+       return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
+}
+
+static ssize_t display_wss_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t size)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       u32 wss;
+       int r;
+
+       if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
+               return -ENOENT;
+
+       r = kstrtou32(buf, 0, &wss);
+       if (r)
+               return r;
+
+       if (wss > 0xfffff)
+               return -EINVAL;
+
+       r = dssdev->driver->set_wss(dssdev, wss);
+       if (r)
+               return r;
+
+       return size;
+}
+
+static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
+               display_enabled_show, display_enabled_store);
+static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
+               display_tear_show, display_tear_store);
+static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR,
+               display_timings_show, display_timings_store);
+static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR,
+               display_rotate_show, display_rotate_store);
+static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
+               display_mirror_show, display_mirror_store);
+static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
+               display_wss_show, display_wss_store);
+
+static struct device_attribute *display_sysfs_attrs[] = {
+       &dev_attr_enabled,
+       &dev_attr_tear_elim,
+       &dev_attr_timings,
+       &dev_attr_rotate,
+       &dev_attr_mirror,
+       &dev_attr_wss,
+       NULL
+};
+
+int display_init_sysfs(struct platform_device *pdev,
+               struct omap_dss_device *dssdev)
+{
+       struct device_attribute *attr;
+       int i, r;
+
+       /* create device sysfs files */
+       i = 0;
+       while ((attr = display_sysfs_attrs[i++]) != NULL) {
+               r = device_create_file(&dssdev->dev, attr);
+               if (r) {
+                       for (i = i - 2; i >= 0; i--) {
+                               attr = display_sysfs_attrs[i];
+                               device_remove_file(&dssdev->dev, attr);
+                       }
+
+                       DSSERR("failed to create sysfs file\n");
+                       return r;
+               }
+       }
+
+       /* create display? sysfs links */
+       r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
+                       dev_name(&dssdev->dev));
+       if (r) {
+               while ((attr = display_sysfs_attrs[i++]) != NULL)
+                       device_remove_file(&dssdev->dev, attr);
+
+               DSSERR("failed to create sysfs display link\n");
+               return r;
+       }
+
+       return 0;
+}
+
+void display_uninit_sysfs(struct platform_device *pdev,
+               struct omap_dss_device *dssdev)
+{
+       struct device_attribute *attr;
+       int i = 0;
+
+       sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev));
+
+       while ((attr = display_sysfs_attrs[i++]) != NULL)
+               device_remove_file(&dssdev->dev, attr);
+}
index ccf8550fafdedf5440a5fc6e585b7cf8d02f2b0d..0aa8ad8f96679db07b11c6221f7a3eff9f150ffe 100644 (file)
 #include "dss.h"
 #include "dss_features.h"
 
-static ssize_t display_enabled_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED;
-
-       return snprintf(buf, PAGE_SIZE, "%d\n", enabled);
-}
-
-static ssize_t display_enabled_store(struct device *dev,
-               struct device_attribute *attr,
-               const char *buf, size_t size)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       int r;
-       bool enabled;
-
-       r = strtobool(buf, &enabled);
-       if (r)
-               return r;
-
-       if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
-               if (enabled) {
-                       r = dssdev->driver->enable(dssdev);
-                       if (r)
-                               return r;
-               } else {
-                       dssdev->driver->disable(dssdev);
-               }
-       }
-
-       return size;
-}
-
-static ssize_t display_tear_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       return snprintf(buf, PAGE_SIZE, "%d\n",
-                       dssdev->driver->get_te ?
-                       dssdev->driver->get_te(dssdev) : 0);
-}
-
-static ssize_t display_tear_store(struct device *dev,
-               struct device_attribute *attr, const char *buf, size_t size)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       int r;
-       bool te;
-
-       if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
-               return -ENOENT;
-
-       r = strtobool(buf, &te);
-       if (r)
-               return r;
-
-       r = dssdev->driver->enable_te(dssdev, te);
-       if (r)
-               return r;
-
-       return size;
-}
-
-static ssize_t display_timings_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       struct omap_video_timings t;
-
-       if (!dssdev->driver->get_timings)
-               return -ENOENT;
-
-       dssdev->driver->get_timings(dssdev, &t);
-
-       return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
-                       t.pixel_clock,
-                       t.x_res, t.hfp, t.hbp, t.hsw,
-                       t.y_res, t.vfp, t.vbp, t.vsw);
-}
-
-static ssize_t display_timings_store(struct device *dev,
-               struct device_attribute *attr, const char *buf, size_t size)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       struct omap_video_timings t = dssdev->panel.timings;
-       int r, found;
-
-       if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
-               return -ENOENT;
-
-       found = 0;
-#ifdef CONFIG_OMAP2_DSS_VENC
-       if (strncmp("pal", buf, 3) == 0) {
-               t = omap_dss_pal_timings;
-               found = 1;
-       } else if (strncmp("ntsc", buf, 4) == 0) {
-               t = omap_dss_ntsc_timings;
-               found = 1;
-       }
-#endif
-       if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
-                               &t.pixel_clock,
-                               &t.x_res, &t.hfp, &t.hbp, &t.hsw,
-                               &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
-               return -EINVAL;
-
-       r = dssdev->driver->check_timings(dssdev, &t);
-       if (r)
-               return r;
-
-       dssdev->driver->disable(dssdev);
-       dssdev->driver->set_timings(dssdev, &t);
-       r = dssdev->driver->enable(dssdev);
-       if (r)
-               return r;
-
-       return size;
-}
-
-static ssize_t display_rotate_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       int rotate;
-       if (!dssdev->driver->get_rotate)
-               return -ENOENT;
-       rotate = dssdev->driver->get_rotate(dssdev);
-       return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
-}
-
-static ssize_t display_rotate_store(struct device *dev,
-               struct device_attribute *attr, const char *buf, size_t size)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       int rot, r;
-
-       if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
-               return -ENOENT;
-
-       r = kstrtoint(buf, 0, &rot);
-       if (r)
-               return r;
-
-       r = dssdev->driver->set_rotate(dssdev, rot);
-       if (r)
-               return r;
-
-       return size;
-}
-
-static ssize_t display_mirror_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       int mirror;
-       if (!dssdev->driver->get_mirror)
-               return -ENOENT;
-       mirror = dssdev->driver->get_mirror(dssdev);
-       return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
-}
-
-static ssize_t display_mirror_store(struct device *dev,
-               struct device_attribute *attr, const char *buf, size_t size)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       int r;
-       bool mirror;
-
-       if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
-               return -ENOENT;
-
-       r = strtobool(buf, &mirror);
-       if (r)
-               return r;
-
-       r = dssdev->driver->set_mirror(dssdev, mirror);
-       if (r)
-               return r;
-
-       return size;
-}
-
-static ssize_t display_wss_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       unsigned int wss;
-
-       if (!dssdev->driver->get_wss)
-               return -ENOENT;
-
-       wss = dssdev->driver->get_wss(dssdev);
-
-       return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
-}
-
-static ssize_t display_wss_store(struct device *dev,
-               struct device_attribute *attr, const char *buf, size_t size)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       u32 wss;
-       int r;
-
-       if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
-               return -ENOENT;
-
-       r = kstrtou32(buf, 0, &wss);
-       if (r)
-               return r;
-
-       if (wss > 0xfffff)
-               return -EINVAL;
-
-       r = dssdev->driver->set_wss(dssdev, wss);
-       if (r)
-               return r;
-
-       return size;
-}
-
-static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
-               display_enabled_show, display_enabled_store);
-static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
-               display_tear_show, display_tear_store);
-static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR,
-               display_timings_show, display_timings_store);
-static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR,
-               display_rotate_show, display_rotate_store);
-static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
-               display_mirror_show, display_mirror_store);
-static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
-               display_wss_show, display_wss_store);
-
-static struct device_attribute *display_sysfs_attrs[] = {
-       &dev_attr_enabled,
-       &dev_attr_tear_elim,
-       &dev_attr_timings,
-       &dev_attr_rotate,
-       &dev_attr_mirror,
-       &dev_attr_wss,
-       NULL
-};
-
 void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
                        u16 *xres, u16 *yres)
 {
@@ -320,136 +76,8 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
 }
 EXPORT_SYMBOL(omapdss_default_get_timings);
 
-/*
- * Connect dssdev to a manager if the manager is free or if force is specified.
- * Connect all overlays to that manager if they are free or if force is
- * specified.
- */
-static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
-{
-       struct omap_dss_output *out;
-       struct omap_overlay_manager *mgr;
-       int i, r;
-
-       out = omapdss_get_output_from_dssdev(dssdev);
-
-       WARN_ON(dssdev->output);
-       WARN_ON(out->device);
-
-       r = omapdss_output_set_device(out, dssdev);
-       if (r) {
-               DSSERR("failed to connect output to new device\n");
-               return r;
-       }
-
-       mgr = omap_dss_get_overlay_manager(dssdev->channel);
-
-       if (mgr->output && !force)
-               return 0;
-
-       if (mgr->output)
-               mgr->unset_output(mgr);
-
-       r = mgr->set_output(mgr, out);
-       if (r) {
-               DSSERR("failed to connect manager to output of new device\n");
-
-               /* remove the output-device connection we just made */
-               omapdss_output_unset_device(out);
-               return r;
-       }
-
-       for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
-               struct omap_overlay *ovl = omap_dss_get_overlay(i);
-
-               if (!ovl->manager || force) {
-                       if (ovl->manager)
-                               ovl->unset_manager(ovl);
-
-                       r = ovl->set_manager(ovl, mgr);
-                       if (r) {
-                               DSSERR("failed to set initial overlay\n");
-                               return r;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-static void dss_uninit_connections(struct omap_dss_device *dssdev)
-{
-       if (dssdev->output) {
-               struct omap_overlay_manager *mgr = dssdev->output->manager;
-
-               if (mgr)
-                       mgr->unset_output(mgr);
-
-               omapdss_output_unset_device(dssdev->output);
-       }
-}
-
-int dss_init_device(struct platform_device *pdev,
-               struct omap_dss_device *dssdev)
-{
-       struct device_attribute *attr;
-       int i, r;
-       const char *def_disp_name = dss_get_default_display_name();
-       bool force;
-
-       force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0;
-       dss_init_connections(dssdev, force);
-
-       /* create device sysfs files */
-       i = 0;
-       while ((attr = display_sysfs_attrs[i++]) != NULL) {
-               r = device_create_file(&dssdev->dev, attr);
-               if (r) {
-                       for (i = i - 2; i >= 0; i--) {
-                               attr = display_sysfs_attrs[i];
-                               device_remove_file(&dssdev->dev, attr);
-                       }
-
-                       dss_uninit_connections(dssdev);
-
-                       DSSERR("failed to create sysfs file\n");
-                       return r;
-               }
-       }
-
-       /* create display? sysfs links */
-       r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
-                       dev_name(&dssdev->dev));
-       if (r) {
-               while ((attr = display_sysfs_attrs[i++]) != NULL)
-                       device_remove_file(&dssdev->dev, attr);
-
-               dss_uninit_connections(dssdev);
-
-               DSSERR("failed to create sysfs display link\n");
-               return r;
-       }
-
-       return 0;
-}
-
-void dss_uninit_device(struct platform_device *pdev,
-               struct omap_dss_device *dssdev)
-{
-       struct device_attribute *attr;
-       int i = 0;
-
-       sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev));
-
-       while ((attr = display_sysfs_attrs[i++]) != NULL)
-               device_remove_file(&dssdev->dev, attr);
-
-       dss_uninit_connections(dssdev);
-}
-
 static int dss_suspend_device(struct device *dev, void *data)
 {
-       int r;
        struct omap_dss_device *dssdev = to_dss_device(dev);
 
        if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
@@ -457,15 +85,7 @@ static int dss_suspend_device(struct device *dev, void *data)
                return 0;
        }
 
-       if (!dssdev->driver->suspend) {
-               DSSERR("display '%s' doesn't implement suspend\n",
-                               dssdev->name);
-               return -ENOSYS;
-       }
-
-       r = dssdev->driver->suspend(dssdev);
-       if (r)
-               return r;
+       dssdev->driver->disable(dssdev);
 
        dssdev->activate_after_resume = true;
 
@@ -492,8 +112,8 @@ static int dss_resume_device(struct device *dev, void *data)
        int r;
        struct omap_dss_device *dssdev = to_dss_device(dev);
 
-       if (dssdev->activate_after_resume && dssdev->driver->resume) {
-               r = dssdev->driver->resume(dssdev);
+       if (dssdev->activate_after_resume) {
+               r = dssdev->driver->enable(dssdev);
                if (r)
                        return r;
        }
index 56748cf8760e52cce7d51245fb2f4dc1808e98c8..4af136a04e53ce4fafc67a3435a0121062e53674 100644 (file)
@@ -49,34 +49,53 @@ static struct {
        struct omap_dss_output output;
 } dpi;
 
-static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
+static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
 {
-       int dsi_module;
-
-       dsi_module = clk == OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ? 0 : 1;
+       /*
+        * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
+        * would also be used for DISPC fclk. Meaning, when the DPI output is
+        * disabled, DISPC clock will be disabled, and TV out will stop.
+        */
+       switch (omapdss_get_version()) {
+       case OMAPDSS_VER_OMAP24xx:
+       case OMAPDSS_VER_OMAP34xx_ES1:
+       case OMAPDSS_VER_OMAP34xx_ES3:
+       case OMAPDSS_VER_OMAP3630:
+       case OMAPDSS_VER_AM35xx:
+               return NULL;
+       default:
+               break;
+       }
 
-       return dsi_get_dsidev_from_id(dsi_module);
+       switch (channel) {
+       case OMAP_DSS_CHANNEL_LCD:
+               return dsi_get_dsidev_from_id(0);
+       case OMAP_DSS_CHANNEL_LCD2:
+               return dsi_get_dsidev_from_id(1);
+       default:
+               return NULL;
+       }
 }
 
-static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
+static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)
 {
-       if (dssdev->clocks.dispc.dispc_fclk_src ==
-                       OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
-                       dssdev->clocks.dispc.dispc_fclk_src ==
-                       OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC ||
-                       dssdev->clocks.dispc.channel.lcd_clk_src ==
-                       OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
-                       dssdev->clocks.dispc.channel.lcd_clk_src ==
-                       OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC)
-               return true;
-       else
-               return false;
+       switch (channel) {
+       case OMAP_DSS_CHANNEL_LCD:
+               return OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC;
+       case OMAP_DSS_CHANNEL_LCD2:
+               return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
+       default:
+               /* this shouldn't happen */
+               WARN_ON(1);
+               return OMAP_DSS_CLK_SRC_FCK;
+       }
 }
 
 static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
                unsigned long pck_req, unsigned long *fck, int *lck_div,
                int *pck_div)
 {
+       struct omap_overlay_manager *mgr = dssdev->output->manager;
        struct dsi_clock_info dsi_cinfo;
        struct dispc_clock_info dispc_cinfo;
        int r;
@@ -90,7 +109,8 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
        if (r)
                return r;
 
-       dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
+       dss_select_lcd_clk_source(mgr->id,
+                       dpi_get_alt_clk_src(mgr->id));
 
        dpi.mgr_config.clock_info = dispc_cinfo;
 
@@ -135,7 +155,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
        unsigned long pck;
        int r = 0;
 
-       if (dpi_use_dsi_pll(dssdev))
+       if (dpi.dsidev)
                r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
                                &lck_div, &pck_div);
        else
@@ -214,7 +234,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
        if (r)
                goto err_src_sel;
 
-       if (dpi_use_dsi_pll(dssdev)) {
+       if (dpi.dsidev) {
                r = dsi_runtime_get(dpi.dsidev);
                if (r)
                        goto err_get_dsi;
@@ -242,10 +262,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 
 err_mgr_enable:
 err_set_mode:
-       if (dpi_use_dsi_pll(dssdev))
+       if (dpi.dsidev)
                dsi_pll_uninit(dpi.dsidev, true);
 err_dsi_pll_init:
-       if (dpi_use_dsi_pll(dssdev))
+       if (dpi.dsidev)
                dsi_runtime_put(dpi.dsidev);
 err_get_dsi:
 err_src_sel:
@@ -271,8 +291,8 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 
        dss_mgr_disable(mgr);
 
-       if (dpi_use_dsi_pll(dssdev)) {
-               dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
+       if (dpi.dsidev) {
+               dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
                dsi_pll_uninit(dpi.dsidev, true);
                dsi_runtime_put(dpi.dsidev);
        }
@@ -311,13 +331,13 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
        unsigned long pck;
        struct dispc_clock_info dispc_cinfo;
 
-       if (dss_mgr_check_timings(mgr, timings))
+       if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))
                return -EINVAL;
 
        if (timings->pixel_clock == 0)
                return -EINVAL;
 
-       if (dpi_use_dsi_pll(dssdev)) {
+       if (dpi.dsidev) {
                struct dsi_clock_info dsi_cinfo;
                r = dsi_pll_calc_clock_div_pck(dpi.dsidev,
                                timings->pixel_clock * 1000,
@@ -359,8 +379,32 @@ void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
 }
 EXPORT_SYMBOL(omapdss_dpi_set_data_lines);
 
+static int __init dpi_verify_dsi_pll(struct platform_device *dsidev)
+{
+       int r;
+
+       /* do initial setup with the PLL to see if it is operational */
+
+       r = dsi_runtime_get(dsidev);
+       if (r)
+               return r;
+
+       r = dsi_pll_init(dsidev, 0, 1);
+       if (r) {
+               dsi_runtime_put(dsidev);
+               return r;
+       }
+
+       dsi_pll_uninit(dsidev, true);
+       dsi_runtime_put(dsidev);
+
+       return 0;
+}
+
 static int __init dpi_init_display(struct omap_dss_device *dssdev)
 {
+       struct platform_device *dsidev;
+
        DSSDBG("init_display\n");
 
        if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
@@ -377,19 +421,30 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
                dpi.vdds_dsi_reg = vdds_dsi;
        }
 
-       if (dpi_use_dsi_pll(dssdev)) {
-               enum omap_dss_clk_source dispc_fclk_src =
-                       dssdev->clocks.dispc.dispc_fclk_src;
-               dpi.dsidev = dpi_get_dsidev(dispc_fclk_src);
+       /*
+        * XXX We shouldn't need dssdev->channel for this. The dsi pll clock
+        * source for DPI is SoC integration detail, not something that should
+        * be configured in the dssdev
+        */
+       dsidev = dpi_get_dsidev(dssdev->channel);
+
+       if (dsidev && dpi_verify_dsi_pll(dsidev)) {
+               dsidev = NULL;
+               DSSWARN("DSI PLL not operational\n");
        }
 
+       if (dsidev)
+               DSSDBG("using DSI PLL for DPI clock\n");
+
+       dpi.dsidev = dsidev;
+
        return 0;
 }
 
 static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev)
 {
        struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-       const char *def_disp_name = dss_get_default_display_name();
+       const char *def_disp_name = omapdss_get_default_display_name();
        struct omap_dss_device *def_dssdev;
        int i;
 
@@ -438,9 +493,18 @@ static void __init dpi_probe_pdata(struct platform_device *dpidev)
                return;
        }
 
+       r = omapdss_output_set_device(&dpi.output, dssdev);
+       if (r) {
+               DSSERR("failed to connect output to new device: %s\n",
+                               dssdev->name);
+               dss_put_device(dssdev);
+               return;
+       }
+
        r = dss_add_device(dssdev);
        if (r) {
                DSSERR("device %s register failed: %d\n", dssdev->name, r);
+               omapdss_output_unset_device(&dpi.output);
                dss_put_device(dssdev);
                return;
        }
index bee92846cfab930f6304a9ebb4316b25b8780bc7..28d41d16b7be45aa10d646ba8983cd57e418e363 100644 (file)
@@ -45,7 +45,6 @@
 #include "dss.h"
 #include "dss_features.h"
 
-/*#define VERBOSE_IRQ*/
 #define DSI_CATCH_MISSING_TE
 
 struct dsi_reg { u16 idx; };
@@ -535,42 +534,38 @@ static inline void dsi_perf_show(struct platform_device *dsidev,
 }
 #endif
 
+static int verbose_irq;
+
 static void print_irq_status(u32 status)
 {
        if (status == 0)
                return;
 
-#ifndef VERBOSE_IRQ
-       if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0)
+       if (!verbose_irq && (status & ~DSI_IRQ_CHANNEL_MASK) == 0)
                return;
-#endif
-       printk(KERN_DEBUG "DSI IRQ: 0x%x: ", status);
 
-#define PIS(x) \
-       if (status & DSI_IRQ_##x) \
-               printk(#x " ");
-#ifdef VERBOSE_IRQ
-       PIS(VC0);
-       PIS(VC1);
-       PIS(VC2);
-       PIS(VC3);
-#endif
-       PIS(WAKEUP);
-       PIS(RESYNC);
-       PIS(PLL_LOCK);
-       PIS(PLL_UNLOCK);
-       PIS(PLL_RECALL);
-       PIS(COMPLEXIO_ERR);
-       PIS(HS_TX_TIMEOUT);
-       PIS(LP_RX_TIMEOUT);
-       PIS(TE_TRIGGER);
-       PIS(ACK_TRIGGER);
-       PIS(SYNC_LOST);
-       PIS(LDO_POWER_GOOD);
-       PIS(TA_TIMEOUT);
+#define PIS(x) (status & DSI_IRQ_##x) ? (#x " ") : ""
+
+       pr_debug("DSI IRQ: 0x%x: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+               status,
+               verbose_irq ? PIS(VC0) : "",
+               verbose_irq ? PIS(VC1) : "",
+               verbose_irq ? PIS(VC2) : "",
+               verbose_irq ? PIS(VC3) : "",
+               PIS(WAKEUP),
+               PIS(RESYNC),
+               PIS(PLL_LOCK),
+               PIS(PLL_UNLOCK),
+               PIS(PLL_RECALL),
+               PIS(COMPLEXIO_ERR),
+               PIS(HS_TX_TIMEOUT),
+               PIS(LP_RX_TIMEOUT),
+               PIS(TE_TRIGGER),
+               PIS(ACK_TRIGGER),
+               PIS(SYNC_LOST),
+               PIS(LDO_POWER_GOOD),
+               PIS(TA_TIMEOUT));
 #undef PIS
-
-       printk("\n");
 }
 
 static void print_irq_status_vc(int channel, u32 status)
@@ -578,28 +573,24 @@ static void print_irq_status_vc(int channel, u32 status)
        if (status == 0)
                return;
 
-#ifndef VERBOSE_IRQ
-       if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
+       if (!verbose_irq && (status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
                return;
-#endif
-       printk(KERN_DEBUG "DSI VC(%d) IRQ 0x%x: ", channel, status);
 
-#define PIS(x) \
-       if (status & DSI_VC_IRQ_##x) \
-               printk(#x " ");
-       PIS(CS);
-       PIS(ECC_CORR);
-#ifdef VERBOSE_IRQ
-       PIS(PACKET_SENT);
-#endif
-       PIS(FIFO_TX_OVF);
-       PIS(FIFO_RX_OVF);
-       PIS(BTA);
-       PIS(ECC_NO_CORR);
-       PIS(FIFO_TX_UDF);
-       PIS(PP_BUSY_CHANGE);
+#define PIS(x) (status & DSI_VC_IRQ_##x) ? (#x " ") : ""
+
+       pr_debug("DSI VC(%d) IRQ 0x%x: %s%s%s%s%s%s%s%s%s\n",
+               channel,
+               status,
+               PIS(CS),
+               PIS(ECC_CORR),
+               PIS(ECC_NO_CORR),
+               verbose_irq ? PIS(PACKET_SENT) : "",
+               PIS(BTA),
+               PIS(FIFO_TX_OVF),
+               PIS(FIFO_RX_OVF),
+               PIS(FIFO_TX_UDF),
+               PIS(PP_BUSY_CHANGE));
 #undef PIS
-       printk("\n");
 }
 
 static void print_irq_status_cio(u32 status)
@@ -607,34 +598,31 @@ static void print_irq_status_cio(u32 status)
        if (status == 0)
                return;
 
-       printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status);
-
-#define PIS(x) \
-       if (status & DSI_CIO_IRQ_##x) \
-               printk(#x " ");
-       PIS(ERRSYNCESC1);
-       PIS(ERRSYNCESC2);
-       PIS(ERRSYNCESC3);
-       PIS(ERRESC1);
-       PIS(ERRESC2);
-       PIS(ERRESC3);
-       PIS(ERRCONTROL1);
-       PIS(ERRCONTROL2);
-       PIS(ERRCONTROL3);
-       PIS(STATEULPS1);
-       PIS(STATEULPS2);
-       PIS(STATEULPS3);
-       PIS(ERRCONTENTIONLP0_1);
-       PIS(ERRCONTENTIONLP1_1);
-       PIS(ERRCONTENTIONLP0_2);
-       PIS(ERRCONTENTIONLP1_2);
-       PIS(ERRCONTENTIONLP0_3);
-       PIS(ERRCONTENTIONLP1_3);
-       PIS(ULPSACTIVENOT_ALL0);
-       PIS(ULPSACTIVENOT_ALL1);
+#define PIS(x) (status & DSI_CIO_IRQ_##x) ? (#x " ") : ""
+
+       pr_debug("DSI CIO IRQ 0x%x: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+               status,
+               PIS(ERRSYNCESC1),
+               PIS(ERRSYNCESC2),
+               PIS(ERRSYNCESC3),
+               PIS(ERRESC1),
+               PIS(ERRESC2),
+               PIS(ERRESC3),
+               PIS(ERRCONTROL1),
+               PIS(ERRCONTROL2),
+               PIS(ERRCONTROL3),
+               PIS(STATEULPS1),
+               PIS(STATEULPS2),
+               PIS(STATEULPS3),
+               PIS(ERRCONTENTIONLP0_1),
+               PIS(ERRCONTENTIONLP1_1),
+               PIS(ERRCONTENTIONLP0_2),
+               PIS(ERRCONTENTIONLP1_2),
+               PIS(ERRCONTENTIONLP0_3),
+               PIS(ERRCONTENTIONLP1_3),
+               PIS(ULPSACTIVENOT_ALL0),
+               PIS(ULPSACTIVENOT_ALL1));
 #undef PIS
-
-       printk("\n");
 }
 
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
@@ -1116,28 +1104,16 @@ static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
        }
 }
 
-#ifdef DEBUG
 static void _dsi_print_reset_status(struct platform_device *dsidev)
 {
        u32 l;
        int b0, b1, b2;
 
-       if (!dss_debug)
-               return;
-
        /* A dummy read using the SCP interface to any DSIPHY register is
         * required after DSIPHY reset to complete the reset of the DSI complex
         * I/O. */
        l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
 
-       printk(KERN_DEBUG "DSI resets: ");
-
-       l = dsi_read_reg(dsidev, DSI_PLL_STATUS);
-       printk("PLL (%d) ", FLD_GET(l, 0, 0));
-
-       l = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
-       printk("CIO (%d) ", FLD_GET(l, 29, 29));
-
        if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
                b0 = 28;
                b1 = 27;
@@ -1148,18 +1124,21 @@ static void _dsi_print_reset_status(struct platform_device *dsidev)
                b2 = 26;
        }
 
-       l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
-       printk("PHY (%x%x%x, %d, %d, %d)\n",
-                       FLD_GET(l, b0, b0),
-                       FLD_GET(l, b1, b1),
-                       FLD_GET(l, b2, b2),
-                       FLD_GET(l, 29, 29),
-                       FLD_GET(l, 30, 30),
-                       FLD_GET(l, 31, 31));
+#define DSI_FLD_GET(fld, start, end)\
+       FLD_GET(dsi_read_reg(dsidev, DSI_##fld), start, end)
+
+       pr_debug("DSI resets: PLL (%d) CIO (%d) PHY (%x%x%x, %d, %d, %d)\n",
+               DSI_FLD_GET(PLL_STATUS, 0, 0),
+               DSI_FLD_GET(COMPLEXIO_CFG1, 29, 29),
+               DSI_FLD_GET(DSIPHY_CFG5, b0, b0),
+               DSI_FLD_GET(DSIPHY_CFG5, b1, b1),
+               DSI_FLD_GET(DSIPHY_CFG5, b2, b2),
+               DSI_FLD_GET(DSIPHY_CFG5, 29, 29),
+               DSI_FLD_GET(DSIPHY_CFG5, 30, 30),
+               DSI_FLD_GET(DSIPHY_CFG5, 31, 31));
+
+#undef DSI_FLD_GET
 }
-#else
-#define _dsi_print_reset_status(x)
-#endif
 
 static inline int dsi_if_enable(struct platform_device *dsidev, bool enable)
 {
@@ -1407,6 +1386,11 @@ retry:
                                cur.dsi_pll_hsdiv_dispc_clk =
                                        cur.clkin4ddr / cur.regm_dispc;
 
+                               if (cur.regm_dispc > 1 &&
+                                               cur.regm_dispc % 2 != 0 &&
+                                               req_pck >= 1000000)
+                                       continue;
+
                                /* this will narrow down the search a bit,
                                 * but still give pixclocks below what was
                                 * requested */
@@ -1621,7 +1605,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
        u8 regn_start, regn_end, regm_start, regm_end;
        u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
 
-       DSSDBGF();
+       DSSDBG("DSI PLL clock config starts");
 
        dsi->current_cinfo.clkin = cinfo->clkin;
        dsi->current_cinfo.fint = cinfo->fint;
@@ -1757,11 +1741,21 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
 
        DSSDBG("PLL init\n");
 
+       /*
+        * It seems that on many OMAPs we need to enable both to have a
+        * functional HSDivider.
+        */
+       enable_hsclk = enable_hsdiv = true;
+
        if (dsi->vdds_dsi_reg == NULL) {
                struct regulator *vdds_dsi;
 
                vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
 
+               /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
+               if (IS_ERR(vdds_dsi))
+                       vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO");
+
                if (IS_ERR(vdds_dsi)) {
                        DSSERR("can't get VDDS_DSI regulator\n");
                        return PTR_ERR(vdds_dsi);
@@ -2440,7 +2434,7 @@ static int dsi_cio_init(struct platform_device *dsidev)
        int r;
        u32 l;
 
-       DSSDBGF();
+       DSSDBG("DSI CIO init starts");
 
        r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
        if (r)
@@ -2791,7 +2785,7 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
 {
        u32 r;
 
-       DSSDBGF("%d", channel);
+       DSSDBG("Initial config of virtual channel %d", channel);
 
        r = dsi_read_reg(dsidev, DSI_VC_CTRL(channel));
 
@@ -2823,7 +2817,7 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
        if (dsi->vc[channel].source == source)
                return 0;
 
-       DSSDBGF("%d", channel);
+       DSSDBG("Source config of virtual channel %d", channel);
 
        dsi_sync_vc(dsidev, channel);
 
@@ -3581,7 +3575,7 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
        int r, i;
        unsigned mask;
 
-       DSSDBGF();
+       DSSDBG("Entering ULPS");
 
        WARN_ON(!dsi_bus_is_locked(dsidev));
 
@@ -4285,7 +4279,7 @@ int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
        unsigned long pck;
        int r;
 
-       DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
+       DSSDBG("Setting DSI clocks: ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
 
        mutex_lock(&dsi->lock);
 
@@ -4541,7 +4535,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
        dsi_handle_framedone(dsi->pdev, -ETIMEDOUT);
 }
 
-static void dsi_framedone_irq_callback(void *data, u32 mask)
+static void dsi_framedone_irq_callback(void *data)
 {
        struct platform_device *dsidev = (struct platform_device *) data;
        struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -4615,7 +4609,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
        struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
        struct omap_overlay_manager *mgr = dssdev->output->manager;
        int r;
-       u32 irq = 0;
 
        if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
                dsi->timings.hsw = 1;
@@ -4625,12 +4618,10 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
                dsi->timings.vfp = 0;
                dsi->timings.vbp = 0;
 
-               irq = dispc_mgr_get_framedone_irq(mgr->id);
-
-               r = omap_dispc_register_isr(dsi_framedone_irq_callback,
-                       (void *) dsidev, irq);
+               r = dss_mgr_register_framedone_handler(mgr,
+                               dsi_framedone_irq_callback, dsidev);
                if (r) {
-                       DSSERR("can't get FRAMEDONE irq\n");
+                       DSSERR("can't register FRAMEDONE handler\n");
                        goto err;
                }
 
@@ -4668,8 +4659,8 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
        return 0;
 err1:
        if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
-               omap_dispc_unregister_isr(dsi_framedone_irq_callback,
-                       (void *) dsidev, irq);
+               dss_mgr_unregister_framedone_handler(mgr,
+                               dsi_framedone_irq_callback, dsidev);
 err:
        return r;
 }
@@ -4680,14 +4671,9 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
        struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
        struct omap_overlay_manager *mgr = dssdev->output->manager;
 
-       if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
-               u32 irq;
-
-               irq = dispc_mgr_get_framedone_irq(mgr->id);
-
-               omap_dispc_unregister_isr(dsi_framedone_irq_callback,
-                       (void *) dsidev, irq);
-       }
+       if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
+               dss_mgr_unregister_framedone_handler(mgr,
+                               dsi_framedone_irq_callback, dsidev);
 }
 
 static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
@@ -4730,7 +4716,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
        if (r)
                goto err1;
 
-       dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
        dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src);
        dss_select_lcd_clk_source(mgr->id,
                        dssdev->clocks.dispc.channel.lcd_clk_src);
@@ -4765,7 +4750,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
 err3:
        dsi_cio_uninit(dsidev);
 err2:
-       dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
        dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
        dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
 
@@ -4792,7 +4776,6 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
        dsi_vc_enable(dsidev, 2, 0);
        dsi_vc_enable(dsidev, 3, 0);
 
-       dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
        dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
        dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
        dsi_cio_uninit(dsidev);
@@ -4981,6 +4964,10 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)
 
                vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
 
+               /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */
+               if (IS_ERR(vdds_dsi))
+                       vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO");
+
                if (IS_ERR(vdds_dsi)) {
                        DSSERR("can't get VDDS_DSI regulator\n");
                        return PTR_ERR(vdds_dsi);
@@ -5121,7 +5108,7 @@ static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *p
 {
        struct omap_dss_board_info *pdata = pdev->dev.platform_data;
        struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
-       const char *def_disp_name = dss_get_default_display_name();
+       const char *def_disp_name = omapdss_get_default_display_name();
        struct omap_dss_device *def_dssdev;
        int i;
 
@@ -5151,6 +5138,7 @@ static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *p
 
 static void __init dsi_probe_pdata(struct platform_device *dsidev)
 {
+       struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
        struct omap_dss_device *plat_dssdev;
        struct omap_dss_device *dssdev;
        int r;
@@ -5173,9 +5161,18 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
                return;
        }
 
+       r = omapdss_output_set_device(&dsi->output, dssdev);
+       if (r) {
+               DSSERR("failed to connect output to new device: %s\n",
+                               dssdev->name);
+               dss_put_device(dssdev);
+               return;
+       }
+
        r = dss_add_device(dssdev);
        if (r) {
                DSSERR("device %s register failed: %d\n", dssdev->name, r);
+               omapdss_output_unset_device(&dsi->output);
                dss_put_device(dssdev);
                return;
        }
index 5f6eea801b064a37949b3cc66bf9ca5f2dde3431..054c2a22b3f1c650aca01037bd6d125d3a55235f 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/gfp.h>
+#include <linux/sizes.h>
 
 #include <video/omapdss.h>
 
-#include <plat/cpu.h>
-
 #include "dss.h"
 #include "dss_features.h"
 
@@ -78,6 +77,7 @@ static struct {
 
        struct clk      *dpll4_m4_ck;
        struct clk      *dss_clk;
+       unsigned long   dss_clk_rate;
 
        unsigned long   cache_req_pck;
        unsigned long   cache_prate;
@@ -98,6 +98,8 @@ static const char * const dss_generic_clk_source_names[] = {
        [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC]  = "DSI_PLL_HSDIV_DISPC",
        [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI]    = "DSI_PLL_HSDIV_DSI",
        [OMAP_DSS_CLK_SRC_FCK]                  = "DSS_FCK",
+       [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DSI_PLL2_HSDIV_DISPC",
+       [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI]   = "DSI_PLL2_HSDIV_DSI",
 };
 
 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
@@ -153,6 +155,21 @@ static void dss_restore_context(void)
 #undef SR
 #undef RR
 
+int dss_get_ctx_loss_count(void)
+{
+       struct omap_dss_board_info *board_data = dss.pdev->dev.platform_data;
+       int cnt;
+
+       if (!board_data->get_context_loss_count)
+               return -ENOENT;
+
+       cnt = board_data->get_context_loss_count(&dss.pdev->dev);
+
+       WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt);
+
+       return cnt;
+}
+
 void dss_sdi_init(int datapairs)
 {
        u32 l;
@@ -303,7 +320,7 @@ static void dss_dump_regs(struct seq_file *s)
 #undef DUMPREG
 }
 
-void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
+static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
 {
        struct platform_device *dsidev;
        int b;
@@ -374,8 +391,10 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
        struct platform_device *dsidev;
        int b, ix, pos;
 
-       if (!dss_has_feature(FEAT_LCD_CLK_SRC))
+       if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
+               dss_select_dispc_clk_source(clk_src);
                return;
+       }
 
        switch (clk_src) {
        case OMAP_DSS_CLK_SRC_FCK:
@@ -431,6 +450,29 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
        }
 }
 
+/* calculate clock rates using dividers in cinfo */
+int dss_calc_clock_rates(struct dss_clock_info *cinfo)
+{
+       if (dss.dpll4_m4_ck) {
+               unsigned long prate;
+
+               if (cinfo->fck_div > dss.feat->fck_div_max ||
+                               cinfo->fck_div == 0)
+                       return -EINVAL;
+
+               prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
+
+               cinfo->fck = prate / cinfo->fck_div *
+                       dss.feat->dss_fck_multiplier;
+       } else {
+               if (cinfo->fck_div != 0)
+                       return -EINVAL;
+               cinfo->fck = clk_get_rate(dss.dss_clk);
+       }
+
+       return 0;
+}
+
 int dss_set_clock_div(struct dss_clock_info *cinfo)
 {
        if (dss.dpll4_m4_ck) {
@@ -448,6 +490,10 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
                        return -EINVAL;
        }
 
+       dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
+
+       WARN_ONCE(dss.dss_clk_rate != cinfo->fck, "clk rate mismatch");
+
        DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
 
        return 0;
@@ -461,6 +507,41 @@ unsigned long dss_get_dpll4_rate(void)
                return 0;
 }
 
+unsigned long dss_get_dispc_clk_rate(void)
+{
+       return dss.dss_clk_rate;
+}
+
+static int dss_setup_default_clock(void)
+{
+       unsigned long max_dss_fck, prate;
+       unsigned fck_div;
+       struct dss_clock_info dss_cinfo = { 0 };
+       int r;
+
+       if (dss.dpll4_m4_ck == NULL)
+               return 0;
+
+       max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+
+       prate = dss_get_dpll4_rate();
+
+       fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
+                       max_dss_fck);
+
+       dss_cinfo.fck_div = fck_div;
+
+       r = dss_calc_clock_rates(&dss_cinfo);
+       if (r)
+               return r;
+
+       r = dss_set_clock_div(&dss_cinfo);
+       if (r)
+               return r;
+
+       return 0;
+}
+
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
                struct dispc_clock_info *dispc_cinfo)
 {
@@ -750,7 +831,7 @@ static void dss_runtime_put(void)
 }
 
 /* DEBUGFS */
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
 void dss_debug_dump_clocks(struct seq_file *s)
 {
        dss_dump_clocks(s);
@@ -796,29 +877,45 @@ static const struct dss_features omap54xx_dss_feats __initconst = {
        .dpi_select_source      =       &dss_dpi_select_source_omap5,
 };
 
-static int __init dss_init_features(struct device *dev)
+static int __init dss_init_features(struct platform_device *pdev)
 {
        const struct dss_features *src;
        struct dss_features *dst;
 
-       dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+       dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
        if (!dst) {
-               dev_err(dev, "Failed to allocate local DSS Features\n");
+               dev_err(&pdev->dev, "Failed to allocate local DSS Features\n");
                return -ENOMEM;
        }
 
-       if (cpu_is_omap24xx())
+       switch (omapdss_get_version()) {
+       case OMAPDSS_VER_OMAP24xx:
                src = &omap24xx_dss_feats;
-       else if (cpu_is_omap3630())
-               src = &omap3630_dss_feats;
-       else if (cpu_is_omap34xx())
+               break;
+
+       case OMAPDSS_VER_OMAP34xx_ES1:
+       case OMAPDSS_VER_OMAP34xx_ES3:
+       case OMAPDSS_VER_AM35xx:
                src = &omap34xx_dss_feats;
-       else if (cpu_is_omap44xx())
+               break;
+
+       case OMAPDSS_VER_OMAP3630:
+               src = &omap3630_dss_feats;
+               break;
+
+       case OMAPDSS_VER_OMAP4430_ES1:
+       case OMAPDSS_VER_OMAP4430_ES2:
+       case OMAPDSS_VER_OMAP4:
                src = &omap44xx_dss_feats;
-       else if (soc_is_omap54xx())
+               break;
+
+       case OMAPDSS_VER_OMAP5:
                src = &omap54xx_dss_feats;
-       else
+               break;
+
+       default:
                return -ENODEV;
+       }
 
        memcpy(dst, src, sizeof(*dst));
        dss.feat = dst;
@@ -835,7 +932,7 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 
        dss.pdev = pdev;
 
-       r = dss_init_features(&dss.pdev->dev);
+       r = dss_init_features(dss.pdev);
        if (r)
                return r;
 
@@ -856,15 +953,23 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
        if (r)
                return r;
 
+       r = dss_setup_default_clock();
+       if (r)
+               goto err_setup_clocks;
+
        pm_runtime_enable(&pdev->dev);
 
        r = dss_runtime_get();
        if (r)
                goto err_runtime_get;
 
+       dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
+
        /* Select DPLL */
        REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
 
+       dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
+
 #ifdef CONFIG_OMAP2_DSS_VENC
        REG_FLD_MOD(DSS_CONTROL, 1, 4, 4);      /* venc dac demen */
        REG_FLD_MOD(DSS_CONTROL, 1, 3, 3);      /* venc clock 4x enable */
@@ -888,6 +993,7 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 
 err_runtime_get:
        pm_runtime_disable(&pdev->dev);
+err_setup_clocks:
        dss_put_clocks();
        return r;
 }
index 6728892f9dad596040c8c5ae0c270036f4ba5975..610c8e563daa2033750c3eec12f3328ad7db38e4 100644 (file)
 #ifndef __OMAP2_DSS_H
 #define __OMAP2_DSS_H
 
-#ifdef CONFIG_OMAP2_DSS_DEBUG_SUPPORT
-#define DEBUG
-#endif
+#include <linux/interrupt.h>
 
-#ifdef DEBUG
-extern bool dss_debug;
-#ifdef DSS_SUBSYS_NAME
-#define DSSDBG(format, ...) \
-       if (dss_debug) \
-               printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME ": " format, \
-               ## __VA_ARGS__)
-#else
-#define DSSDBG(format, ...) \
-       if (dss_debug) \
-               printk(KERN_DEBUG "omapdss: " format, ## __VA_ARGS__)
+#ifdef pr_fmt
+#undef pr_fmt
 #endif
 
 #ifdef DSS_SUBSYS_NAME
-#define DSSDBGF(format, ...) \
-       if (dss_debug) \
-               printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME \
-                               ": %s(" format ")\n", \
-                               __func__, \
-                               ## __VA_ARGS__)
+#define pr_fmt(fmt) DSS_SUBSYS_NAME ": " fmt
 #else
-#define DSSDBGF(format, ...) \
-       if (dss_debug) \
-               printk(KERN_DEBUG "omapdss: " \
-                               ": %s(" format ")\n", \
-                               __func__, \
-                               ## __VA_ARGS__)
-#endif
-
-#else /* DEBUG */
-#define DSSDBG(format, ...)
-#define DSSDBGF(format, ...)
+#define pr_fmt(fmt) fmt
 #endif
 
+#define DSSDBG(format, ...) \
+       pr_debug(format, ## __VA_ARGS__)
 
 #ifdef DSS_SUBSYS_NAME
 #define DSSERR(format, ...) \
@@ -186,11 +162,10 @@ struct seq_file;
 struct platform_device;
 
 /* core */
-const char *dss_get_default_display_name(void);
+struct platform_device *dss_get_core_pdev(void);
 struct bus_type *dss_get_bus(void);
 struct regulator *dss_get_vdds_dsi(void);
 struct regulator *dss_get_vdds_sdi(void);
-int dss_get_ctx_loss_count(struct device *dev);
 int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask);
 void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask);
 int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
@@ -204,55 +179,18 @@ void dss_put_device(struct omap_dss_device *dssdev);
 void dss_copy_device_pdata(struct omap_dss_device *dst,
                const struct omap_dss_device *src);
 
-/* apply */
-void dss_apply_init(void);
-int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr);
-int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
-void dss_mgr_start_update(struct omap_overlay_manager *mgr);
-int omap_dss_mgr_apply(struct omap_overlay_manager *mgr);
-
-int dss_mgr_enable(struct omap_overlay_manager *mgr);
-void dss_mgr_disable(struct omap_overlay_manager *mgr);
-int dss_mgr_set_info(struct omap_overlay_manager *mgr,
-               struct omap_overlay_manager_info *info);
-void dss_mgr_get_info(struct omap_overlay_manager *mgr,
-               struct omap_overlay_manager_info *info);
-int dss_mgr_set_device(struct omap_overlay_manager *mgr,
-               struct omap_dss_device *dssdev);
-int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
-int dss_mgr_set_output(struct omap_overlay_manager *mgr,
-               struct omap_dss_output *output);
-int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
-void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
-               const struct omap_video_timings *timings);
-void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
-               const struct dss_lcd_mgr_config *config);
-const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
-
-bool dss_ovl_is_enabled(struct omap_overlay *ovl);
-int dss_ovl_enable(struct omap_overlay *ovl);
-int dss_ovl_disable(struct omap_overlay *ovl);
-int dss_ovl_set_info(struct omap_overlay *ovl,
-               struct omap_overlay_info *info);
-void dss_ovl_get_info(struct omap_overlay *ovl,
-               struct omap_overlay_info *info);
-int dss_ovl_set_manager(struct omap_overlay *ovl,
-               struct omap_overlay_manager *mgr);
-int dss_ovl_unset_manager(struct omap_overlay *ovl);
-
 /* output */
 void dss_register_output(struct omap_dss_output *out);
 void dss_unregister_output(struct omap_dss_output *out);
-struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev);
 
 /* display */
 int dss_suspend_all_devices(void);
 int dss_resume_all_devices(void);
 void dss_disable_all_devices(void);
 
-int dss_init_device(struct platform_device *pdev,
+int display_init_sysfs(struct platform_device *pdev,
                struct omap_dss_device *dssdev);
-void dss_uninit_device(struct platform_device *pdev,
+void display_uninit_sysfs(struct platform_device *pdev,
                struct omap_dss_device *dssdev);
 
 /* manager */
@@ -299,21 +237,23 @@ void dss_overlay_kobj_uninit(struct omap_overlay *ovl);
 int dss_init_platform_driver(void) __init;
 void dss_uninit_platform_driver(void);
 
+unsigned long dss_get_dispc_clk_rate(void);
 int dss_dpi_select_source(enum omap_channel channel);
 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
 const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
 void dss_dump_clocks(struct seq_file *s);
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
 void dss_debug_dump_clocks(struct seq_file *s);
 #endif
 
+int dss_get_ctx_loss_count(void);
+
 void dss_sdi_init(int datapairs);
 int dss_sdi_enable(void);
 void dss_sdi_disable(void);
 
-void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src);
 void dss_select_dsi_clk_source(int dsi_module,
                enum omap_dss_clk_source clk_src);
 void dss_select_lcd_clk_source(enum omap_channel channel,
@@ -326,6 +266,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type);
 void dss_set_dac_pwrdn_bgz(bool enable);
 
 unsigned long dss_get_dpll4_rate(void);
+int dss_calc_clock_rates(struct dss_clock_info *cinfo);
 int dss_set_clock_div(struct dss_clock_info *cinfo);
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
                struct dispc_clock_info *dispc_cinfo);
@@ -413,8 +354,6 @@ static inline void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
 }
 static inline struct platform_device *dsi_get_dsidev_from_id(int module)
 {
-       WARN("%s: DSI not compiled in, returning platform device as NULL\n",
-                       __func__);
        return NULL;
 }
 #endif
@@ -427,15 +366,10 @@ void dpi_uninit_platform_driver(void) __exit;
 int dispc_init_platform_driver(void) __init;
 void dispc_uninit_platform_driver(void) __exit;
 void dispc_dump_clocks(struct seq_file *s);
-void dispc_irq_handler(void);
-
-int dispc_runtime_get(void);
-void dispc_runtime_put(void);
 
 void dispc_enable_sidle(void);
 void dispc_disable_sidle(void);
 
-void dispc_lcd_enable_signal_polarity(bool act_high);
 void dispc_lcd_enable_signal(bool enable);
 void dispc_pck_free_enable(bool enable);
 void dispc_enable_fifomerge(bool enable);
@@ -455,36 +389,14 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
 void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
                u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
                bool manual_update);
-int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
-               bool replication, const struct omap_video_timings *mgr_timings,
-               bool mem_to_mem);
-int dispc_ovl_enable(enum omap_plane plane, bool enable);
-void dispc_ovl_set_channel_out(enum omap_plane plane,
-               enum omap_channel channel);
-
-void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
-u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
-u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
-bool dispc_mgr_go_busy(enum omap_channel channel);
-void dispc_mgr_go(enum omap_channel channel);
-bool dispc_mgr_is_enabled(enum omap_channel channel);
-void dispc_mgr_enable(enum omap_channel channel, bool enable);
-bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
-void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
-void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
-void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
-void dispc_mgr_set_lcd_type_tft(enum omap_channel channel);
-void dispc_mgr_set_timings(enum omap_channel channel,
-               struct omap_video_timings *timings);
+
 unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
 unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
 unsigned long dispc_core_clk_rate(void);
 void dispc_mgr_set_clock_div(enum omap_channel channel,
-               struct dispc_clock_info *cinfo);
+               const struct dispc_clock_info *cinfo);
 int dispc_mgr_get_clock_div(enum omap_channel channel,
                struct dispc_clock_info *cinfo);
-void dispc_mgr_setup(enum omap_channel channel,
-               struct omap_overlay_manager_info *info);
 
 u32 dispc_wb_get_framedone_irq(void);
 bool dispc_wb_go_busy(void);
@@ -536,6 +448,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
 #endif
 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
+int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev);
+void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev);
 void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
                struct omap_video_timings *timings);
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
index acbc1e1efba3650aaccba2d86b000816973d23ba..18688c12e30d9e5399d732ce6d972d101ae46b55 100644 (file)
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 
 #include <video/omapdss.h>
-#include <plat/cpu.h>
 
 #include "dss.h"
 #include "dss_features.h"
@@ -430,8 +430,6 @@ static const struct dss_param_range omap2_dss_param_range[] = {
         * scaler cannot scale a image with width more than 768.
         */
        [FEAT_PARAM_LINEWIDTH]                  = { 1, 768 },
-       [FEAT_PARAM_MGR_WIDTH]                  = { 1, 2048 },
-       [FEAT_PARAM_MGR_HEIGHT]                 = { 1, 2048 },
 };
 
 static const struct dss_param_range omap3_dss_param_range[] = {
@@ -446,8 +444,6 @@ static const struct dss_param_range omap3_dss_param_range[] = {
        [FEAT_PARAM_DSI_FCK]                    = { 0, 173000000 },
        [FEAT_PARAM_DOWNSCALE]                  = { 1, 4 },
        [FEAT_PARAM_LINEWIDTH]                  = { 1, 1024 },
-       [FEAT_PARAM_MGR_WIDTH]                  = { 1, 2048 },
-       [FEAT_PARAM_MGR_HEIGHT]                 = { 1, 2048 },
 };
 
 static const struct dss_param_range omap4_dss_param_range[] = {
@@ -462,8 +458,6 @@ static const struct dss_param_range omap4_dss_param_range[] = {
        [FEAT_PARAM_DSI_FCK]                    = { 0, 170000000 },
        [FEAT_PARAM_DOWNSCALE]                  = { 1, 4 },
        [FEAT_PARAM_LINEWIDTH]                  = { 1, 2048 },
-       [FEAT_PARAM_MGR_WIDTH]                  = { 1, 2048 },
-       [FEAT_PARAM_MGR_HEIGHT]                 = { 1, 2048 },
 };
 
 static const struct dss_param_range omap5_dss_param_range[] = {
@@ -478,8 +472,6 @@ static const struct dss_param_range omap5_dss_param_range[] = {
        [FEAT_PARAM_DSI_FCK]                    = { 0, 170000000 },
        [FEAT_PARAM_DOWNSCALE]                  = { 1, 4 },
        [FEAT_PARAM_LINEWIDTH]                  = { 1, 2048 },
-       [FEAT_PARAM_MGR_WIDTH]                  = { 1, 2048 },
-       [FEAT_PARAM_MGR_HEIGHT]                 = { 1, 2048 },
 };
 
 static const enum dss_feat_id omap2_dss_feat_list[] = {
@@ -821,14 +813,25 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
        .audio_start            =       ti_hdmi_4xxx_audio_start,
        .audio_stop             =       ti_hdmi_4xxx_audio_stop,
        .audio_config           =       ti_hdmi_4xxx_audio_config,
+       .audio_get_dma_port     =       ti_hdmi_4xxx_audio_get_dma_port,
 #endif
 
 };
 
-void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data)
+void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data,
+               enum omapdss_version version)
 {
-       if (cpu_is_omap44xx())
+       switch (version) {
+       case OMAPDSS_VER_OMAP4430_ES1:
+       case OMAPDSS_VER_OMAP4430_ES2:
+       case OMAPDSS_VER_OMAP4:
                ip_data->ops = &omap4_hdmi_functions;
+               break;
+       default:
+               ip_data->ops = NULL;
+       }
+
+       WARN_ON(ip_data->ops == NULL);
 }
 #endif
 
@@ -837,11 +840,13 @@ int dss_feat_get_num_mgrs(void)
 {
        return omap_current_dss_features->num_mgrs;
 }
+EXPORT_SYMBOL(dss_feat_get_num_mgrs);
 
 int dss_feat_get_num_ovls(void)
 {
        return omap_current_dss_features->num_ovls;
 }
+EXPORT_SYMBOL(dss_feat_get_num_ovls);
 
 int dss_feat_get_num_wbs(void)
 {
@@ -862,16 +867,19 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
 {
        return omap_current_dss_features->supported_displays[channel];
 }
+EXPORT_SYMBOL(dss_feat_get_supported_displays);
 
 enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
 {
        return omap_current_dss_features->supported_outputs[channel];
 }
+EXPORT_SYMBOL(dss_feat_get_supported_outputs);
 
 enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
 {
        return omap_current_dss_features->supported_color_modes[plane];
 }
+EXPORT_SYMBOL(dss_feat_get_supported_color_modes);
 
 enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane)
 {
@@ -929,29 +937,44 @@ bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type)
        return omap_current_dss_features->supported_rotation_types & rot_type;
 }
 
-void dss_features_init(void)
+void dss_features_init(enum omapdss_version version)
 {
-       if (cpu_is_omap24xx())
+       switch (version) {
+       case OMAPDSS_VER_OMAP24xx:
                omap_current_dss_features = &omap2_dss_features;
-       else if (cpu_is_omap3630())
+               break;
+
+       case OMAPDSS_VER_OMAP34xx_ES1:
+       case OMAPDSS_VER_OMAP34xx_ES3:
+               omap_current_dss_features = &omap3430_dss_features;
+               break;
+
+       case OMAPDSS_VER_OMAP3630:
                omap_current_dss_features = &omap3630_dss_features;
-       else if (cpu_is_omap34xx()) {
-               if (soc_is_am35xx()) {
-                       omap_current_dss_features = &am35xx_dss_features;
-               } else {
-                       omap_current_dss_features = &omap3430_dss_features;
-               }
-       }
-       else if (omap_rev() == OMAP4430_REV_ES1_0)
+               break;
+
+       case OMAPDSS_VER_OMAP4430_ES1:
                omap_current_dss_features = &omap4430_es1_0_dss_features;
-       else if (omap_rev() == OMAP4430_REV_ES2_0 ||
-               omap_rev() == OMAP4430_REV_ES2_1 ||
-               omap_rev() == OMAP4430_REV_ES2_2)
+               break;
+
+       case OMAPDSS_VER_OMAP4430_ES2:
                omap_current_dss_features = &omap4430_es2_0_1_2_dss_features;
-       else if (cpu_is_omap44xx())
+               break;
+
+       case OMAPDSS_VER_OMAP4:
                omap_current_dss_features = &omap4_dss_features;
-       else if (soc_is_omap54xx())
+               break;
+
+       case OMAPDSS_VER_OMAP5:
                omap_current_dss_features = &omap5_dss_features;
-       else
+               break;
+
+       case OMAPDSS_VER_AM35xx:
+               omap_current_dss_features = &am35xx_dss_features;
+               break;
+
+       default:
                DSSWARN("Unsupported OMAP version");
+               break;
+       }
 }
index 9218113b5e88c2c5488acb2f989e06ff080cfe06..489b9bec4a6d5ceebbc0cc01caaf9b96b7583673 100644 (file)
@@ -98,19 +98,12 @@ enum dss_range_param {
        FEAT_PARAM_DSI_FCK,
        FEAT_PARAM_DOWNSCALE,
        FEAT_PARAM_LINEWIDTH,
-       FEAT_PARAM_MGR_WIDTH,
-       FEAT_PARAM_MGR_HEIGHT,
 };
 
 /* DSS Feature Functions */
-int dss_feat_get_num_mgrs(void);
-int dss_feat_get_num_ovls(void);
 int dss_feat_get_num_wbs(void);
 unsigned long dss_feat_get_param_min(enum dss_range_param param);
 unsigned long dss_feat_get_param_max(enum dss_range_param param);
-enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
-enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
-enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
 enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
 bool dss_feat_color_mode_supported(enum omap_plane plane,
                enum omap_color_mode color_mode);
@@ -123,8 +116,9 @@ bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type);
 
 bool dss_has_feature(enum dss_feat_id id);
 void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
-void dss_features_init(void);
+void dss_features_init(enum omapdss_version version);
 #if defined(CONFIG_OMAP4_DSS_HDMI)
-void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data);
+void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data,
+               enum omapdss_version version);
 #endif
 #endif
index 8c9b8b3b7f773cd41c00f78b923070f87c325f70..769d0828581ccfec1f350b49b8d1d791732e9b04 100644 (file)
@@ -60,6 +60,7 @@
 static struct {
        struct mutex lock;
        struct platform_device *pdev;
+
        struct hdmi_ip_data ip_data;
 
        struct clk *sys_clk;
@@ -295,6 +296,12 @@ static const struct hdmi_config vesa_timings[] = {
                        false, },
                { 0x55, HDMI_DVI },
        },
+       {
+               { 1920, 1200, 154000, 32, 48, 80, 6, 3, 26,
+                       OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
+                       false, },
+               { 0x44, HDMI_DVI },
+       },
 };
 
 static int hdmi_runtime_get(void)
@@ -333,13 +340,17 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev)
 
        DSSDBG("init_display\n");
 
-       dss_init_hdmi_ip_ops(&hdmi.ip_data);
+       dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
 
        if (hdmi.vdda_hdmi_dac_reg == NULL) {
                struct regulator *reg;
 
                reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
 
+               /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */
+               if (IS_ERR(reg))
+                       reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
+
                if (IS_ERR(reg)) {
                        DSSERR("can't get VDDA_HDMI_DAC regulator\n");
                        return PTR_ERR(reg);
@@ -355,7 +366,7 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev)
        return 0;
 }
 
-static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev)
+static void hdmi_uninit_display(struct omap_dss_device *dssdev)
 {
        DSSDBG("uninit_display\n");
 
@@ -398,7 +409,8 @@ static bool hdmi_timings_compare(struct omap_video_timings *timing1,
 {
        int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
 
-       if ((timing2->pixel_clock == timing1->pixel_clock) &&
+       if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) ==
+                       DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) &&
                (timing2->x_res == timing1->x_res) &&
                (timing2->y_res == timing1->y_res)) {
 
@@ -500,12 +512,9 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
        DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
 }
 
-static int hdmi_power_on(struct omap_dss_device *dssdev)
+static int hdmi_power_on_core(struct omap_dss_device *dssdev)
 {
        int r;
-       struct omap_video_timings *p;
-       struct omap_overlay_manager *mgr = dssdev->output->manager;
-       unsigned long phy;
 
        gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
        gpio_set_value(hdmi.ls_oe_gpio, 1);
@@ -521,6 +530,38 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
        if (r)
                goto err_runtime_get;
 
+       /* Make selection of HDMI in DSS */
+       dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
+
+       return 0;
+
+err_runtime_get:
+       regulator_disable(hdmi.vdda_hdmi_dac_reg);
+err_vdac_enable:
+       gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+       gpio_set_value(hdmi.ls_oe_gpio, 0);
+       return r;
+}
+
+static void hdmi_power_off_core(struct omap_dss_device *dssdev)
+{
+       hdmi_runtime_put();
+       regulator_disable(hdmi.vdda_hdmi_dac_reg);
+       gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+       gpio_set_value(hdmi.ls_oe_gpio, 0);
+}
+
+static int hdmi_power_on_full(struct omap_dss_device *dssdev)
+{
+       int r;
+       struct omap_video_timings *p;
+       struct omap_overlay_manager *mgr = dssdev->output->manager;
+       unsigned long phy;
+
+       r = hdmi_power_on_core(dssdev);
+       if (r)
+               return r;
+
        dss_mgr_disable(mgr);
 
        p = &hdmi.ip_data.cfg.timings;
@@ -548,17 +589,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 
        hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
 
-       /* Make selection of HDMI in DSS */
-       dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
-
-       /* Select the dispc clock source as PRCM clock, to ensure that it is not
-        * DSI PLL source as the clock selected by DSI PLL might not be
-        * sufficient for the resolution selected / that can be changed
-        * dynamically by user. This can be moved to single location , say
-        * Boardfile.
-        */
-       dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
-
        /* bypass TV gamma table */
        dispc_enable_gamma_table(0);
 
@@ -582,16 +612,11 @@ err_vid_enable:
 err_phy_enable:
        hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
 err_pll_enable:
-       hdmi_runtime_put();
-err_runtime_get:
-       regulator_disable(hdmi.vdda_hdmi_dac_reg);
-err_vdac_enable:
-       gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
-       gpio_set_value(hdmi.ls_oe_gpio, 0);
+       hdmi_power_off_core(dssdev);
        return -EIO;
 }
 
-static void hdmi_power_off(struct omap_dss_device *dssdev)
+static void hdmi_power_off_full(struct omap_dss_device *dssdev)
 {
        struct omap_overlay_manager *mgr = dssdev->output->manager;
 
@@ -600,12 +625,8 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
        hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
        hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
        hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
-       hdmi_runtime_put();
-
-       regulator_disable(hdmi.vdda_hdmi_dac_reg);
 
-       gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
-       gpio_set_value(hdmi.ls_oe_gpio, 0);
+       hdmi_power_off_core(dssdev);
 }
 
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -715,7 +736,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
                goto err0;
        }
 
-       r = hdmi_power_on(dssdev);
+       r = hdmi_power_on_full(dssdev);
        if (r) {
                DSSERR("failed to power on device\n");
                goto err1;
@@ -737,13 +758,48 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
 
        mutex_lock(&hdmi.lock);
 
-       hdmi_power_off(dssdev);
+       hdmi_power_off_full(dssdev);
 
        omap_dss_stop_device(dssdev);
 
        mutex_unlock(&hdmi.lock);
 }
 
+int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev)
+{
+       int r = 0;
+
+       DSSDBG("ENTER omapdss_hdmi_core_enable\n");
+
+       mutex_lock(&hdmi.lock);
+
+       hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
+
+       r = hdmi_power_on_core(dssdev);
+       if (r) {
+               DSSERR("failed to power on device\n");
+               goto err0;
+       }
+
+       mutex_unlock(&hdmi.lock);
+       return 0;
+
+err0:
+       mutex_unlock(&hdmi.lock);
+       return r;
+}
+
+void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev)
+{
+       DSSDBG("Enter omapdss_hdmi_core_disable\n");
+
+       mutex_lock(&hdmi.lock);
+
+       hdmi_power_off_core(dssdev);
+
+       mutex_unlock(&hdmi.lock);
+}
+
 static int hdmi_get_clocks(struct platform_device *pdev)
 {
        struct clk *clk;
@@ -912,7 +968,7 @@ int hdmi_audio_config(struct omap_dss_audio *audio)
 static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev)
 {
        struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-       const char *def_disp_name = dss_get_default_display_name();
+       const char *def_disp_name = omapdss_get_default_display_name();
        struct omap_dss_device *def_dssdev;
        int i;
 
@@ -970,9 +1026,19 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
                return;
        }
 
+       r = omapdss_output_set_device(&hdmi.output, dssdev);
+       if (r) {
+               DSSERR("failed to connect output to new device: %s\n",
+                               dssdev->name);
+               dss_put_device(dssdev);
+               return;
+       }
+
        r = dss_add_device(dssdev);
        if (r) {
                DSSERR("device %s register failed: %d\n", dssdev->name, r);
+               omapdss_output_unset_device(&hdmi.output);
+               hdmi_uninit_display(dssdev);
                dss_put_device(dssdev);
                return;
        }
@@ -999,22 +1065,22 @@ static void __exit hdmi_uninit_output(struct platform_device *pdev)
 /* HDMI HW IP initialisation */
 static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 {
-       struct resource *hdmi_mem;
+       struct resource *res;
        int r;
 
        hdmi.pdev = pdev;
 
        mutex_init(&hdmi.lock);
+       mutex_init(&hdmi.ip_data.lock);
 
-       hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
-       if (!hdmi_mem) {
+       res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
+       if (!res) {
                DSSERR("can't get IORESOURCE_MEM HDMI\n");
                return -EINVAL;
        }
 
        /* Base address taken from platform */
-       hdmi.ip_data.base_wp = ioremap(hdmi_mem->start,
-                                               resource_size(hdmi_mem));
+       hdmi.ip_data.base_wp = devm_request_and_ioremap(&pdev->dev, res);
        if (!hdmi.ip_data.base_wp) {
                DSSERR("can't ioremap WP\n");
                return -ENOMEM;
@@ -1022,7 +1088,7 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 
        r = hdmi_get_clocks(pdev);
        if (r) {
-               iounmap(hdmi.ip_data.base_wp);
+               DSSERR("can't get clocks\n");
                return r;
        }
 
@@ -1033,9 +1099,11 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
        hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
        hdmi.ip_data.phy_offset = HDMI_PHY;
 
-       mutex_init(&hdmi.ip_data.lock);
-
-       hdmi_panel_init();
+       r = hdmi_panel_init();
+       if (r) {
+               DSSERR("can't init panel\n");
+               goto err_panel_init;
+       }
 
        dss_debugfs_create_file("hdmi", hdmi_dump_regs);
 
@@ -1044,6 +1112,10 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
        hdmi_probe_pdata(pdev);
 
        return 0;
+
+err_panel_init:
+       hdmi_put_clocks();
+       return r;
 }
 
 static int __exit hdmi_remove_child(struct device *dev, void *data)
@@ -1067,8 +1139,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
 
        hdmi_put_clocks();
 
-       iounmap(hdmi.ip_data.base_wp);
-
        return 0;
 }
 
index 69fb115bab32928d7ce58574cb0120020b5720fe..dfb8eda81b61d85169e55b424fa92dbc5a7ce8c5 100644 (file)
@@ -280,58 +280,6 @@ static void hdmi_panel_disable(struct omap_dss_device *dssdev)
        mutex_unlock(&hdmi.lock);
 }
 
-static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
-{
-       int r = 0;
-
-       mutex_lock(&hdmi.lock);
-
-       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
-               r = -EINVAL;
-               goto err;
-       }
-
-       /*
-        * TODO: notify audio users that the display was suspended. For now,
-        * disable audio locally to not break our audio state machine.
-        */
-       hdmi_panel_audio_disable(dssdev);
-
-       dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-       omapdss_hdmi_display_disable(dssdev);
-
-err:
-       mutex_unlock(&hdmi.lock);
-
-       return r;
-}
-
-static int hdmi_panel_resume(struct omap_dss_device *dssdev)
-{
-       int r = 0;
-
-       mutex_lock(&hdmi.lock);
-
-       if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
-               r = -EINVAL;
-               goto err;
-       }
-
-       r = omapdss_hdmi_display_enable(dssdev);
-       if (r) {
-               DSSERR("failed to power on\n");
-               goto err;
-       }
-       /* TODO: notify audio users that the panel resumed. */
-
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-err:
-       mutex_unlock(&hdmi.lock);
-
-       return r;
-}
-
 static void hdmi_get_timings(struct omap_dss_device *dssdev,
                        struct omap_video_timings *timings)
 {
@@ -379,20 +327,22 @@ static int hdmi_check_timings(struct omap_dss_device *dssdev,
 static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
 {
        int r;
+       bool need_enable;
 
        mutex_lock(&hdmi.lock);
 
-       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
-               r = omapdss_hdmi_display_enable(dssdev);
+       need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED;
+
+       if (need_enable) {
+               r = omapdss_hdmi_core_enable(dssdev);
                if (r)
                        goto err;
        }
 
        r = omapdss_hdmi_read_edid(buf, len);
 
-       if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
-                       dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
-               omapdss_hdmi_display_disable(dssdev);
+       if (need_enable)
+               omapdss_hdmi_core_disable(dssdev);
 err:
        mutex_unlock(&hdmi.lock);
 
@@ -402,20 +352,22 @@ err:
 static bool hdmi_detect(struct omap_dss_device *dssdev)
 {
        int r;
+       bool need_enable;
 
        mutex_lock(&hdmi.lock);
 
-       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
-               r = omapdss_hdmi_display_enable(dssdev);
+       need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED;
+
+       if (need_enable) {
+               r = omapdss_hdmi_core_enable(dssdev);
                if (r)
                        goto err;
        }
 
        r = omapdss_hdmi_detect();
 
-       if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
-                       dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
-               omapdss_hdmi_display_disable(dssdev);
+       if (need_enable)
+               omapdss_hdmi_core_disable(dssdev);
 err:
        mutex_unlock(&hdmi.lock);
 
@@ -427,8 +379,6 @@ static struct omap_dss_driver hdmi_driver = {
        .remove         = hdmi_panel_remove,
        .enable         = hdmi_panel_enable,
        .disable        = hdmi_panel_disable,
-       .suspend        = hdmi_panel_suspend,
-       .resume         = hdmi_panel_resume,
        .get_timings    = hdmi_get_timings,
        .set_timings    = hdmi_set_timings,
        .check_timings  = hdmi_check_timings,
@@ -454,9 +404,7 @@ int hdmi_panel_init(void)
        spin_lock_init(&hdmi.audio_lock);
 #endif
 
-       omap_dss_register_driver(&hdmi_driver);
-
-       return 0;
+       return omap_dss_register_driver(&hdmi_driver);
 }
 
 void hdmi_panel_exit(void)
index c54d2f620ce3e5d94c4fb65ef39fb4fd150c44ab..2551eaa14c42537fb8ed38464b68eb42b0259b85 100644 (file)
 static int num_managers;
 static struct omap_overlay_manager *managers;
 
-static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
-{
-       return mgr->output ? mgr->output->device : NULL;
-}
-
-static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
-{
-       unsigned long timeout = msecs_to_jiffies(500);
-       struct omap_dss_device *dssdev = mgr->get_device(mgr);
-       u32 irq;
-       int r;
-
-       r = dispc_runtime_get();
-       if (r)
-               return r;
-
-       if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
-               irq = DISPC_IRQ_EVSYNC_ODD;
-       else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
-               irq = DISPC_IRQ_EVSYNC_EVEN;
-       else
-               irq = dispc_mgr_get_vsync_irq(mgr->id);
-
-       r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
-
-       dispc_runtime_put();
-
-       return r;
-}
-
 int dss_init_overlay_managers(struct platform_device *pdev)
 {
        int i, r;
@@ -99,15 +69,6 @@ int dss_init_overlay_managers(struct platform_device *pdev)
                        break;
                }
 
-               mgr->set_output = &dss_mgr_set_output;
-               mgr->unset_output = &dss_mgr_unset_output;
-               mgr->apply = &omap_dss_mgr_apply;
-               mgr->set_manager_info = &dss_mgr_set_info;
-               mgr->get_manager_info = &dss_mgr_get_info;
-               mgr->wait_for_go = &dss_mgr_wait_for_go;
-               mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
-               mgr->get_device = &dss_mgr_get_device;
-
                mgr->caps = 0;
                mgr->supported_displays =
                        dss_feat_get_supported_displays(mgr->id);
index 813f26682b7a836f127449517f9ed82dd2c33dac..79dea1a1a7320a6f4198891b10172ee10f7afe6b 100644 (file)
@@ -114,35 +114,67 @@ struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
        return NULL;
 }
 
-struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev)
+static const struct dss_mgr_ops *dss_mgr_ops;
+
+int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops)
 {
-       struct omap_dss_output *out = NULL;
-       enum omap_dss_output_id id;
-
-       switch (dssdev->type) {
-       case OMAP_DISPLAY_TYPE_DPI:
-               out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
-               break;
-       case OMAP_DISPLAY_TYPE_DBI:
-               out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
-               break;
-       case OMAP_DISPLAY_TYPE_SDI:
-               out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
-               break;
-       case OMAP_DISPLAY_TYPE_VENC:
-               out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
-               break;
-       case OMAP_DISPLAY_TYPE_HDMI:
-               out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
-               break;
-       case OMAP_DISPLAY_TYPE_DSI:
-               id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 :
-                                       OMAP_DSS_OUTPUT_DSI2;
-               out = omap_dss_get_output(id);
-               break;
-       default:
-               break;
-       }
+       if (dss_mgr_ops)
+               return -EBUSY;
+
+       dss_mgr_ops = mgr_ops;
+
+       return 0;
+}
+EXPORT_SYMBOL(dss_install_mgr_ops);
+
+void dss_uninstall_mgr_ops(void)
+{
+       dss_mgr_ops = NULL;
+}
+EXPORT_SYMBOL(dss_uninstall_mgr_ops);
+
+void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
+               const struct omap_video_timings *timings)
+{
+       dss_mgr_ops->set_timings(mgr, timings);
+}
+EXPORT_SYMBOL(dss_mgr_set_timings);
+
+void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
+               const struct dss_lcd_mgr_config *config)
+{
+       dss_mgr_ops->set_lcd_config(mgr, config);
+}
+EXPORT_SYMBOL(dss_mgr_set_lcd_config);
+
+int dss_mgr_enable(struct omap_overlay_manager *mgr)
+{
+       return dss_mgr_ops->enable(mgr);
+}
+EXPORT_SYMBOL(dss_mgr_enable);
+
+void dss_mgr_disable(struct omap_overlay_manager *mgr)
+{
+       dss_mgr_ops->disable(mgr);
+}
+EXPORT_SYMBOL(dss_mgr_disable);
 
-       return out;
+void dss_mgr_start_update(struct omap_overlay_manager *mgr)
+{
+       dss_mgr_ops->start_update(mgr);
+}
+EXPORT_SYMBOL(dss_mgr_start_update);
+
+int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
+               void (*handler)(void *), void *data)
+{
+       return dss_mgr_ops->register_framedone_handler(mgr, handler, data);
+}
+EXPORT_SYMBOL(dss_mgr_register_framedone_handler);
+
+void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
+               void (*handler)(void *), void *data)
+{
+       dss_mgr_ops->unregister_framedone_handler(mgr, handler, data);
 }
+EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler);
index 45f4994bc6b06b64056db0cc9a7075532757bdc3..eccde322c28a53b72bece7945a809a5ddd6f843a 100644 (file)
 static int num_overlays;
 static struct omap_overlay *overlays;
 
-static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
-{
-       return ovl->manager ?
-               (ovl->manager->output ? ovl->manager->output->device : NULL) :
-               NULL;
-}
-
 int omap_dss_get_num_overlays(void)
 {
        return num_overlays;
@@ -93,16 +86,6 @@ void dss_init_overlays(struct platform_device *pdev)
                        break;
                }
 
-               ovl->is_enabled = &dss_ovl_is_enabled;
-               ovl->enable = &dss_ovl_enable;
-               ovl->disable = &dss_ovl_disable;
-               ovl->set_manager = &dss_ovl_set_manager;
-               ovl->unset_manager = &dss_ovl_unset_manager;
-               ovl->set_overlay_info = &dss_ovl_set_info;
-               ovl->get_overlay_info = &dss_ovl_get_info;
-               ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
-               ovl->get_device = &dss_ovl_get_device;
-
                ovl->caps = dss_feat_get_overlay_caps(ovl->id);
                ovl->supported_modes =
                        dss_feat_get_supported_color_modes(ovl->id);
index 7282e5af3e1a2e2458605c5a6f76b7d371269be3..e903dd3f54d9466e802126e3801ac0c86dc10d4c 100644 (file)
@@ -342,7 +342,7 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
        return 0;
 }
 
-static void framedone_callback(void *data, u32 mask)
+static void framedone_callback(void *data)
 {
        void (*callback)(void *data);
 
@@ -908,8 +908,8 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
                goto err0;
        }
 
-       r = omap_dispc_register_isr(framedone_callback, NULL,
-                       DISPC_IRQ_FRAMEDONE);
+       r = dss_mgr_register_framedone_handler(out->manager,
+                       framedone_callback, NULL);
        if (r) {
                DSSERR("can't get FRAMEDONE irq\n");
                goto err1;
@@ -933,8 +933,10 @@ EXPORT_SYMBOL(omapdss_rfbi_display_enable);
 
 void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
 {
-       omap_dispc_unregister_isr(framedone_callback, NULL,
-                       DISPC_IRQ_FRAMEDONE);
+       struct omap_dss_output *out = dssdev->output;
+
+       dss_mgr_unregister_framedone_handler(out->manager,
+                       framedone_callback, NULL);
        omap_dss_stop_device(dssdev);
 
        rfbi_runtime_put();
@@ -950,7 +952,7 @@ static int __init rfbi_init_display(struct omap_dss_device *dssdev)
 static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev)
 {
        struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-       const char *def_disp_name = dss_get_default_display_name();
+       const char *def_disp_name = omapdss_get_default_display_name();
        struct omap_dss_device *def_dssdev;
        int i;
 
@@ -999,9 +1001,18 @@ static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
                return;
        }
 
+       r = omapdss_output_set_device(&rfbi.output, dssdev);
+       if (r) {
+               DSSERR("failed to connect output to new device: %s\n",
+                               dssdev->name);
+               dss_put_device(dssdev);
+               return;
+       }
+
        r = dss_add_device(dssdev);
        if (r) {
                DSSERR("device %s register failed: %d\n", dssdev->name, r);
+               omapdss_output_unset_device(&rfbi.output);
                dss_put_device(dssdev);
                return;
        }
index 7760851f6e5d5ad5dc9adcc3b540ee4f2f5301d2..62b5374ce438f3ff7e4db23d4ad5c6d5165456cd 100644 (file)
@@ -205,7 +205,7 @@ static int __init sdi_init_display(struct omap_dss_device *dssdev)
 static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev)
 {
        struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-       const char *def_disp_name = dss_get_default_display_name();
+       const char *def_disp_name = omapdss_get_default_display_name();
        struct omap_dss_device *def_dssdev;
        int i;
 
@@ -254,9 +254,18 @@ static void __init sdi_probe_pdata(struct platform_device *sdidev)
                return;
        }
 
+       r = omapdss_output_set_device(&sdi.output, dssdev);
+       if (r) {
+               DSSERR("failed to connect output to new device: %s\n",
+                               dssdev->name);
+               dss_put_device(dssdev);
+               return;
+       }
+
        r = dss_add_device(dssdev);
        if (r) {
                DSSERR("device %s register failed: %d\n", dssdev->name, r);
+               omapdss_output_unset_device(&sdi.output);
                dss_put_device(dssdev);
                return;
        }
index b046c208cb9708fc30db861759c6a2cf01fde3be..216aa704f9d72ef08b06a82865d5b8fda03cc876 100644 (file)
@@ -102,6 +102,8 @@ struct ti_hdmi_ip_ops {
 
        int (*audio_config)(struct hdmi_ip_data *ip_data,
                struct omap_dss_audio *audio);
+
+       int (*audio_get_dma_port)(u32 *offset, u32 *size);
 #endif
 
 };
@@ -183,5 +185,6 @@ int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data);
 void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data);
 int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data,
                struct omap_dss_audio *audio);
+int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size);
 #endif
 #endif
index c23b85a20cdc5b84cd6aeec9743a4f931a9470a2..e18b222ed739081819c35ef6276e7b7094068fa4 100644 (file)
@@ -899,7 +899,7 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)
 #define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\
                hdmi_read_reg(hdmi_av_base(ip_data), r))
 #define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \
-               (i < 10) ? 32 - strlen(#r) : 31 - strlen(#r), " ", \
+               (i < 10) ? 32 - (int)strlen(#r) : 31 - (int)strlen(#r), " ", \
                hdmi_read_reg(hdmi_av_base(ip_data), CORE_REG(i, r)))
 
        DUMPCORE(HDMI_CORE_SYS_VND_IDL);
@@ -1418,4 +1418,13 @@ void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data)
        REG_FLD_MOD(hdmi_wp_base(ip_data),
                    HDMI_WP_AUDIO_CTRL, false, 30, 30);
 }
+
+int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size)
+{
+       if (!offset || !size)
+               return -EINVAL;
+       *offset = HDMI_WP_AUDIO_DATA;
+       *size = 4;
+       return 0;
+}
 #endif
index 56efa3bb465d1ef4dd8011b89ead18ae36e41e03..006caf3cb509778d472d0a28d528cc3bde16748e 100644 (file)
@@ -744,7 +744,7 @@ static void venc_put_clocks(void)
 static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev)
 {
        struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-       const char *def_disp_name = dss_get_default_display_name();
+       const char *def_disp_name = omapdss_get_default_display_name();
        struct omap_dss_device *def_dssdev;
        int i;
 
@@ -795,9 +795,18 @@ static void __init venc_probe_pdata(struct platform_device *vencdev)
                return;
        }
 
+       r = omapdss_output_set_device(&venc.output, dssdev);
+       if (r) {
+               DSSERR("failed to connect output to new device: %s\n",
+                               dssdev->name);
+               dss_put_device(dssdev);
+               return;
+       }
+
        r = dss_add_device(dssdev);
        if (r) {
                DSSERR("device %s register failed: %d\n", dssdev->name, r);
+               omapdss_output_unset_device(&venc.output);
                dss_put_device(dssdev);
                return;
        }
index d55b8784ecfde6ddfa184a6d86f5a5d659f5b9c4..0d2b1a0834a0cb17dc4902db8c74273d319c6d5b 100644 (file)
@@ -157,12 +157,6 @@ static void venc_panel_disable(struct omap_dss_device *dssdev)
        if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
                goto end;
 
-       if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
-               /* suspended is the same as disabled with venc */
-               dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-               goto end;
-       }
-
        omapdss_venc_display_disable(dssdev);
 
        dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
@@ -170,17 +164,6 @@ end:
        mutex_unlock(&venc_panel.lock);
 }
 
-static int venc_panel_suspend(struct omap_dss_device *dssdev)
-{
-       venc_panel_disable(dssdev);
-       return 0;
-}
-
-static int venc_panel_resume(struct omap_dss_device *dssdev)
-{
-       return venc_panel_enable(dssdev);
-}
-
 static void venc_panel_set_timings(struct omap_dss_device *dssdev,
                struct omap_video_timings *timings)
 {
@@ -222,8 +205,6 @@ static struct omap_dss_driver venc_driver = {
 
        .enable         = venc_panel_enable,
        .disable        = venc_panel_disable,
-       .suspend        = venc_panel_suspend,
-       .resume         = venc_panel_resume,
 
        .get_resolution = omapdss_default_get_resolution,
        .get_recommended_bpp = omapdss_default_get_recommended_bpp,
index 4ea17dc3258c02d056fe838245c37f4cf8a9c9e1..4cb12ce68855ae998644a8454e8802494173659a 100644 (file)
@@ -2,7 +2,6 @@ menuconfig FB_OMAP2
         tristate "OMAP2+ frame buffer support"
         depends on FB && OMAP2_DSS && !DRM_OMAP
 
-       select OMAP2_VRAM
        select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
         select FB_CFB_FILLRECT
         select FB_CFB_COPYAREA
index d630b26a005c7ae2e0bea55b1c0a644fc64ad1e9..d30b45d7264972590a4cf39a9131cc619eb9fbb2 100644 (file)
 #include <linux/omapfb.h>
 #include <linux/vmalloc.h>
 #include <linux/export.h>
+#include <linux/sizes.h>
 
 #include <video/omapdss.h>
-#include <plat/vrfb.h>
-#include <plat/vram.h>
+#include <video/omapvrfb.h>
 
 #include "omapfb.h"
 
@@ -211,6 +211,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
 {
        struct omapfb_info *ofbi = FB2OFB(fbi);
        struct omapfb2_device *fbdev = ofbi->fbdev;
+       struct omap_dss_device *display = fb2display(fbi);
        struct omapfb2_mem_region *rg;
        int r = 0, i;
        size_t size;
@@ -220,6 +221,9 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
 
        size = PAGE_ALIGN(mi->size);
 
+       if (display && display->driver->sync)
+               display->driver->sync(display);
+
        rg = ofbi->region;
 
        down_write_nested(&rg->lock, rg->id);
@@ -279,7 +283,7 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
        return 0;
 }
 
-static int omapfb_update_window_nolock(struct fb_info *fbi,
+static int omapfb_update_window(struct fb_info *fbi,
                u32 x, u32 y, u32 w, u32 h)
 {
        struct omap_dss_device *display = fb2display(fbi);
@@ -299,27 +303,6 @@ static int omapfb_update_window_nolock(struct fb_info *fbi,
        return display->driver->update(display, x, y, w, h);
 }
 
-/* This function is exported for SGX driver use */
-int omapfb_update_window(struct fb_info *fbi,
-               u32 x, u32 y, u32 w, u32 h)
-{
-       struct omapfb_info *ofbi = FB2OFB(fbi);
-       struct omapfb2_device *fbdev = ofbi->fbdev;
-       int r;
-
-       if (!lock_fb_info(fbi))
-               return -ENODEV;
-       omapfb_lock(fbdev);
-
-       r = omapfb_update_window_nolock(fbi, x, y, w, h);
-
-       omapfb_unlock(fbdev);
-       unlock_fb_info(fbi);
-
-       return r;
-}
-EXPORT_SYMBOL(omapfb_update_window);
-
 int omapfb_set_update_mode(struct fb_info *fbi,
                                   enum omapfb_update_mode mode)
 {
@@ -646,7 +629,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
                        break;
                }
 
-               r = omapfb_update_window_nolock(fbi, p.uwnd_o.x, p.uwnd_o.y,
+               r = omapfb_update_window(fbi, p.uwnd_o.x, p.uwnd_o.y,
                                p.uwnd_o.width, p.uwnd_o.height);
                break;
 
@@ -663,7 +646,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
                        break;
                }
 
-               r = omapfb_update_window_nolock(fbi, p.uwnd.x, p.uwnd.y,
+               r = omapfb_update_window(fbi, p.uwnd.x, p.uwnd.y,
                                p.uwnd.width, p.uwnd.height);
                break;
 
@@ -853,14 +836,15 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
                break;
 
        case OMAPFB_GET_VRAM_INFO: {
-               unsigned long vram, free, largest;
-
                DBG("ioctl GET_VRAM_INFO\n");
 
-               omap_vram_get_info(&vram, &free, &largest);
-               p.vram_info.total = vram;
-               p.vram_info.free = free;
-               p.vram_info.largest_free_block = largest;
+               /*
+                * We don't have the ability to get this vram info anymore.
+                * Fill in something that should keep the applications working.
+                */
+               p.vram_info.total = SZ_1M * 64;
+               p.vram_info.free = SZ_1M * 64;
+               p.vram_info.largest_free_block = SZ_1M * 64;
 
                if (copy_to_user((void __user *)arg, &p.vram_info,
                                        sizeof(p.vram_info)))
index 16db1589bd9180a01920078f156b3650971b2311..ca585ef37f2528d36d0534200a911db95b07baff 100644 (file)
@@ -31,9 +31,7 @@
 #include <linux/omapfb.h>
 
 #include <video/omapdss.h>
-#include <plat/cpu.h>
-#include <plat/vram.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
 
 #include "omapfb.h"
 
@@ -1259,11 +1257,10 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
 
        switch (blank) {
        case FB_BLANK_UNBLANK:
-               if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
+               if (display->state == OMAP_DSS_DISPLAY_ACTIVE)
                        goto exit;
 
-               if (display->driver->resume)
-                       r = display->driver->resume(display);
+               r = display->driver->enable(display);
 
                if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) &&
                                d->update_mode == OMAPFB_AUTO_UPDATE &&
@@ -1284,8 +1281,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
                if (d->auto_update_work_enabled)
                        omapfb_stop_auto_update(fbdev, display);
 
-               if (display->driver->suspend)
-                       r = display->driver->suspend(display);
+               display->driver->disable(display);
 
                break;
 
@@ -1336,24 +1332,25 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
 
        rg = ofbi->region;
 
-       WARN_ON(atomic_read(&rg->map_count));
-
-       if (rg->paddr)
-               if (omap_vram_free(rg->paddr, rg->size))
-                       dev_err(fbdev->dev, "VRAM FREE failed\n");
+       if (rg->token == NULL)
+               return;
 
-       if (rg->vaddr)
-               iounmap(rg->vaddr);
+       WARN_ON(atomic_read(&rg->map_count));
 
        if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
                /* unmap the 0 angle rotation */
                if (rg->vrfb.vaddr[0]) {
                        iounmap(rg->vrfb.vaddr[0]);
-                       omap_vrfb_release_ctx(&rg->vrfb);
                        rg->vrfb.vaddr[0] = NULL;
                }
+
+               omap_vrfb_release_ctx(&rg->vrfb);
        }
 
+       dma_free_attrs(fbdev->dev, rg->size, rg->token, rg->dma_handle,
+                       &rg->attrs);
+
+       rg->token = NULL;
        rg->vaddr = NULL;
        rg->paddr = 0;
        rg->alloc = 0;
@@ -1388,7 +1385,9 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
        struct omapfb_info *ofbi = FB2OFB(fbi);
        struct omapfb2_device *fbdev = ofbi->fbdev;
        struct omapfb2_mem_region *rg;
-       void __iomem *vaddr;
+       void *token;
+       DEFINE_DMA_ATTRS(attrs);
+       dma_addr_t dma_handle;
        int r;
 
        rg = ofbi->region;
@@ -1403,42 +1402,40 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
 
        size = PAGE_ALIGN(size);
 
-       if (!paddr) {
-               DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
-               r = omap_vram_alloc(size, &paddr);
-       } else {
-               DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
-                               ofbi->id);
-               r = omap_vram_reserve(paddr, size);
-       }
+       dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
 
-       if (r) {
+       if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
+               dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
+
+       DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
+
+       token = dma_alloc_attrs(fbdev->dev, size, &dma_handle,
+                       GFP_KERNEL, &attrs);
+
+       if (token == NULL) {
                dev_err(fbdev->dev, "failed to allocate framebuffer\n");
                return -ENOMEM;
        }
 
-       if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) {
-               vaddr = ioremap_wc(paddr, size);
-
-               if (!vaddr) {
-                       dev_err(fbdev->dev, "failed to ioremap framebuffer\n");
-                       omap_vram_free(paddr, size);
-                       return -ENOMEM;
-               }
+       DBG("allocated VRAM paddr %lx, vaddr %p\n",
+                       (unsigned long)dma_handle, token);
 
-               DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr);
-       } else {
+       if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
                r = omap_vrfb_request_ctx(&rg->vrfb);
                if (r) {
+                       dma_free_attrs(fbdev->dev, size, token, dma_handle,
+                                       &attrs);
                        dev_err(fbdev->dev, "vrfb create ctx failed\n");
                        return r;
                }
-
-               vaddr = NULL;
        }
 
-       rg->paddr = paddr;
-       rg->vaddr = vaddr;
+       rg->attrs = attrs;
+       rg->token = token;
+       rg->dma_handle = dma_handle;
+
+       rg->paddr = (unsigned long)dma_handle;
+       rg->vaddr = (void __iomem *)token;
        rg->size = size;
        rg->alloc = 1;
 
@@ -1532,6 +1529,9 @@ static int omapfb_parse_vram_param(const char *param, int max_entries,
 
                }
 
+               WARN_ONCE(paddr,
+                       "reserving memory at predefined address not supported\n");
+
                paddrs[fbnum] = paddr;
                sizes[fbnum] = size;
 
@@ -1611,7 +1611,6 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
 {
        struct omapfb_info *ofbi = FB2OFB(fbi);
        struct omapfb2_device *fbdev = ofbi->fbdev;
-       struct omap_dss_device *display = fb2display(fbi);
        struct omapfb2_mem_region *rg = ofbi->region;
        unsigned long old_size = rg->size;
        unsigned long old_paddr = rg->paddr;
@@ -1626,9 +1625,6 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
        if (old_size == size && old_type == type)
                return 0;
 
-       if (display && display->driver->sync)
-                       display->driver->sync(display);
-
        omapfb_free_fbmem(fbi);
 
        if (size == 0) {
@@ -1883,7 +1879,6 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
        }
 
        dev_set_drvdata(fbdev->dev, NULL);
-       kfree(fbdev);
 }
 
 static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
@@ -2259,26 +2254,28 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
 {
        struct fb_monspecs *specs;
        u8 *edid;
-       int r, i, best_xres, best_idx, len;
+       int r, i, best_idx, len;
 
        if (!display->driver->read_edid)
                return -ENODEV;
 
        len = 0x80 * 2;
        edid = kmalloc(len, GFP_KERNEL);
+       if (edid == NULL)
+               return -ENOMEM;
 
        r = display->driver->read_edid(display, edid, len);
        if (r < 0)
                goto err1;
 
        specs = kzalloc(sizeof(*specs), GFP_KERNEL);
+       if (specs == NULL) {
+               r = -ENOMEM;
+               goto err1;
+       }
 
        fb_edid_to_monspecs(edid, specs);
 
-       if (edid[126] > 0)
-               fb_edid_add_monspecs(edid + 0x80, specs);
-
-       best_xres = 0;
        best_idx = -1;
 
        for (i = 0; i < specs->modedb_len; ++i) {
@@ -2294,16 +2291,20 @@ static int omapfb_find_best_mode(struct omap_dss_device *display,
                if (m->xres == 2880 || m->xres == 1440)
                        continue;
 
+               if (m->vmode & FB_VMODE_INTERLACED ||
+                               m->vmode & FB_VMODE_DOUBLE)
+                       continue;
+
                fb_videomode_to_omap_timings(m, display, &t);
 
                r = display->driver->check_timings(display, &t);
-               if (r == 0 && best_xres < m->xres) {
-                       best_xres = m->xres;
+               if (r == 0) {
                        best_idx = i;
+                       break;
                }
        }
 
-       if (best_xres == 0) {
+       if (best_idx == -1) {
                r = -ENOENT;
                goto err2;
        }
@@ -2372,15 +2373,62 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
        return 0;
 }
 
+static int omapfb_init_connections(struct omapfb2_device *fbdev,
+               struct omap_dss_device *def_dssdev)
+{
+       int i, r;
+       struct omap_overlay_manager *mgr;
+
+       if (!def_dssdev->output) {
+               dev_err(fbdev->dev, "no output for the default display\n");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < fbdev->num_displays; ++i) {
+               struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
+               struct omap_dss_output *out = dssdev->output;
+
+               mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+               if (!mgr || !out)
+                       continue;
+
+               if (mgr->output)
+                       mgr->unset_output(mgr);
+
+               mgr->set_output(mgr, out);
+       }
+
+       mgr = def_dssdev->output->manager;
+
+       if (!mgr) {
+               dev_err(fbdev->dev, "no ovl manager for the default display\n");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < fbdev->num_overlays; i++) {
+               struct omap_overlay *ovl = fbdev->overlays[i];
+
+               if (ovl->manager)
+                       ovl->unset_manager(ovl);
+
+               r = ovl->set_manager(ovl, mgr);
+               if (r)
+                       dev_warn(fbdev->dev,
+                                       "failed to connect overlay %s to manager %s\n",
+                                       ovl->name, mgr->name);
+       }
+
+       return 0;
+}
+
 static int __init omapfb_probe(struct platform_device *pdev)
 {
        struct omapfb2_device *fbdev = NULL;
        int r = 0;
        int i;
-       struct omap_overlay *ovl;
        struct omap_dss_device *def_display;
        struct omap_dss_device *dssdev;
-       struct omap_dss_device *ovl_device;
 
        DBG("omapfb_probe\n");
 
@@ -2390,28 +2438,28 @@ static int __init omapfb_probe(struct platform_device *pdev)
                goto err0;
        }
 
-       fbdev = kzalloc(sizeof(struct omapfb2_device), GFP_KERNEL);
+       fbdev = devm_kzalloc(&pdev->dev, sizeof(struct omapfb2_device),
+                       GFP_KERNEL);
        if (fbdev == NULL) {
                r = -ENOMEM;
                goto err0;
        }
 
-       /* TODO : Replace cpu check with omap_has_vrfb once HAS_FEATURE
-       *        available for OMAP2 and OMAP3
-       */
-       if (def_vrfb && !cpu_is_omap24xx() && !cpu_is_omap34xx()) {
+       if (def_vrfb && !omap_vrfb_supported()) {
                def_vrfb = 0;
                dev_warn(&pdev->dev, "VRFB is not supported on this hardware, "
                                "ignoring the module parameter vrfb=y\n");
        }
 
+       r = omapdss_compat_init();
+       if (r)
+               goto err0;
 
        mutex_init(&fbdev->mtx);
 
        fbdev->dev = &pdev->dev;
        platform_set_drvdata(pdev, fbdev);
 
-       r = 0;
        fbdev->num_displays = 0;
        dssdev = NULL;
        for_each_dss_dev(dssdev) {
@@ -2434,9 +2482,6 @@ static int __init omapfb_probe(struct platform_device *pdev)
                        d->update_mode = OMAPFB_AUTO_UPDATE;
        }
 
-       if (r)
-               goto cleanup;
-
        if (fbdev->num_displays == 0) {
                dev_err(&pdev->dev, "no displays\n");
                r = -EINVAL;
@@ -2451,15 +2496,33 @@ static int __init omapfb_probe(struct platform_device *pdev)
        for (i = 0; i < fbdev->num_managers; i++)
                fbdev->managers[i] = omap_dss_get_overlay_manager(i);
 
-       /* gfx overlay should be the default one. find a display
-        * connected to that, and use it as default display */
-       ovl = omap_dss_get_overlay(0);
-       ovl_device = ovl->get_device(ovl);
-       if (ovl_device) {
-               def_display = ovl_device;
-       } else {
-               dev_warn(&pdev->dev, "cannot find default display\n");
-               def_display = NULL;
+       def_display = NULL;
+
+       for (i = 0; i < fbdev->num_displays; ++i) {
+               struct omap_dss_device *dssdev;
+               const char *def_name;
+
+               def_name = omapdss_get_default_display_name();
+
+               dssdev = fbdev->displays[i].dssdev;
+
+               if (def_name == NULL ||
+                       (dssdev->name && strcmp(def_name, dssdev->name) == 0)) {
+                       def_display = dssdev;
+                       break;
+               }
+       }
+
+       if (def_display == NULL) {
+               dev_err(fbdev->dev, "failed to find default display\n");
+               r = -EINVAL;
+               goto cleanup;
+       }
+
+       r = omapfb_init_connections(fbdev, def_display);
+       if (r) {
+               dev_err(fbdev->dev, "failed to init overlay connections\n");
+               goto cleanup;
        }
 
        if (def_mode && strlen(def_mode) > 0) {
@@ -2510,6 +2573,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
 
 cleanup:
        omapfb_free_resources(fbdev);
+       omapdss_compat_uninit();
 err0:
        dev_err(&pdev->dev, "failed to setup omapfb\n");
        return r;
@@ -2525,6 +2589,8 @@ static int __exit omapfb_remove(struct platform_device *pdev)
 
        omapfb_free_resources(fbdev);
 
+       omapdss_compat_uninit();
+
        return 0;
 }
 
index e8d8cc76a4351ce58e306d5a67b4b947cec2e9c1..18fa9e1d003319e62388aa12bac398f12e5927ec 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/omapfb.h>
 
 #include <video/omapdss.h>
-#include <plat/vrfb.h>
+#include <video/omapvrfb.h>
 
 #include "omapfb.h"
 
@@ -441,6 +441,7 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
        struct fb_info *fbi = dev_get_drvdata(dev);
        struct omapfb_info *ofbi = FB2OFB(fbi);
        struct omapfb2_device *fbdev = ofbi->fbdev;
+       struct omap_dss_device *display = fb2display(fbi);
        struct omapfb2_mem_region *rg;
        unsigned long size;
        int r;
@@ -455,6 +456,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
        if (!lock_fb_info(fbi))
                return -ENODEV;
 
+       if (display && display->driver->sync)
+               display->driver->sync(display);
+
        rg = ofbi->region;
 
        down_write_nested(&rg->lock, rg->id);
index 5ced9b334d35e5861f8fcf3dccee914862405120..623cd872a36788f3dc8cccd25fa53b475995cb3a 100644 (file)
@@ -28,6 +28,8 @@
 #endif
 
 #include <linux/rwsem.h>
+#include <linux/dma-attrs.h>
+#include <linux/dma-mapping.h>
 
 #include <video/omapdss.h>
 
@@ -49,6 +51,9 @@ extern bool omapfb_debug;
 
 struct omapfb2_mem_region {
        int             id;
+       struct dma_attrs attrs;
+       void            *token;
+       dma_addr_t      dma_handle;
        u32             paddr;
        void __iomem    *vaddr;
        struct vrfb     vrfb;
@@ -124,9 +129,6 @@ void omapfb_remove_sysfs(struct omapfb2_device *fbdev);
 
 int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg);
 
-int omapfb_update_window(struct fb_info *fbi,
-               u32 x, u32 y, u32 w, u32 h);
-
 int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
                        struct fb_var_screeninfo *var);
 
@@ -144,16 +146,16 @@ int omapfb_set_update_mode(struct fb_info *fbi, enum omapfb_update_mode mode);
 static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
 {
        struct omapfb_info *ofbi = FB2OFB(fbi);
-       int i;
+       struct omap_overlay *ovl;
 
        /* XXX: returns the display connected to first attached overlay */
-       for (i = 0; i < ofbi->num_overlays; i++) {
-               struct omap_overlay *ovl = ofbi->overlays[i];
 
-               return ovl->get_device(ovl);
-       }
+       if (ofbi->num_overlays == 0)
+               return NULL;
 
-       return NULL;
+       ovl = ofbi->overlays[0];
+
+       return ovl->get_device(ovl);
 }
 
 static inline struct omapfb_display_data *get_display_data(
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
deleted file mode 100644 (file)
index f2b15c4..0000000
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * VRAM manager for OMAP
- *
- * Copyright (C) 2009 Nokia Corporation
- * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*#define DEBUG*/
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/seq_file.h>
-#include <linux/memblock.h>
-#include <linux/completion.h>
-#include <linux/debugfs.h>
-#include <linux/jiffies.h>
-#include <linux/module.h>
-
-#include <asm/setup.h>
-
-#include <plat/vram.h>
-
-#ifdef DEBUG
-#define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__)
-#else
-#define DBG(format, ...)
-#endif
-
-/* postponed regions are used to temporarily store region information at boot
- * time when we cannot yet allocate the region list */
-#define MAX_POSTPONED_REGIONS 10
-
-static bool vram_initialized;
-static int postponed_cnt;
-static struct {
-       unsigned long paddr;
-       size_t size;
-} postponed_regions[MAX_POSTPONED_REGIONS];
-
-struct vram_alloc {
-       struct list_head list;
-       unsigned long paddr;
-       unsigned pages;
-};
-
-struct vram_region {
-       struct list_head list;
-       struct list_head alloc_list;
-       unsigned long paddr;
-       unsigned pages;
-};
-
-static DEFINE_MUTEX(region_mutex);
-static LIST_HEAD(region_list);
-
-static struct vram_region *omap_vram_create_region(unsigned long paddr,
-               unsigned pages)
-{
-       struct vram_region *rm;
-
-       rm = kzalloc(sizeof(*rm), GFP_KERNEL);
-
-       if (rm) {
-               INIT_LIST_HEAD(&rm->alloc_list);
-               rm->paddr = paddr;
-               rm->pages = pages;
-       }
-
-       return rm;
-}
-
-#if 0
-static void omap_vram_free_region(struct vram_region *vr)
-{
-       list_del(&vr->list);
-       kfree(vr);
-}
-#endif
-
-static struct vram_alloc *omap_vram_create_allocation(struct vram_region *vr,
-               unsigned long paddr, unsigned pages)
-{
-       struct vram_alloc *va;
-       struct vram_alloc *new;
-
-       new = kzalloc(sizeof(*va), GFP_KERNEL);
-
-       if (!new)
-               return NULL;
-
-       new->paddr = paddr;
-       new->pages = pages;
-
-       list_for_each_entry(va, &vr->alloc_list, list) {
-               if (va->paddr > new->paddr)
-                       break;
-       }
-
-       list_add_tail(&new->list, &va->list);
-
-       return new;
-}
-
-static void omap_vram_free_allocation(struct vram_alloc *va)
-{
-       list_del(&va->list);
-       kfree(va);
-}
-
-int omap_vram_add_region(unsigned long paddr, size_t size)
-{
-       struct vram_region *rm;
-       unsigned pages;
-
-       if (vram_initialized) {
-               DBG("adding region paddr %08lx size %d\n",
-                               paddr, size);
-
-               size &= PAGE_MASK;
-               pages = size >> PAGE_SHIFT;
-
-               rm = omap_vram_create_region(paddr, pages);
-               if (rm == NULL)
-                       return -ENOMEM;
-
-               list_add(&rm->list, &region_list);
-       } else {
-               if (postponed_cnt == MAX_POSTPONED_REGIONS)
-                       return -ENOMEM;
-
-               postponed_regions[postponed_cnt].paddr = paddr;
-               postponed_regions[postponed_cnt].size = size;
-
-               ++postponed_cnt;
-       }
-       return 0;
-}
-
-int omap_vram_free(unsigned long paddr, size_t size)
-{
-       struct vram_region *rm;
-       struct vram_alloc *alloc;
-       unsigned start, end;
-
-       DBG("free mem paddr %08lx size %d\n", paddr, size);
-
-       size = PAGE_ALIGN(size);
-
-       mutex_lock(&region_mutex);
-
-       list_for_each_entry(rm, &region_list, list) {
-               list_for_each_entry(alloc, &rm->alloc_list, list) {
-                       start = alloc->paddr;
-                       end = alloc->paddr + (alloc->pages >> PAGE_SHIFT);
-
-                       if (start >= paddr && end < paddr + size)
-                               goto found;
-               }
-       }
-
-       mutex_unlock(&region_mutex);
-       return -EINVAL;
-
-found:
-       omap_vram_free_allocation(alloc);
-
-       mutex_unlock(&region_mutex);
-       return 0;
-}
-EXPORT_SYMBOL(omap_vram_free);
-
-static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
-{
-       struct vram_region *rm;
-       struct vram_alloc *alloc;
-       size_t size;
-
-       size = pages << PAGE_SHIFT;
-
-       list_for_each_entry(rm, &region_list, list) {
-               unsigned long start, end;
-
-               DBG("checking region %lx %d\n", rm->paddr, rm->pages);
-
-               start = rm->paddr;
-               end = start + (rm->pages << PAGE_SHIFT) - 1;
-               if (start > paddr || end < paddr + size - 1)
-                       continue;
-
-               DBG("block ok, checking allocs\n");
-
-               list_for_each_entry(alloc, &rm->alloc_list, list) {
-                       end = alloc->paddr - 1;
-
-                       if (start <= paddr && end >= paddr + size - 1)
-                               goto found;
-
-                       start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
-               }
-
-               end = rm->paddr + (rm->pages << PAGE_SHIFT) - 1;
-
-               if (!(start <= paddr && end >= paddr + size - 1))
-                       continue;
-found:
-               DBG("found area start %lx, end %lx\n", start, end);
-
-               if (omap_vram_create_allocation(rm, paddr, pages) == NULL)
-                       return -ENOMEM;
-
-               return 0;
-       }
-
-       return -ENOMEM;
-}
-
-int omap_vram_reserve(unsigned long paddr, size_t size)
-{
-       unsigned pages;
-       int r;
-
-       DBG("reserve mem paddr %08lx size %d\n", paddr, size);
-
-       size = PAGE_ALIGN(size);
-       pages = size >> PAGE_SHIFT;
-
-       mutex_lock(&region_mutex);
-
-       r = _omap_vram_reserve(paddr, pages);
-
-       mutex_unlock(&region_mutex);
-
-       return r;
-}
-EXPORT_SYMBOL(omap_vram_reserve);
-
-static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
-{
-       struct vram_region *rm;
-       struct vram_alloc *alloc;
-
-       list_for_each_entry(rm, &region_list, list) {
-               unsigned long start, end;
-
-               DBG("checking region %lx %d\n", rm->paddr, rm->pages);
-
-               start = rm->paddr;
-
-               list_for_each_entry(alloc, &rm->alloc_list, list) {
-                       end = alloc->paddr;
-
-                       if (end - start >= pages << PAGE_SHIFT)
-                               goto found;
-
-                       start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
-               }
-
-               end = rm->paddr + (rm->pages << PAGE_SHIFT);
-found:
-               if (end - start < pages << PAGE_SHIFT)
-                       continue;
-
-               DBG("found %lx, end %lx\n", start, end);
-
-               alloc = omap_vram_create_allocation(rm, start, pages);
-               if (alloc == NULL)
-                       return -ENOMEM;
-
-               *paddr = start;
-
-               return 0;
-       }
-
-       return -ENOMEM;
-}
-
-int omap_vram_alloc(size_t size, unsigned long *paddr)
-{
-       unsigned pages;
-       int r;
-
-       BUG_ON(!size);
-
-       DBG("alloc mem size %d\n", size);
-
-       size = PAGE_ALIGN(size);
-       pages = size >> PAGE_SHIFT;
-
-       mutex_lock(&region_mutex);
-
-       r = _omap_vram_alloc(pages, paddr);
-
-       mutex_unlock(&region_mutex);
-
-       return r;
-}
-EXPORT_SYMBOL(omap_vram_alloc);
-
-void omap_vram_get_info(unsigned long *vram,
-               unsigned long *free_vram,
-               unsigned long *largest_free_block)
-{
-       struct vram_region *vr;
-       struct vram_alloc *va;
-
-       *vram = 0;
-       *free_vram = 0;
-       *largest_free_block = 0;
-
-       mutex_lock(&region_mutex);
-
-       list_for_each_entry(vr, &region_list, list) {
-               unsigned free;
-               unsigned long pa;
-
-               pa = vr->paddr;
-               *vram += vr->pages << PAGE_SHIFT;
-
-               list_for_each_entry(va, &vr->alloc_list, list) {
-                       free = va->paddr - pa;
-                       *free_vram += free;
-                       if (free > *largest_free_block)
-                               *largest_free_block = free;
-                       pa = va->paddr + (va->pages << PAGE_SHIFT);
-               }
-
-               free = vr->paddr + (vr->pages << PAGE_SHIFT) - pa;
-               *free_vram += free;
-               if (free > *largest_free_block)
-                       *largest_free_block = free;
-       }
-
-       mutex_unlock(&region_mutex);
-}
-EXPORT_SYMBOL(omap_vram_get_info);
-
-#if defined(CONFIG_DEBUG_FS)
-static int vram_debug_show(struct seq_file *s, void *unused)
-{
-       struct vram_region *vr;
-       struct vram_alloc *va;
-       unsigned size;
-
-       mutex_lock(&region_mutex);
-
-       list_for_each_entry(vr, &region_list, list) {
-               size = vr->pages << PAGE_SHIFT;
-               seq_printf(s, "%08lx-%08lx (%d bytes)\n",
-                               vr->paddr, vr->paddr + size - 1,
-                               size);
-
-               list_for_each_entry(va, &vr->alloc_list, list) {
-                       size = va->pages << PAGE_SHIFT;
-                       seq_printf(s, "    %08lx-%08lx (%d bytes)\n",
-                                       va->paddr, va->paddr + size - 1,
-                                       size);
-               }
-       }
-
-       mutex_unlock(&region_mutex);
-
-       return 0;
-}
-
-static int vram_debug_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, vram_debug_show, inode->i_private);
-}
-
-static const struct file_operations vram_debug_fops = {
-       .open           = vram_debug_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int __init omap_vram_create_debugfs(void)
-{
-       struct dentry *d;
-
-       d = debugfs_create_file("vram", S_IRUGO, NULL,
-                       NULL, &vram_debug_fops);
-       if (IS_ERR(d))
-               return PTR_ERR(d);
-
-       return 0;
-}
-#endif
-
-static __init int omap_vram_init(void)
-{
-       int i;
-
-       vram_initialized = 1;
-
-       for (i = 0; i < postponed_cnt; i++)
-               omap_vram_add_region(postponed_regions[i].paddr,
-                               postponed_regions[i].size);
-
-#ifdef CONFIG_DEBUG_FS
-       if (omap_vram_create_debugfs())
-               pr_err("VRAM: Failed to create debugfs file\n");
-#endif
-
-       return 0;
-}
-
-arch_initcall(omap_vram_init);
-
-/* boottime vram alloc stuff */
-
-/* set from board file */
-static u32 omap_vram_sdram_start __initdata;
-static u32 omap_vram_sdram_size __initdata;
-
-/* set from kernel cmdline */
-static u32 omap_vram_def_sdram_size __initdata;
-static u32 omap_vram_def_sdram_start __initdata;
-
-static int __init omap_vram_early_vram(char *p)
-{
-       omap_vram_def_sdram_size = memparse(p, &p);
-       if (*p == ',')
-               omap_vram_def_sdram_start = simple_strtoul(p + 1, &p, 16);
-       return 0;
-}
-early_param("vram", omap_vram_early_vram);
-
-/*
- * Called from map_io. We need to call to this early enough so that we
- * can reserve the fixed SDRAM regions before VM could get hold of them.
- */
-void __init omap_vram_reserve_sdram_memblock(void)
-{
-       u32 paddr;
-       u32 size = 0;
-
-       /* cmdline arg overrides the board file definition */
-       if (omap_vram_def_sdram_size) {
-               size = omap_vram_def_sdram_size;
-               paddr = omap_vram_def_sdram_start;
-       }
-
-       if (!size) {
-               size = omap_vram_sdram_size;
-               paddr = omap_vram_sdram_start;
-       }
-
-#ifdef CONFIG_OMAP2_VRAM_SIZE
-       if (!size) {
-               size = CONFIG_OMAP2_VRAM_SIZE * 1024 * 1024;
-               paddr = 0;
-       }
-#endif
-
-       if (!size)
-               return;
-
-       size = ALIGN(size, SZ_2M);
-
-       if (paddr) {
-               if (paddr & ~PAGE_MASK) {
-                       pr_err("VRAM start address 0x%08x not page aligned\n",
-                                       paddr);
-                       return;
-               }
-
-               if (!memblock_is_region_memory(paddr, size)) {
-                       pr_err("Illegal SDRAM region 0x%08x..0x%08x for VRAM\n",
-                                       paddr, paddr + size - 1);
-                       return;
-               }
-
-               if (memblock_is_region_reserved(paddr, size)) {
-                       pr_err("FB: failed to reserve VRAM - busy\n");
-                       return;
-               }
-
-               if (memblock_reserve(paddr, size) < 0) {
-                       pr_err("FB: failed to reserve VRAM - no memory\n");
-                       return;
-               }
-       } else {
-               paddr = memblock_alloc(size, SZ_2M);
-       }
-
-       memblock_free(paddr, size);
-       memblock_remove(paddr, size);
-
-       omap_vram_add_region(paddr, size);
-
-       pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
-}
-
-void __init omap_vram_set_sdram_vram(u32 size, u32 start)
-{
-       omap_vram_sdram_start = start;
-       omap_vram_sdram_size = size;
-}
index 7e990220ad2a6f52a25ff861f754d86e447a8358..5d8fdac3b8003982242d1f5f865492752ccac4bf 100644 (file)
@@ -26,9 +26,9 @@
 #include <linux/io.h>
 #include <linux/bitops.h>
 #include <linux/mutex.h>
+#include <linux/platform_device.h>
 
-#include <plat/vrfb.h>
-#include <plat/sdrc.h>
+#include <video/omapvrfb.h>
 
 #ifdef DEBUG
 #define DBG(format, ...) pr_debug("VRFB: " format, ## __VA_ARGS__)
 #define DBG(format, ...)
 #endif
 
-#define SMS_ROT_VIRT_BASE(context, rot) \
-       (((context >= 4) ? 0xD0000000 : 0x70000000) \
-        + (0x4000000 * (context)) \
-        + (0x1000000 * (rot)))
+#define SMS_ROT_CONTROL(context)       (0x0 + 0x10 * context)
+#define SMS_ROT_SIZE(context)          (0x4 + 0x10 * context)
+#define SMS_ROT_PHYSICAL_BA(context)   (0x8 + 0x10 * context)
+#define SMS_ROT_VIRT_BASE(rot)         (0x1000000 * (rot))
 
 #define OMAP_VRFB_SIZE                 (2048 * 2048 * 4)
 
 #define SMS_PW_OFFSET          4
 #define SMS_PS_OFFSET          0
 
-#define VRFB_NUM_CTXS 12
 /* bitmap of reserved contexts */
 static unsigned long ctx_map;
 
+struct vrfb_ctx {
+       u32 base;
+       u32 physical_ba;
+       u32 control;
+       u32 size;
+};
+
 static DEFINE_MUTEX(ctx_lock);
 
 /*
@@ -65,17 +71,34 @@ static DEFINE_MUTEX(ctx_lock);
  * we don't need locking, since no drivers will run until after the wake-up
  * has finished.
  */
-static struct {
-       u32 physical_ba;
-       u32 control;
-       u32 size;
-} vrfb_hw_context[VRFB_NUM_CTXS];
+
+static void __iomem *vrfb_base;
+
+static int num_ctxs;
+static struct vrfb_ctx *ctxs;
+
+static bool vrfb_loaded;
+
+static void omap2_sms_write_rot_control(u32 val, unsigned ctx)
+{
+       __raw_writel(val, vrfb_base + SMS_ROT_CONTROL(ctx));
+}
+
+static void omap2_sms_write_rot_size(u32 val, unsigned ctx)
+{
+       __raw_writel(val, vrfb_base + SMS_ROT_SIZE(ctx));
+}
+
+static void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx)
+{
+       __raw_writel(val, vrfb_base + SMS_ROT_PHYSICAL_BA(ctx));
+}
 
 static inline void restore_hw_context(int ctx)
 {
-       omap2_sms_write_rot_control(vrfb_hw_context[ctx].control, ctx);
-       omap2_sms_write_rot_size(vrfb_hw_context[ctx].size, ctx);
-       omap2_sms_write_rot_physical_ba(vrfb_hw_context[ctx].physical_ba, ctx);
+       omap2_sms_write_rot_control(ctxs[ctx].control, ctx);
+       omap2_sms_write_rot_size(ctxs[ctx].size, ctx);
+       omap2_sms_write_rot_physical_ba(ctxs[ctx].physical_ba, ctx);
 }
 
 static u32 get_image_width_roundup(u16 width, u8 bytespp)
@@ -196,9 +219,9 @@ void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
        control |= VRFB_PAGE_WIDTH_EXP  << SMS_PW_OFFSET;
        control |= VRFB_PAGE_HEIGHT_EXP << SMS_PH_OFFSET;
 
-       vrfb_hw_context[ctx].physical_ba = paddr;
-       vrfb_hw_context[ctx].size = size;
-       vrfb_hw_context[ctx].control = control;
+       ctxs[ctx].physical_ba = paddr;
+       ctxs[ctx].size = size;
+       ctxs[ctx].control = control;
 
        omap2_sms_write_rot_physical_ba(paddr, ctx);
        omap2_sms_write_rot_size(size, ctx);
@@ -274,11 +297,11 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb)
 
        mutex_lock(&ctx_lock);
 
-       for (ctx = 0; ctx < VRFB_NUM_CTXS; ++ctx)
+       for (ctx = 0; ctx < num_ctxs; ++ctx)
                if ((ctx_map & (1 << ctx)) == 0)
                        break;
 
-       if (ctx == VRFB_NUM_CTXS) {
+       if (ctx == num_ctxs) {
                pr_err("vrfb: no free contexts\n");
                r = -EBUSY;
                goto out;
@@ -293,7 +316,7 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb)
        vrfb->context = ctx;
 
        for (rot = 0; rot < 4; ++rot) {
-               paddr = SMS_ROT_VIRT_BASE(ctx, rot);
+               paddr = ctxs[ctx].base + SMS_ROT_VIRT_BASE(rot);
                if (!request_mem_region(paddr, OMAP_VRFB_SIZE, "vrfb")) {
                        pr_err("vrfb: failed to reserve VRFB "
                                        "area for ctx %d, rotation %d\n",
@@ -314,3 +337,80 @@ out:
        return r;
 }
 EXPORT_SYMBOL(omap_vrfb_request_ctx);
+
+bool omap_vrfb_supported(void)
+{
+       return vrfb_loaded;
+}
+EXPORT_SYMBOL(omap_vrfb_supported);
+
+static int __init vrfb_probe(struct platform_device *pdev)
+{
+       struct resource *mem;
+       int i;
+
+       /* first resource is the register res, the rest are vrfb contexts */
+
+       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!mem) {
+               dev_err(&pdev->dev, "can't get vrfb base address\n");
+               return -EINVAL;
+       }
+
+       vrfb_base = devm_request_and_ioremap(&pdev->dev, mem);
+       if (!vrfb_base) {
+               dev_err(&pdev->dev, "can't ioremap vrfb memory\n");
+               return -ENOMEM;
+       }
+
+       num_ctxs = pdev->num_resources - 1;
+
+       ctxs = devm_kzalloc(&pdev->dev,
+                       sizeof(struct vrfb_ctx) * num_ctxs,
+                       GFP_KERNEL);
+
+       if (!ctxs)
+               return -ENOMEM;
+
+       for (i = 0; i < num_ctxs; ++i) {
+               mem = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i);
+               if (!mem) {
+                       dev_err(&pdev->dev, "can't get vrfb ctx %d address\n",
+                                       i);
+                       return -EINVAL;
+               }
+
+               ctxs[i].base = mem->start;
+       }
+
+       vrfb_loaded = true;
+
+       return 0;
+}
+
+static void __exit vrfb_remove(struct platform_device *pdev)
+{
+       vrfb_loaded = false;
+}
+
+static struct platform_driver vrfb_driver = {
+       .driver.name    = "omapvrfb",
+       .remove         = __exit_p(vrfb_remove),
+};
+
+static int __init vrfb_init(void)
+{
+       return platform_driver_probe(&vrfb_driver, &vrfb_probe);
+}
+
+static void __exit vrfb_exit(void)
+{
+       platform_driver_unregister(&vrfb_driver);
+}
+
+module_init(vrfb_init);
+module_exit(vrfb_exit);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
+MODULE_DESCRIPTION("OMAP VRFB");
+MODULE_LICENSE("GPL v2");
index 3729173b7fbcec618be006af9fa8507824a6db7c..caefa093337d9da1d0ba440cdc98665d91bb1801 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/list.h>
 #include <linux/kobject.h>
 #include <linux/device.h>
+#include <linux/interrupt.h>
 
 #define DISPC_IRQ_FRAMEDONE            (1 << 0)
 #define DISPC_IRQ_VSYNC                        (1 << 1)
@@ -55,6 +56,7 @@
 
 struct omap_dss_device;
 struct omap_overlay_manager;
+struct dss_lcd_mgr_config;
 struct snd_aes_iec958;
 struct snd_cea_861_aud_if;
 
@@ -158,7 +160,6 @@ enum omap_display_caps {
 enum omap_dss_display_state {
        OMAP_DSS_DISPLAY_DISABLED = 0,
        OMAP_DSS_DISPLAY_ACTIVE,
-       OMAP_DSS_DISPLAY_SUSPENDED,
 };
 
 enum omap_dss_audio_state {
@@ -314,6 +315,19 @@ int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel);
 int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel);
 void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel);
 
+enum omapdss_version {
+       OMAPDSS_VER_UNKNOWN = 0,
+       OMAPDSS_VER_OMAP24xx,
+       OMAPDSS_VER_OMAP34xx_ES1,       /* OMAP3430 ES1.0, 2.0 */
+       OMAPDSS_VER_OMAP34xx_ES3,       /* OMAP3430 ES3.0+ */
+       OMAPDSS_VER_OMAP3630,
+       OMAPDSS_VER_AM35xx,
+       OMAPDSS_VER_OMAP4430_ES1,       /* OMAP4430 ES1.0 */
+       OMAPDSS_VER_OMAP4430_ES2,       /* OMAP4430 ES2.0, 2.1, 2.2 */
+       OMAPDSS_VER_OMAP4,              /* All other OMAP4s */
+       OMAPDSS_VER_OMAP5,
+};
+
 /* Board specific data */
 struct omap_dss_board_info {
        int (*get_context_loss_count)(struct device *dev);
@@ -323,6 +337,7 @@ struct omap_dss_board_info {
        int (*dsi_enable_pads)(int dsi_id, unsigned lane_mask);
        void (*dsi_disable_pads)(int dsi_id, unsigned lane_mask);
        int (*set_min_bus_tput)(struct device *dev, unsigned long r);
+       enum omapdss_version version;
 };
 
 /* Init with the board info */
@@ -607,10 +622,6 @@ struct omap_dss_device {
        struct {
                struct omap_video_timings timings;
 
-               int acbi;       /* ac-bias pin transitions per interrupt */
-               /* Unit: line clocks */
-               int acb;        /* ac-bias pin frequency */
-
                enum omap_dss_dsi_pixel_format dsi_pix_fmt;
                enum omap_dss_dsi_mode dsi_mode;
                struct omap_dss_dsi_videomode_timings dsi_vm_timings;
@@ -672,8 +683,6 @@ struct omap_dss_driver {
 
        int (*enable)(struct omap_dss_device *display);
        void (*disable)(struct omap_dss_device *display);
-       int (*suspend)(struct omap_dss_device *display);
-       int (*resume)(struct omap_dss_device *display);
        int (*run_test)(struct omap_dss_device *display, int test);
 
        int (*update)(struct omap_dss_device *dssdev,
@@ -731,6 +740,8 @@ struct omap_dss_driver {
 
 };
 
+enum omapdss_version omapdss_get_version(void);
+
 int omap_dss_register_driver(struct omap_dss_driver *);
 void omap_dss_unregister_driver(struct omap_dss_driver *);
 
@@ -740,10 +751,19 @@ void omap_dss_put_device(struct omap_dss_device *dssdev);
 struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from);
 struct omap_dss_device *omap_dss_find_device(void *data,
                int (*match)(struct omap_dss_device *dssdev, void *data));
+const char *omapdss_get_default_display_name(void);
 
 int omap_dss_start_device(struct omap_dss_device *dssdev);
 void omap_dss_stop_device(struct omap_dss_device *dssdev);
 
+int dss_feat_get_num_mgrs(void);
+int dss_feat_get_num_ovls(void);
+enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
+enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
+
+
+
 int omap_dss_get_num_overlay_managers(void);
 struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
 
@@ -765,9 +785,43 @@ typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
 int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
 int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
 
-int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout);
-int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
-               unsigned long timeout);
+u32 dispc_read_irqstatus(void);
+void dispc_clear_irqstatus(u32 mask);
+u32 dispc_read_irqenable(void);
+void dispc_write_irqenable(u32 mask);
+
+int dispc_request_irq(irq_handler_t handler, void *dev_id);
+void dispc_free_irq(void *dev_id);
+
+int dispc_runtime_get(void);
+void dispc_runtime_put(void);
+
+void dispc_mgr_enable(enum omap_channel channel, bool enable);
+bool dispc_mgr_is_enabled(enum omap_channel channel);
+u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
+u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
+u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel);
+bool dispc_mgr_go_busy(enum omap_channel channel);
+void dispc_mgr_go(enum omap_channel channel);
+void dispc_mgr_set_lcd_config(enum omap_channel channel,
+               const struct dss_lcd_mgr_config *config);
+void dispc_mgr_set_timings(enum omap_channel channel,
+               const struct omap_video_timings *timings);
+void dispc_mgr_setup(enum omap_channel channel,
+               const struct omap_overlay_manager_info *info);
+
+int dispc_ovl_check(enum omap_plane plane, enum omap_channel channel,
+               const struct omap_overlay_info *oi,
+               const struct omap_video_timings *timings,
+               int *x_predecim, int *y_predecim);
+
+int dispc_ovl_enable(enum omap_plane plane, bool enable);
+bool dispc_ovl_enabled(enum omap_plane plane);
+void dispc_ovl_set_channel_out(enum omap_plane plane,
+               enum omap_channel channel);
+int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
+               bool replication, const struct omap_video_timings *mgr_timings,
+               bool mem_to_mem);
 
 #define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
 #define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
@@ -826,4 +880,35 @@ void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev,
 void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
                struct rfbi_timings *timings);
 
+int omapdss_compat_init(void);
+void omapdss_compat_uninit(void);
+
+struct dss_mgr_ops {
+       void (*start_update)(struct omap_overlay_manager *mgr);
+       int (*enable)(struct omap_overlay_manager *mgr);
+       void (*disable)(struct omap_overlay_manager *mgr);
+       void (*set_timings)(struct omap_overlay_manager *mgr,
+                       const struct omap_video_timings *timings);
+       void (*set_lcd_config)(struct omap_overlay_manager *mgr,
+                       const struct dss_lcd_mgr_config *config);
+       int (*register_framedone_handler)(struct omap_overlay_manager *mgr,
+                       void (*handler)(void *), void *data);
+       void (*unregister_framedone_handler)(struct omap_overlay_manager *mgr,
+                       void (*handler)(void *), void *data);
+};
+
+int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops);
+void dss_uninstall_mgr_ops(void);
+
+void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
+               const struct omap_video_timings *timings);
+void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
+               const struct dss_lcd_mgr_config *config);
+int dss_mgr_enable(struct omap_overlay_manager *mgr);
+void dss_mgr_disable(struct omap_overlay_manager *mgr);
+void dss_mgr_start_update(struct omap_overlay_manager *mgr);
+int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
+               void (*handler)(void *), void *data);
+void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
+               void (*handler)(void *), void *data);
 #endif
similarity index 95%
rename from arch/arm/plat-omap/include/plat/vrfb.h
rename to include/video/omapvrfb.h
index 3792bdea2f6dcbb0be40fe8de0387e49efaf1be7..bb0bd89f8bc6b0a83b6fa2ec12610be6e822339a 100644 (file)
@@ -36,6 +36,7 @@ struct vrfb {
 };
 
 #ifdef CONFIG_OMAP2_VRFB
+extern bool omap_vrfb_supported(void);
 extern int omap_vrfb_request_ctx(struct vrfb *vrfb);
 extern void omap_vrfb_release_ctx(struct vrfb *vrfb);
 extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
@@ -49,6 +50,7 @@ extern int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot);
 extern void omap_vrfb_restore_context(void);
 
 #else
+static inline bool omap_vrfb_supported(void) { return false; }
 static inline int omap_vrfb_request_ctx(struct vrfb *vrfb) { return 0; }
 static inline void omap_vrfb_release_ctx(struct vrfb *vrfb) {}
 static inline void omap_vrfb_adjust_size(u16 *width, u16 *height,