Merge branch 'for-l-o-3.5'
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Thu, 10 May 2012 16:55:44 +0000 (19:55 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Thu, 10 May 2012 17:24:14 +0000 (20:24 +0300)
Conflicts:
drivers/video/omap2/displays/panel-taal.c

Merge OMAP DSS related board file changes. The branch will also be
merged through linux-omap tree to solve conflicts.

28 files changed:
arch/arm/mach-omap2/display.c
drivers/video/omap/Kconfig
drivers/video/omap2/displays/panel-acx565akm.c
drivers/video/omap2/displays/panel-generic-dpi.c
drivers/video/omap2/displays/panel-n8x0.c
drivers/video/omap2/displays/panel-taal.c
drivers/video/omap2/displays/panel-tpo-td043mtea1.c
drivers/video/omap2/dss/Kconfig
drivers/video/omap2/dss/apply.c
drivers/video/omap2/dss/core.c
drivers/video/omap2/dss/dispc.c
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/manager.c
drivers/video/omap2/dss/overlay.c
drivers/video/omap2/dss/rfbi.c
drivers/video/omap2/dss/sdi.c
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
drivers/video/omap2/dss/venc.c
drivers/video/omap2/omapfb/omapfb-ioctl.c
include/video/omapdss.h

index db5a88a36c63418d746e6fbfd6ecb89d97e2c2e5..60cded4738a09ac819f20c05348c01e0a6c5632a 100644 (file)
@@ -180,6 +180,11 @@ static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
                omap4_dsi_mux_pads(dsi_id, 0);
 }
 
+static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput)
+{
+       return omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, tput);
+}
+
 int __init omap_display_init(struct omap_dss_board_info *board_data)
 {
        int r = 0;
@@ -210,6 +215,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
        pdata.board_data = board_data;
        pdata.board_data->get_context_loss_count =
                omap_pm_get_dev_context_loss_count;
+       pdata.board_data->set_min_bus_tput = omap_dss_set_min_bus_tput;
 
        for (i = 0; i < oh_count; i++) {
                oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name);
index 1e7536d9a8fcfeac9e9c808aeee9629363c92efa..b48f95f0dfe24d2685d8d6ee296b18b98eab9091 100644 (file)
@@ -39,14 +39,6 @@ config FB_OMAP_LCD_MIPID
          the Mobile Industry Processor Interface DBI-C/DCS
          specification. (Supported LCDs: Philips LPH8923, Sharp LS041Y3)
 
-config FB_OMAP_BOOTLOADER_INIT
-       bool "Check bootloader initialization"
-       depends on FB_OMAP
-       help
-         Say Y here if you want to enable checking if the bootloader has
-         already initialized the display controller. In this case the
-         driver will skip the initialization.
-
 config FB_OMAP_CONSISTENT_DMA_SIZE
        int "Consistent DMA memory size (MB)"
        depends on FB_OMAP
index d26f37ac69d87d882eb7a2a5d539a7e90e55c4fa..c98f2c16f744e3c3743f751b77a176c123d60bee 100644 (file)
@@ -738,12 +738,6 @@ static void acx_panel_set_timings(struct omap_dss_device *dssdev,
        }
 }
 
-static void acx_panel_get_timings(struct omap_dss_device *dssdev,
-               struct omap_video_timings *timings)
-{
-       *timings = dssdev->panel.timings;
-}
-
 static int acx_panel_check_timings(struct omap_dss_device *dssdev,
                struct omap_video_timings *timings)
 {
@@ -761,7 +755,6 @@ static struct omap_dss_driver acx_panel_driver = {
        .resume         = acx_panel_resume,
 
        .set_timings    = acx_panel_set_timings,
-       .get_timings    = acx_panel_get_timings,
        .check_timings  = acx_panel_check_timings,
 
        .get_recommended_bpp = acx_get_recommended_bpp,
index 30fe4dfeb22700a92f8347f4cad682252e68df36..e42f9dc22123e319cde3eba127b0b57ccc05e910 100644 (file)
@@ -386,6 +386,106 @@ static struct panel_config generic_dpi_panels[] = {
 
                .name                   = "innolux_at080tn52",
        },
+
+       /* Mitsubishi AA084SB01 */
+       {
+               {
+                       .x_res          = 800,
+                       .y_res          = 600,
+                       .pixel_clock    = 40000,
+
+                       .hsw            = 1,
+                       .hfp            = 254,
+                       .hbp            = 1,
+
+                       .vsw            = 1,
+                       .vfp            = 26,
+                       .vbp            = 1,
+               },
+               .config                 = OMAP_DSS_LCD_TFT,
+               .name                   = "mitsubishi_aa084sb01",
+       },
+       /* EDT ET0500G0DH6 */
+       {
+               {
+                       .x_res          = 800,
+                       .y_res          = 480,
+                       .pixel_clock    = 33260,
+
+                       .hsw            = 128,
+                       .hfp            = 216,
+                       .hbp            = 40,
+
+                       .vsw            = 2,
+                       .vfp            = 35,
+                       .vbp            = 10,
+               },
+               .config                 = OMAP_DSS_LCD_TFT,
+               .name                   = "edt_et0500g0dh6",
+       },
+
+       /* Prime-View PD050VL1 */
+       {
+               {
+                       .x_res          = 640,
+                       .y_res          = 480,
+
+                       .pixel_clock    = 25000,
+
+                       .hsw            = 96,
+                       .hfp            = 18,
+                       .hbp            = 46,
+
+                       .vsw            = 2,
+                       .vfp            = 10,
+                       .vbp            = 33,
+               },
+               .config                 = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+                                         OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
+               .name                   = "primeview_pd050vl1",
+       },
+
+       /* Prime-View PM070WL4 */
+       {
+               {
+                       .x_res          = 800,
+                       .y_res          = 480,
+
+                       .pixel_clock    = 32000,
+
+                       .hsw            = 128,
+                       .hfp            = 42,
+                       .hbp            = 86,
+
+                       .vsw            = 2,
+                       .vfp            = 10,
+                       .vbp            = 33,
+               },
+               .config                 = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+                                         OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
+               .name                   = "primeview_pm070wl4",
+       },
+
+       /* Prime-View PD104SLF */
+       {
+               {
+                       .x_res          = 800,
+                       .y_res          = 600,
+
+                       .pixel_clock    = 40000,
+
+                       .hsw            = 128,
+                       .hfp            = 42,
+                       .hbp            = 86,
+
+                       .vsw            = 4,
+                       .vfp            = 1,
+                       .vbp            = 23,
+               },
+               .config                 = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+                                         OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
+               .name                   = "primeview_pd104slf",
+       },
 };
 
 struct panel_drv_data {
@@ -549,12 +649,6 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
        dpi_set_timings(dssdev, timings);
 }
 
-static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
-               struct omap_video_timings *timings)
-{
-       *timings = dssdev->panel.timings;
-}
-
 static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
                struct omap_video_timings *timings)
 {
@@ -571,7 +665,6 @@ static struct omap_dss_driver dpi_driver = {
        .resume         = generic_dpi_panel_resume,
 
        .set_timings    = generic_dpi_panel_set_timings,
-       .get_timings    = generic_dpi_panel_get_timings,
        .check_timings  = generic_dpi_panel_check_timings,
 
        .driver         = {
index dc9408dc93d1ed36f702187aebab9e5d7605b84b..4a34cdc1371b34c777c8b4747bd669186cd2d530 100644 (file)
@@ -610,12 +610,6 @@ static int n8x0_panel_resume(struct omap_dss_device *dssdev)
        return 0;
 }
 
-static void n8x0_panel_get_timings(struct omap_dss_device *dssdev,
-               struct omap_video_timings *timings)
-{
-       *timings = dssdev->panel.timings;
-}
-
 static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
                u16 *xres, u16 *yres)
 {
@@ -678,8 +672,6 @@ static struct omap_dss_driver n8x0_panel_driver = {
        .get_resolution = n8x0_panel_get_resolution,
        .get_recommended_bpp = omapdss_default_get_recommended_bpp,
 
-       .get_timings    = n8x0_panel_get_timings,
-
        .driver         = {
                .name   = "n8x0_panel",
                .owner  = THIS_MODULE,
index b2dd88b484209b46f5b213e9007cb2108b438c34..2ce9992f403b838efababfbc9a7ec7e65a13e533 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/gpio.h>
 #include <linux/workqueue.h>
 #include <linux/slab.h>
-#include <linux/regulator/consumer.h>
 #include <linux/mutex.h>
 
 #include <video/omapdss.h>
@@ -55,73 +54,6 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
 
 static int taal_panel_reset(struct omap_dss_device *dssdev);
 
-struct panel_regulator {
-       struct regulator *regulator;
-       const char *name;
-       int min_uV;
-       int max_uV;
-};
-
-static void free_regulators(struct panel_regulator *regulators, int n)
-{
-       int i;
-
-       for (i = 0; i < n; i++) {
-               /* disable/put in reverse order */
-               regulator_disable(regulators[n - i - 1].regulator);
-               regulator_put(regulators[n - i - 1].regulator);
-       }
-}
-
-static int init_regulators(struct omap_dss_device *dssdev,
-                       struct panel_regulator *regulators, int n)
-{
-       int r, i, v;
-
-       for (i = 0; i < n; i++) {
-               struct regulator *reg;
-
-               reg = regulator_get(&dssdev->dev, regulators[i].name);
-               if (IS_ERR(reg)) {
-                       dev_err(&dssdev->dev, "failed to get regulator %s\n",
-                               regulators[i].name);
-                       r = PTR_ERR(reg);
-                       goto err;
-               }
-
-               /* FIXME: better handling of fixed vs. variable regulators */
-               v = regulator_get_voltage(reg);
-               if (v < regulators[i].min_uV || v > regulators[i].max_uV) {
-                       r = regulator_set_voltage(reg, regulators[i].min_uV,
-                                               regulators[i].max_uV);
-                       if (r) {
-                               dev_err(&dssdev->dev,
-                                       "failed to set regulator %s voltage\n",
-                                       regulators[i].name);
-                               regulator_put(reg);
-                               goto err;
-                       }
-               }
-
-               r = regulator_enable(reg);
-               if (r) {
-                       dev_err(&dssdev->dev, "failed to enable regulator %s\n",
-                               regulators[i].name);
-                       regulator_put(reg);
-                       goto err;
-               }
-
-               regulators[i].regulator = reg;
-       }
-
-       return 0;
-
-err:
-       free_regulators(regulators, i);
-
-       return r;
-}
-
 /**
  * struct panel_config - panel configuration
  * @name: panel name
@@ -150,8 +82,6 @@ struct panel_config {
                unsigned int low;
        } reset_sequence;
 
-       struct panel_regulator *regulators;
-       int num_regulators;
 };
 
 enum {
@@ -577,12 +507,6 @@ static const struct backlight_ops taal_bl_ops = {
        .update_status  = taal_bl_update_status,
 };
 
-static void taal_get_timings(struct omap_dss_device *dssdev,
-                       struct omap_video_timings *timings)
-{
-       *timings = dssdev->panel.timings;
-}
-
 static void taal_get_resolution(struct omap_dss_device *dssdev,
                u16 *xres, u16 *yres)
 {
@@ -977,11 +901,6 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
        atomic_set(&td->do_update, 0);
 
-       r = init_regulators(dssdev, panel_config->regulators,
-                       panel_config->num_regulators);
-       if (r)
-               goto err_reg;
-
        td->workqueue = create_singlethread_workqueue("taal_esd");
        if (td->workqueue == NULL) {
                dev_err(&dssdev->dev, "can't create ESD workqueue\n");
@@ -1087,8 +1006,6 @@ err_bl:
 err_rst_gpio:
        destroy_workqueue(td->workqueue);
 err_wq:
-       free_regulators(panel_config->regulators, panel_config->num_regulators);
-err_reg:
        kfree(td);
 err:
        return r;
@@ -1125,9 +1042,6 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
        /* reset, to be sure that the panel is in a valid state */
        taal_hw_reset(dssdev);
 
-       free_regulators(td->panel_config->regulators,
-                       td->panel_config->num_regulators);
-
        if (gpio_is_valid(panel_data->reset_gpio))
                gpio_free(panel_data->reset_gpio);
 
@@ -1909,8 +1823,6 @@ static struct omap_dss_driver taal_driver = {
        .run_test       = taal_run_test,
        .memory_read    = taal_memory_read,
 
-       .get_timings    = taal_get_timings,
-
        .driver         = {
                .name   = "taal",
                .owner  = THIS_MODULE,
index 32f3fcd7f0f0adc8361523035ce5435412578424..4b6448b3c31f224f0919cd49d345eee9f61f52ae 100644 (file)
@@ -272,13 +272,16 @@ static const struct omap_video_timings tpo_td043_timings = {
 static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
 {
        int nreset_gpio = tpo_td043->nreset_gpio;
+       int r;
 
        if (tpo_td043->powered_on)
                return 0;
 
-       regulator_enable(tpo_td043->vcc_reg);
+       r = regulator_enable(tpo_td043->vcc_reg);
+       if (r != 0)
+               return r;
 
-       /* wait for regulator to stabilize */
+       /* wait for panel to stabilize */
        msleep(160);
 
        if (gpio_is_valid(nreset_gpio))
@@ -470,6 +473,18 @@ static void tpo_td043_remove(struct omap_dss_device *dssdev)
                gpio_free(nreset_gpio);
 }
 
+static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       dpi_set_timings(dssdev, timings);
+}
+
+static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       return dpi_check_timings(dssdev, timings);
+}
+
 static struct omap_dss_driver tpo_td043_driver = {
        .probe          = tpo_td043_probe,
        .remove         = tpo_td043_remove,
@@ -481,6 +496,9 @@ static struct omap_dss_driver tpo_td043_driver = {
        .set_mirror     = tpo_td043_set_hmirror,
        .get_mirror     = tpo_td043_get_hmirror,
 
+       .set_timings    = tpo_td043_set_timings,
+       .check_timings  = tpo_td043_check_timings,
+
        .driver         = {
                .name   = "tpo_td043mtea1_panel",
                .owner  = THIS_MODULE,
index 7be7c06a249ecd9cde3487a4862e1e1f9a2a2673..9aaf3246f821858e3b2d0bca1b6021cb818f2da2 100644 (file)
@@ -90,15 +90,6 @@ config OMAP2_DSS_DSI
 
          See http://www.mipi.org/ for DSI spesifications.
 
-config OMAP2_DSS_FAKE_VSYNC
-       bool "Fake VSYNC irq from manual update displays"
-       default n
-       help
-         If this is selected, DSI will generate a fake DISPC VSYNC interrupt
-         when DSI has sent a frame. This is only needed with DSI or RFBI
-         displays using manual mode, and you want VSYNC to, for example,
-         time animation.
-
 config OMAP2_DSS_MIN_FCK_PER_PCK
        int "Minimum FCK/PCK ratio (for scaling)"
        range 0 32
index b10b3bc1931e6ce0217172475155c3d07a4c7fe0..dd88b8f936c490d8da8200105b34787f41afe6a2 100644 (file)
@@ -99,6 +99,11 @@ struct mgr_priv_data {
 
        /* If true, a display is enabled using this manager */
        bool enabled;
+
+       bool extra_info_dirty;
+       bool shadow_extra_info_dirty;
+
+       struct omap_video_timings timings;
 };
 
 static struct {
@@ -176,7 +181,7 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr)
 }
 
 static int dss_check_settings_low(struct omap_overlay_manager *mgr,
-               struct omap_dss_device *dssdev, bool applying)
+               bool applying)
 {
        struct omap_overlay_info *oi;
        struct omap_overlay_manager_info *mi;
@@ -187,6 +192,9 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr,
 
        mp = get_mgr_priv(mgr);
 
+       if (!mp->enabled)
+               return 0;
+
        if (applying && mp->user_info_dirty)
                mi = &mp->user_info;
        else
@@ -206,26 +214,24 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr,
                ois[ovl->id] = oi;
        }
 
-       return dss_mgr_check(mgr, dssdev, mi, ois);
+       return dss_mgr_check(mgr, mi, &mp->timings, ois);
 }
 
 /*
  * check manager and overlay settings using overlay_info from data->info
  */
-static int dss_check_settings(struct omap_overlay_manager *mgr,
-               struct omap_dss_device *dssdev)
+static int dss_check_settings(struct omap_overlay_manager *mgr)
 {
-       return dss_check_settings_low(mgr, dssdev, false);
+       return dss_check_settings_low(mgr, false);
 }
 
 /*
  * check manager and overlay settings using overlay_info from ovl->info if
  * dirty and from data->info otherwise
  */
-static int dss_check_settings_apply(struct omap_overlay_manager *mgr,
-               struct omap_dss_device *dssdev)
+static int dss_check_settings_apply(struct omap_overlay_manager *mgr)
 {
-       return dss_check_settings_low(mgr, dssdev, true);
+       return dss_check_settings_low(mgr, true);
 }
 
 static bool need_isr(void)
@@ -261,6 +267,20 @@ static bool need_isr(void)
                        if (mp->shadow_info_dirty)
                                return true;
 
+                       /*
+                        * NOTE: we don't check extra_info flags for disabled
+                        * managers, once the manager is enabled, the extra_info
+                        * related manager changes will be taken in by HW.
+                        */
+
+                       /* to write new values to registers */
+                       if (mp->extra_info_dirty)
+                               return true;
+
+                       /* to set GO bit */
+                       if (mp->shadow_extra_info_dirty)
+                               return true;
+
                        list_for_each_entry(ovl, &mgr->overlays, list) {
                                struct ovl_priv_data *op;
 
@@ -305,7 +325,7 @@ static bool need_go(struct omap_overlay_manager *mgr)
 
        mp = get_mgr_priv(mgr);
 
-       if (mp->shadow_info_dirty)
+       if (mp->shadow_info_dirty || mp->shadow_extra_info_dirty)
                return true;
 
        list_for_each_entry(ovl, &mgr->overlays, list) {
@@ -320,20 +340,16 @@ static bool need_go(struct omap_overlay_manager *mgr)
 /* returns true if an extra_info field is currently being updated */
 static bool extra_info_update_ongoing(void)
 {
-       const int num_ovls = omap_dss_get_num_overlays();
-       struct ovl_priv_data *op;
-       struct omap_overlay *ovl;
-       struct mgr_priv_data *mp;
+       const int num_mgrs = dss_feat_get_num_mgrs();
        int i;
 
-       for (i = 0; i < num_ovls; ++i) {
-               ovl = omap_dss_get_overlay(i);
-               op = get_ovl_priv(ovl);
-
-               if (!ovl->manager)
-                       continue;
+       for (i = 0; i < num_mgrs; ++i) {
+               struct omap_overlay_manager *mgr;
+               struct omap_overlay *ovl;
+               struct mgr_priv_data *mp;
 
-               mp = get_mgr_priv(ovl->manager);
+               mgr = omap_dss_get_overlay_manager(i);
+               mp = get_mgr_priv(mgr);
 
                if (!mp->enabled)
                        continue;
@@ -341,8 +357,15 @@ static bool extra_info_update_ongoing(void)
                if (!mp->updating)
                        continue;
 
-               if (op->extra_info_dirty || op->shadow_extra_info_dirty)
+               if (mp->extra_info_dirty || mp->shadow_extra_info_dirty)
                        return true;
+
+               list_for_each_entry(ovl, &mgr->overlays, list) {
+                       struct ovl_priv_data *op = get_ovl_priv(ovl);
+
+                       if (op->extra_info_dirty || op->shadow_extra_info_dirty)
+                               return true;
+               }
        }
 
        return false;
@@ -525,11 +548,13 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
 
        oi = &op->info;
 
+       mp = get_mgr_priv(ovl->manager);
+
        replication = dss_use_replication(ovl->manager->device, oi->color_mode);
 
        ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC;
 
-       r = dispc_ovl_setup(ovl->id, oi, ilace, replication);
+       r = dispc_ovl_setup(ovl->id, oi, ilace, replication, &mp->timings);
        if (r) {
                /*
                 * We can't do much here, as this function can be called from
@@ -543,8 +568,6 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
                return;
        }
 
-       mp = get_mgr_priv(ovl->manager);
-
        op->info_dirty = false;
        if (mp->updating)
                op->shadow_info_dirty = true;
@@ -601,6 +624,22 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
        }
 }
 
+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);
+
+       if (!mp->extra_info_dirty)
+               return;
+
+       dispc_mgr_set_timings(mgr->id, &mp->timings);
+
+       mp->extra_info_dirty = false;
+       if (mp->updating)
+               mp->shadow_extra_info_dirty = true;
+}
+
 static void dss_write_regs_common(void)
 {
        const int num_mgrs = omap_dss_get_num_overlay_managers();
@@ -646,7 +685,7 @@ static void dss_write_regs(void)
                if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
                        continue;
 
-               r = dss_check_settings(mgr, mgr->device);
+               r = dss_check_settings(mgr);
                if (r) {
                        DSSERR("cannot write registers for manager %s: "
                                        "illegal configuration\n", mgr->name);
@@ -654,6 +693,7 @@ static void dss_write_regs(void)
                }
 
                dss_mgr_write_regs(mgr);
+               dss_mgr_write_regs_extra(mgr);
        }
 }
 
@@ -693,6 +733,7 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
 
        mp = get_mgr_priv(mgr);
        mp->shadow_info_dirty = false;
+       mp->shadow_extra_info_dirty = false;
 
        list_for_each_entry(ovl, &mgr->overlays, list) {
                op = get_ovl_priv(ovl);
@@ -711,7 +752,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
 
        WARN_ON(mp->updating);
 
-       r = dss_check_settings(mgr, mgr->device);
+       r = dss_check_settings(mgr);
        if (r) {
                DSSERR("cannot start manual update: illegal configuration\n");
                spin_unlock_irqrestore(&data_lock, flags);
@@ -719,6 +760,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
        }
 
        dss_mgr_write_regs(mgr);
+       dss_mgr_write_regs_extra(mgr);
 
        dss_write_regs_common();
 
@@ -857,7 +899,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
 
        spin_lock_irqsave(&data_lock, flags);
 
-       r = dss_check_settings_apply(mgr, mgr->device);
+       r = dss_check_settings_apply(mgr);
        if (r) {
                spin_unlock_irqrestore(&data_lock, flags);
                DSSERR("failed to apply settings: illegal configuration.\n");
@@ -918,14 +960,11 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
                bool use_fifo_merge)
 {
        struct ovl_priv_data *op = get_ovl_priv(ovl);
-       struct omap_dss_device *dssdev;
        u32 fifo_low, fifo_high;
 
        if (!op->enabled && !op->enabling)
                return;
 
-       dssdev = ovl->manager->device;
-
        dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high,
                        use_fifo_merge);
 
@@ -1050,7 +1089,7 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
 
        mp->enabled = true;
 
-       r = dss_check_settings(mgr, mgr->device);
+       r = dss_check_settings(mgr);
        if (r) {
                DSSERR("failed to enable manager %d: check_settings failed\n",
                                mgr->id);
@@ -1225,6 +1264,35 @@ err:
        return r;
 }
 
+static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
+               struct omap_video_timings *timings)
+{
+       struct mgr_priv_data *mp = get_mgr_priv(mgr);
+
+       mp->timings = *timings;
+       mp->extra_info_dirty = true;
+}
+
+void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
+               struct omap_video_timings *timings)
+{
+       unsigned long flags;
+
+       mutex_lock(&apply_lock);
+
+       spin_lock_irqsave(&data_lock, flags);
+
+       dss_apply_mgr_timings(mgr, timings);
+
+       dss_write_regs();
+       dss_set_go_bits();
+
+       spin_unlock_irqrestore(&data_lock, flags);
+
+       wait_pending_extra_info_updates();
+
+       mutex_unlock(&apply_lock);
+}
 
 int dss_ovl_set_info(struct omap_overlay *ovl,
                struct omap_overlay_info *info)
@@ -1393,7 +1461,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
 
        op->enabling = true;
 
-       r = dss_check_settings(ovl->manager, ovl->manager->device);
+       r = dss_check_settings(ovl->manager);
        if (r) {
                DSSERR("failed to enable overlay %d: check_settings failed\n",
                                ovl->id);
index e8a120771ac6fc0cdb4fc537aca478ecde0d6ab2..64cb8aa49b26dd0a35a6cfc3f3a382d25e24691d 100644 (file)
@@ -87,6 +87,16 @@ struct regulator *dss_get_vdds_sdi(void)
        return reg;
 }
 
+int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
+{
+       struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
+
+       if (pdata->set_min_bus_tput)
+               return pdata->set_min_bus_tput(dev, tput);
+       else
+               return 0;
+}
+
 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
 static int dss_debug_show(struct seq_file *s, void *unused)
 {
@@ -381,6 +391,8 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
        if (dssdriver->get_recommended_bpp == NULL)
                dssdriver->get_recommended_bpp =
                        omapdss_default_get_recommended_bpp;
+       if (dssdriver->get_timings == NULL)
+               dssdriver->get_timings = omapdss_default_get_timings;
 
        return driver_register(&dssdriver->driver);
 }
index ee30937482e1156240de18ccaff3f889a1e4637b..727e15b29a143ebfc342761c7c547062e0c2cdcd 100644 (file)
@@ -413,14 +413,6 @@ static inline bool dispc_mgr_is_lcd(enum omap_channel channel)
                return false;
 }
 
-static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel)
-{
-       struct omap_overlay_manager *mgr =
-               omap_dss_get_overlay_manager(channel);
-
-       return mgr ? mgr->device : NULL;
-}
-
 u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
 {
        switch (channel) {
@@ -983,20 +975,13 @@ static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable)
        REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift);
 }
 
-void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
+static void dispc_mgr_set_size(enum omap_channel channel, u16 width,
+               u16 height)
 {
        u32 val;
-       BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
-       val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
-       dispc_write_reg(DISPC_SIZE_MGR(channel), val);
-}
 
-void dispc_set_digit_size(u16 width, u16 height)
-{
-       u32 val;
-       BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
        val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
-       dispc_write_reg(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT), val);
+       dispc_write_reg(DISPC_SIZE_MGR(channel), val);
 }
 
 static void dispc_read_plane_fifo_sizes(void)
@@ -1431,7 +1416,7 @@ static void calc_vrfb_rotation_offset(u8 rotation, bool mirror,
                enum omap_color_mode color_mode, bool fieldmode,
                unsigned int field_offset,
                unsigned *offset0, unsigned *offset1,
-               s32 *row_inc, s32 *pix_inc)
+               s32 *row_inc, s32 *pix_inc, int x_predecim, int y_predecim)
 {
        u8 ps;
 
@@ -1477,10 +1462,10 @@ static void calc_vrfb_rotation_offset(u8 rotation, bool mirror,
                else
                        *offset0 = 0;
 
-               *row_inc = pixinc(1 + (screen_width - width) +
-                               (fieldmode ? screen_width : 0),
-                               ps);
-               *pix_inc = pixinc(1, ps);
+               *row_inc = pixinc(1 +
+                       (y_predecim * screen_width - x_predecim * width) +
+                       (fieldmode ? screen_width : 0), ps);
+               *pix_inc = pixinc(x_predecim, ps);
                break;
 
        case OMAP_DSS_ROT_0 + 4:
@@ -1498,10 +1483,10 @@ static void calc_vrfb_rotation_offset(u8 rotation, bool mirror,
                        *offset0 = field_offset * screen_width * ps;
                else
                        *offset0 = 0;
-               *row_inc = pixinc(1 - (screen_width + width) -
-                               (fieldmode ? screen_width : 0),
-                               ps);
-               *pix_inc = pixinc(1, ps);
+               *row_inc = pixinc(1 -
+                       (y_predecim * screen_width + x_predecim * width) -
+                       (fieldmode ? screen_width : 0), ps);
+               *pix_inc = pixinc(x_predecim, ps);
                break;
 
        default:
@@ -1515,7 +1500,7 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
                enum omap_color_mode color_mode, bool fieldmode,
                unsigned int field_offset,
                unsigned *offset0, unsigned *offset1,
-               s32 *row_inc, s32 *pix_inc)
+               s32 *row_inc, s32 *pix_inc, int x_predecim, int y_predecim)
 {
        u8 ps;
        u16 fbw, fbh;
@@ -1557,10 +1542,14 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
                        *offset0 = *offset1 + field_offset * screen_width * ps;
                else
                        *offset0 = *offset1;
-               *row_inc = pixinc(1 + (screen_width - fbw) +
-                               (fieldmode ? screen_width : 0),
-                               ps);
-               *pix_inc = pixinc(1, ps);
+               *row_inc = pixinc(1 +
+                       (y_predecim * screen_width - fbw * x_predecim) +
+                       (fieldmode ? screen_width : 0), ps);
+               if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+                       color_mode == OMAP_DSS_COLOR_UYVY)
+                       *pix_inc = pixinc(x_predecim, 2 * ps);
+               else
+                       *pix_inc = pixinc(x_predecim, ps);
                break;
        case OMAP_DSS_ROT_90:
                *offset1 = screen_width * (fbh - 1) * ps;
@@ -1568,9 +1557,9 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
                        *offset0 = *offset1 + field_offset * ps;
                else
                        *offset0 = *offset1;
-               *row_inc = pixinc(screen_width * (fbh - 1) + 1 +
-                               (fieldmode ? 1 : 0), ps);
-               *pix_inc = pixinc(-screen_width, ps);
+               *row_inc = pixinc(screen_width * (fbh * x_predecim - 1) +
+                               y_predecim + (fieldmode ? 1 : 0), ps);
+               *pix_inc = pixinc(-x_predecim * screen_width, ps);
                break;
        case OMAP_DSS_ROT_180:
                *offset1 = (screen_width * (fbh - 1) + fbw - 1) * ps;
@@ -1579,10 +1568,13 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
                else
                        *offset0 = *offset1;
                *row_inc = pixinc(-1 -
-                               (screen_width - fbw) -
-                               (fieldmode ? screen_width : 0),
-                               ps);
-               *pix_inc = pixinc(-1, ps);
+                       (y_predecim * screen_width - fbw * x_predecim) -
+                       (fieldmode ? screen_width : 0), ps);
+               if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+                       color_mode == OMAP_DSS_COLOR_UYVY)
+                       *pix_inc = pixinc(-x_predecim, 2 * ps);
+               else
+                       *pix_inc = pixinc(-x_predecim, ps);
                break;
        case OMAP_DSS_ROT_270:
                *offset1 = (fbw - 1) * ps;
@@ -1590,9 +1582,9 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
                        *offset0 = *offset1 - field_offset * ps;
                else
                        *offset0 = *offset1;
-               *row_inc = pixinc(-screen_width * (fbh - 1) - 1 -
-                               (fieldmode ? 1 : 0), ps);
-               *pix_inc = pixinc(screen_width, ps);
+               *row_inc = pixinc(-screen_width * (fbh * x_predecim - 1) -
+                               y_predecim - (fieldmode ? 1 : 0), ps);
+               *pix_inc = pixinc(x_predecim * screen_width, ps);
                break;
 
        /* mirroring */
@@ -1602,10 +1594,14 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
                        *offset0 = *offset1 + field_offset * screen_width * ps;
                else
                        *offset0 = *offset1;
-               *row_inc = pixinc(screen_width * 2 - 1 +
+               *row_inc = pixinc(y_predecim * screen_width * 2 - 1 +
                                (fieldmode ? screen_width : 0),
                                ps);
-               *pix_inc = pixinc(-1, ps);
+               if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+                       color_mode == OMAP_DSS_COLOR_UYVY)
+                       *pix_inc = pixinc(-x_predecim, 2 * ps);
+               else
+                       *pix_inc = pixinc(-x_predecim, ps);
                break;
 
        case OMAP_DSS_ROT_90 + 4:
@@ -1614,10 +1610,10 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
                        *offset0 = *offset1 + field_offset * ps;
                else
                        *offset0 = *offset1;
-               *row_inc = pixinc(-screen_width * (fbh - 1) + 1 +
-                               (fieldmode ? 1 : 0),
+               *row_inc = pixinc(-screen_width * (fbh * x_predecim - 1) +
+                               y_predecim + (fieldmode ? 1 : 0),
                                ps);
-               *pix_inc = pixinc(screen_width, ps);
+               *pix_inc = pixinc(x_predecim * screen_width, ps);
                break;
 
        case OMAP_DSS_ROT_180 + 4:
@@ -1626,10 +1622,14 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
                        *offset0 = *offset1 - field_offset * screen_width * ps;
                else
                        *offset0 = *offset1;
-               *row_inc = pixinc(1 - screen_width * 2 -
+               *row_inc = pixinc(1 - y_predecim * screen_width * 2 -
                                (fieldmode ? screen_width : 0),
                                ps);
-               *pix_inc = pixinc(1, ps);
+               if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+                       color_mode == OMAP_DSS_COLOR_UYVY)
+                       *pix_inc = pixinc(x_predecim, 2 * ps);
+               else
+                       *pix_inc = pixinc(x_predecim, ps);
                break;
 
        case OMAP_DSS_ROT_270 + 4:
@@ -1638,10 +1638,10 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
                        *offset0 = *offset1 - field_offset * ps;
                else
                        *offset0 = *offset1;
-               *row_inc = pixinc(screen_width * (fbh - 1) - 1 -
-                               (fieldmode ? 1 : 0),
+               *row_inc = pixinc(screen_width * (fbh * x_predecim - 1) -
+                               y_predecim - (fieldmode ? 1 : 0),
                                ps);
-               *pix_inc = pixinc(-screen_width, ps);
+               *pix_inc = pixinc(-x_predecim * screen_width, ps);
                break;
 
        default:
@@ -1649,23 +1649,79 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
        }
 }
 
-static unsigned long calc_fclk_five_taps(enum omap_channel channel, 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_channel channel,
+               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);
+       unsigned long nonactive, lclk, pclk;
+       static const u8 limits[3] = { 8, 10, 20 };
+       u64 val, blank;
+       int i;
+
+       nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
+       pclk = dispc_mgr_pclk_rate(channel);
+       if (dispc_mgr_is_lcd(channel))
+               lclk = dispc_mgr_lclk_rate(channel);
+       else
+               lclk = dispc_fclk_rate();
+
+       i = 0;
+       if (out_height < height)
+               i++;
+       if (out_width < width)
+               i++;
+       blank = div_u64((u64)(t->hbp + t->hsw + t->hfp) * lclk, pclk);
+       DSSDBG("blanking period + ppl = %llu (limit = %u)\n", blank, limits[i]);
+       if (blank <= limits[i])
+               return -EINVAL;
+
+       /*
+        * Pixel data should be prepared before visible display point starts.
+        * So, atleast DS-2 lines must have already been fetched by DISPC
+        * during nonactive - pos_x period.
+        */
+       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)
+               return -EINVAL;
+
+       /*
+        * All lines need to be refilled during the nonactive period of which
+        * only one line can be loaded during the active period. So, atleast
+        * DS - 1 lines should be loaded during nonactive period.
+        */
+       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)
+               return -EINVAL;
+
+       return 0;
+}
+
+static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
+               const struct omap_video_timings *mgr_timings, u16 width,
                u16 height, u16 out_width, u16 out_height,
                enum omap_color_mode color_mode)
 {
-       u32 fclk = 0;
+       u32 core_clk = 0;
        u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
 
        if (height <= out_height && width <= out_width)
                return (unsigned long) pclk;
 
        if (height > out_height) {
-               struct omap_dss_device *dssdev = dispc_mgr_get_device(channel);
-               unsigned int ppl = dssdev->panel.timings.x_res;
+               unsigned int ppl = mgr_timings->x_res;
 
                tmp = pclk * height * out_width;
                do_div(tmp, 2 * out_height * ppl);
-               fclk = tmp;
+               core_clk = tmp;
 
                if (height > 2 * out_height) {
                        if (ppl == out_width)
@@ -1673,23 +1729,23 @@ static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
 
                        tmp = pclk * (height - 2 * out_height) * out_width;
                        do_div(tmp, 2 * out_height * (ppl - out_width));
-                       fclk = max(fclk, (u32) tmp);
+                       core_clk = max_t(u32, core_clk, tmp);
                }
        }
 
        if (width > out_width) {
                tmp = pclk * width;
                do_div(tmp, out_width);
-               fclk = max(fclk, (u32) tmp);
+               core_clk = max_t(u32, core_clk, tmp);
 
                if (color_mode == OMAP_DSS_COLOR_RGB24U)
-                       fclk <<= 1;
+                       core_clk <<= 1;
        }
 
-       return fclk;
+       return core_clk;
 }
 
-static unsigned long calc_fclk(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
                u16 height, u16 out_width, u16 out_height)
 {
        unsigned int hf, vf;
@@ -1730,15 +1786,20 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
-               enum omap_channel channel, u16 width, u16 height,
-               u16 out_width, u16 out_height,
-               enum omap_color_mode color_mode, bool *five_taps)
+               enum omap_channel channel,
+               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, u16 pos_x)
 {
        struct omap_overlay *ovl = omap_dss_get_overlay(plane);
        const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
        const int maxsinglelinewidth =
                                dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
-       unsigned long fclk = 0;
+       const int max_decim_limit = 16;
+       unsigned long core_clk = 0;
+       int decim_x, decim_y, error, min_factor;
+       u16 in_width, in_height, in_width_max = 0;
 
        if (width == out_width && height == out_height)
                return 0;
@@ -1746,64 +1807,154 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
        if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
                return -EINVAL;
 
-       if (out_width < width / maxdownscale ||
-                       out_width > width * 8)
+       *x_predecim = max_decim_limit;
+       *y_predecim = max_decim_limit;
+
+       if (color_mode == OMAP_DSS_COLOR_CLUT1 ||
+           color_mode == OMAP_DSS_COLOR_CLUT2 ||
+           color_mode == OMAP_DSS_COLOR_CLUT4 ||
+           color_mode == OMAP_DSS_COLOR_CLUT8) {
+               *x_predecim = 1;
+               *y_predecim = 1;
+               *five_taps = false;
+               return 0;
+       }
+
+       decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
+       decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
+
+       min_factor = min(decim_x, decim_y);
+
+       if (decim_x > *x_predecim || out_width > width * 8)
                return -EINVAL;
 
-       if (out_height < height / maxdownscale ||
-                       out_height > height * 8)
+       if (decim_y > *y_predecim || out_height > height * 8)
                return -EINVAL;
 
        if (cpu_is_omap24xx()) {
-               if (width > maxsinglelinewidth)
-                       DSSERR("Cannot scale max input width exceeded");
                *five_taps = false;
-               fclk = calc_fclk(channel, width, height, out_width,
-                                                               out_height);
+
+               do {
+                       in_height = DIV_ROUND_UP(height, decim_y);
+                       in_width = DIV_ROUND_UP(width, decim_x);
+                       core_clk = calc_core_clk(channel, in_width, in_height,
+                                       out_width, out_height);
+                       error = (in_width > maxsinglelinewidth || !core_clk ||
+                               core_clk > dispc_core_clk_rate());
+                       if (error) {
+                               if (decim_x == decim_y) {
+                                       decim_x = min_factor;
+                                       decim_y++;
+                               } else {
+                                       swap(decim_x, decim_y);
+                                       if (decim_x < decim_y)
+                                               decim_x++;
+                               }
+                       }
+               } while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
+                               error);
+
+               if (in_width > maxsinglelinewidth) {
+                       DSSERR("Cannot scale max input width exceeded");
+                       return -EINVAL;
+               }
        } else if (cpu_is_omap34xx()) {
-               if (width > (maxsinglelinewidth * 2)) {
+
+               do {
+                       in_height = DIV_ROUND_UP(height, decim_y);
+                       in_width = DIV_ROUND_UP(width, decim_x);
+                       core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+                               in_width, in_height, out_width, out_height,
+                               color_mode);
+
+                       error = check_horiz_timing_omap3(channel, mgr_timings,
+                               pos_x, in_width, in_height, out_width,
+                               out_height);
+
+                       if (in_width > maxsinglelinewidth)
+                               if (in_height > out_height &&
+                                       in_height < out_height * 2)
+                                       *five_taps = false;
+                       if (!*five_taps)
+                               core_clk = calc_core_clk(channel, in_width,
+                                       in_height, out_width, out_height);
+                       error = (error || in_width > maxsinglelinewidth * 2 ||
+                               (in_width > maxsinglelinewidth && *five_taps) ||
+                               !core_clk || core_clk > dispc_core_clk_rate());
+                       if (error) {
+                               if (decim_x == decim_y) {
+                                       decim_x = min_factor;
+                                       decim_y++;
+                               } else {
+                                       swap(decim_x, decim_y);
+                                       if (decim_x < decim_y)
+                                               decim_x++;
+                               }
+                       }
+               } while (decim_x <= *x_predecim && decim_y <= *y_predecim
+                       && error);
+
+               if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
+                       height, out_width, out_height)){
+                               DSSERR("horizontal timing too tight\n");
+                               return -EINVAL;
+               }
+
+               if (in_width > (maxsinglelinewidth * 2)) {
                        DSSERR("Cannot setup scaling");
                        DSSERR("width exceeds maximum width possible");
                        return -EINVAL;
                }
-               fclk = calc_fclk_five_taps(channel, width, height, out_width,
-                                               out_height, color_mode);
-               if (width > maxsinglelinewidth) {
-                       if (height > out_height && height < out_height * 2)
-                               *five_taps = false;
-                       else {
-                               DSSERR("cannot setup scaling with five taps");
-                               return -EINVAL;
-                       }
+
+               if (in_width > maxsinglelinewidth && *five_taps) {
+                       DSSERR("cannot setup scaling with five taps");
+                       return -EINVAL;
                }
-               if (!*five_taps)
-                       fclk = calc_fclk(channel, width, height, out_width,
-                                       out_height);
        } else {
-               if (width > maxsinglelinewidth) {
+               int decim_x_min = decim_x;
+               in_height = DIV_ROUND_UP(height, decim_y);
+               in_width_max = dispc_core_clk_rate() /
+                               DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
+                                               out_width);
+               decim_x = DIV_ROUND_UP(width, in_width_max);
+
+               decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
+               if (decim_x > *x_predecim)
+                       return -EINVAL;
+
+               do {
+                       in_width = DIV_ROUND_UP(width, decim_x);
+               } while (decim_x <= *x_predecim &&
+                               in_width > maxsinglelinewidth && decim_x++);
+
+               if (in_width > maxsinglelinewidth) {
                        DSSERR("Cannot scale width exceeds max line width");
                        return -EINVAL;
                }
-               fclk = calc_fclk(channel, width, height, out_width,
-                               out_height);
+
+               core_clk = calc_core_clk(channel, in_width, in_height,
+                               out_width, out_height);
        }
 
-       DSSDBG("required fclk rate = %lu Hz\n", fclk);
-       DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
+       DSSDBG("required core clk rate = %lu Hz\n", core_clk);
+       DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
 
-       if (!fclk || fclk > dispc_fclk_rate()) {
+       if (!core_clk || core_clk > dispc_core_clk_rate()) {
                DSSERR("failed to set up scaling, "
-                       "required fclk rate = %lu Hz, "
-                       "current fclk rate = %lu Hz\n",
-                       fclk, dispc_fclk_rate());
+                       "required core clk rate = %lu Hz, "
+                       "current core clk rate = %lu Hz\n",
+                       core_clk, dispc_core_clk_rate());
                return -EINVAL;
        }
 
+       *x_predecim = decim_x;
+       *y_predecim = decim_y;
        return 0;
 }
 
 int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
-               bool ilace, bool replication)
+               bool ilace, bool replication,
+               const struct omap_video_timings *mgr_timings)
 {
        struct omap_overlay *ovl = omap_dss_get_overlay(plane);
        bool five_taps = true;
@@ -1814,8 +1965,11 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
        s32 pix_inc;
        u16 frame_height = oi->height;
        unsigned int field_offset = 0;
-       u16 outw, outh;
+       u16 in_height = oi->height;
+       u16 in_width = oi->width;
+       u16 out_width, out_height;
        enum omap_channel channel;
+       int x_predecim = 1, y_predecim = 1;
 
        channel = dispc_ovl_get_channel_out(plane);
 
@@ -1829,32 +1983,35 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
        if (oi->paddr == 0)
                return -EINVAL;
 
-       outw = oi->out_width == 0 ? oi->width : oi->out_width;
-       outh = oi->out_height == 0 ? oi->height : oi->out_height;
+       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 == outh)
+       if (ilace && oi->height == out_height)
                fieldmode = 1;
 
        if (ilace) {
                if (fieldmode)
-                       oi->height /= 2;
+                       in_height /= 2;
                oi->pos_y /= 2;
-               outh /= 2;
+               out_height /= 2;
 
                DSSDBG("adjusting for ilace: height %d, pos_y %d, "
                                "out_height %d\n",
-                               oi->height, oi->pos_y, outh);
+                               in_height, oi->pos_y, out_height);
        }
 
        if (!dss_feat_color_mode_supported(plane, oi->color_mode))
                return -EINVAL;
 
-       r = dispc_ovl_calc_scaling(plane, channel, oi->width, oi->height,
-                       outw, outh, oi->color_mode,
-                       &five_taps);
+       r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width,
+                       in_height, out_width, out_height, oi->color_mode,
+                       &five_taps, &x_predecim, &y_predecim, oi->pos_x);
        if (r)
                return r;
 
+       in_width = DIV_ROUND_UP(in_width, x_predecim);
+       in_height = DIV_ROUND_UP(in_height, y_predecim);
+
        if (oi->color_mode == OMAP_DSS_COLOR_YUV2 ||
                        oi->color_mode == OMAP_DSS_COLOR_UYVY ||
                        oi->color_mode == OMAP_DSS_COLOR_NV12)
@@ -1868,10 +2025,10 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
                 * so the integer part must be added to the base address of the
                 * bottom field.
                 */
-               if (!oi->height || oi->height == outh)
+               if (!in_height || in_height == out_height)
                        field_offset = 0;
                else
-                       field_offset = oi->height / outh / 2;
+                       field_offset = in_height / out_height / 2;
        }
 
        /* Fields are independent but interleaved in memory. */
@@ -1880,14 +2037,16 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 
        if (oi->rotation_type == OMAP_DSS_ROT_DMA)
                calc_dma_rotation_offset(oi->rotation, oi->mirror,
-                               oi->screen_width, oi->width, frame_height,
+                               oi->screen_width, in_width, frame_height,
                                oi->color_mode, fieldmode, field_offset,
-                               &offset0, &offset1, &row_inc, &pix_inc);
+                               &offset0, &offset1, &row_inc, &pix_inc,
+                               x_predecim, y_predecim);
        else
                calc_vrfb_rotation_offset(oi->rotation, oi->mirror,
-                               oi->screen_width, oi->width, frame_height,
+                               oi->screen_width, in_width, frame_height,
                                oi->color_mode, fieldmode, field_offset,
-                               &offset0, &offset1, &row_inc, &pix_inc);
+                               &offset0, &offset1, &row_inc, &pix_inc,
+                               x_predecim, y_predecim);
 
        DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
                        offset0, offset1, row_inc, pix_inc);
@@ -1906,19 +2065,18 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
        dispc_ovl_set_row_inc(plane, row_inc);
        dispc_ovl_set_pix_inc(plane, pix_inc);
 
-       DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, oi->width,
-                       oi->height, outw, outh);
+       DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width,
+                       in_height, out_width, out_height);
 
        dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y);
 
-       dispc_ovl_set_pic_size(plane, oi->width, oi->height);
+       dispc_ovl_set_pic_size(plane, in_width, in_height);
 
        if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
-               dispc_ovl_set_scaling(plane, oi->width, oi->height,
-                                  outw, outh,
-                                  ilace, five_taps, fieldmode,
+               dispc_ovl_set_scaling(plane, in_width, in_height, out_width,
+                                  out_height, ilace, five_taps, fieldmode,
                                   oi->color_mode, oi->rotation);
-               dispc_ovl_set_vid_size(plane, outw, outh);
+               dispc_ovl_set_vid_size(plane, out_width, out_height);
                dispc_ovl_set_vid_color_conv(plane, cconv);
        }
 
@@ -2285,6 +2443,12 @@ void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
                REG_FLD_MOD(DISPC_CONTROL, enable, 11, 11);
 }
 
+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);
+}
+
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
                int vsw, int vfp, int vbp)
 {
@@ -2309,11 +2473,20 @@ static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
        return true;
 }
 
-bool dispc_lcd_timings_ok(struct omap_video_timings *timings)
+bool dispc_mgr_timings_ok(enum omap_channel channel,
+               const struct omap_video_timings *timings)
 {
-       return _dispc_lcd_timings_ok(timings->hsw, timings->hfp,
-                       timings->hbp, timings->vsw,
-                       timings->vfp, timings->vbp);
+       bool timings_ok;
+
+       timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
+
+       if (dispc_mgr_is_lcd(channel))
+               timings_ok =  timings_ok && _dispc_lcd_timings_ok(timings->hsw,
+                                               timings->hfp, timings->hbp,
+                                               timings->vsw, timings->vfp,
+                                               timings->vbp);
+
+       return timings_ok;
 }
 
 static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
@@ -2340,37 +2513,40 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 }
 
 /* change name to mode? */
-void dispc_mgr_set_lcd_timings(enum omap_channel channel,
+void dispc_mgr_set_timings(enum omap_channel channel,
                struct omap_video_timings *timings)
 {
        unsigned xtot, ytot;
        unsigned long ht, vt;
 
-       if (!_dispc_lcd_timings_ok(timings->hsw, timings->hfp,
-                               timings->hbp, timings->vsw,
-                               timings->vfp, timings->vbp))
-               BUG();
+       DSSDBG("channel %d xres %u yres %u\n", channel, timings->x_res,
+                       timings->y_res);
 
-       _dispc_mgr_set_lcd_timings(channel, timings->hsw, timings->hfp,
-                       timings->hbp, timings->vsw, timings->vfp,
-                       timings->vbp);
+       if (!dispc_mgr_timings_ok(channel, timings))
+               BUG();
 
-       dispc_mgr_set_lcd_size(channel, timings->x_res, timings->y_res);
+       if (dispc_mgr_is_lcd(channel)) {
+               _dispc_mgr_set_lcd_timings(channel, timings->hsw, timings->hfp,
+                               timings->hbp, timings->vsw, timings->vfp,
+                               timings->vbp);
 
-       xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp;
-       ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp;
+               xtot = timings->x_res + timings->hfp + timings->hsw +
+                               timings->hbp;
+               ytot = timings->y_res + timings->vfp + timings->vsw +
+                               timings->vbp;
 
-       ht = (timings->pixel_clock * 1000) / xtot;
-       vt = (timings->pixel_clock * 1000) / xtot / ytot;
+               ht = (timings->pixel_clock * 1000) / xtot;
+               vt = (timings->pixel_clock * 1000) / xtot / ytot;
 
-       DSSDBG("channel %d xres %u yres %u\n", channel, timings->x_res,
-                       timings->y_res);
-       DSSDBG("pck %u\n", timings->pixel_clock);
-       DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
+               DSSDBG("pck %u\n", timings->pixel_clock);
+               DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
                        timings->hsw, timings->hfp, timings->hbp,
                        timings->vsw, timings->vfp, timings->vbp);
 
-       DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
+               DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
+       }
+
+       dispc_mgr_set_size(channel, timings->x_res, timings->y_res);
 }
 
 static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
@@ -2462,13 +2638,14 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
 
                return r / pcd;
        } else {
-               struct omap_dss_device *dssdev =
-                       dispc_mgr_get_device(channel);
+               enum dss_hdmi_venc_clk_source_select source;
 
-               switch (dssdev->type) {
-               case OMAP_DISPLAY_TYPE_VENC:
+               source = dss_get_hdmi_venc_clk_source();
+
+               switch (source) {
+               case DSS_VENC_TV_CLK:
                        return venc_get_pixel_clock();
-               case OMAP_DISPLAY_TYPE_HDMI:
+               case DSS_HDMI_M_PCLK:
                        return hdmi_get_pixel_clock();
                default:
                        BUG();
@@ -2476,6 +2653,19 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
        }
 }
 
+unsigned long dispc_core_clk_rate(void)
+{
+       int lcd;
+       unsigned long fclk = dispc_fclk_rate();
+
+       if (dss_has_feature(FEAT_CORE_CLK_DIV))
+               lcd = REG_GET(DISPC_DIVISOR, 23, 16);
+       else
+               lcd = REG_GET(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD), 23, 16);
+
+       return fclk / lcd;
+}
+
 void dispc_dump_clocks(struct seq_file *s)
 {
        int lcd, pcd;
@@ -3247,27 +3437,6 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
        return 0;
 }
 
-#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
-void dispc_fake_vsync_irq(void)
-{
-       u32 irqstatus = DISPC_IRQ_VSYNC;
-       int i;
-
-       WARN_ON(!in_interrupt());
-
-       for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
-               struct omap_dispc_isr_data *isr_data;
-               isr_data = &dispc.registered_isr[i];
-
-               if (!isr_data->isr)
-                       continue;
-
-               if (isr_data->mask & irqstatus)
-                       isr_data->isr(isr_data->arg, irqstatus);
-       }
-}
-#endif
-
 static void _omap_dispc_initialize_irq(void)
 {
        unsigned long flags;
index 4424c198dbcda6c3a34fa53189ecd28a5a446388..e688d10f061a976ab5c603e3578796cedb2a2914 100644 (file)
@@ -308,6 +308,13 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL(omapdss_default_get_recommended_bpp);
 
+void omapdss_default_get_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       *timings = dssdev->panel.timings;
+}
+EXPORT_SYMBOL(omapdss_default_get_timings);
+
 /* Checks if replication logic should be used. Only use for active matrix,
  * when overlay is in RGB12U or RGB16 mode, and LCD interface is
  * 18bpp or 24bpp */
index faaf305fda279615a6748ff0cfbbe78e315049a2..d6e8fe7761521df2e30850924053712dd2506e10 100644 (file)
@@ -156,7 +156,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
                t->pixel_clock = pck;
        }
 
-       dispc_mgr_set_lcd_timings(dssdev->manager->id, t);
+       dss_mgr_set_timings(dssdev->manager, t);
 
        return 0;
 }
@@ -294,10 +294,11 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
                }
 
                dpi_set_mode(dssdev);
-               dispc_mgr_go(dssdev->manager->id);
 
                dispc_runtime_put();
                dss_runtime_put();
+       } else {
+               dss_mgr_set_timings(dssdev->manager, timings);
        }
 }
 EXPORT_SYMBOL(dpi_set_timings);
@@ -312,7 +313,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
        unsigned long pck;
        struct dispc_clock_info dispc_cinfo;
 
-       if (!dispc_lcd_timings_ok(timings))
+       if (dss_mgr_check_timings(dssdev->manager, timings))
                return -EINVAL;
 
        if (timings->pixel_clock == 0)
index 210a3c4f615012662769010e37d6cd54e28e61e3..446e1366747118ffa90c47ec2ffa7c8d6c9f8ff0 100644 (file)
@@ -1279,10 +1279,9 @@ static int dsi_pll_power(struct platform_device *dsidev,
 }
 
 /* calculate clock rates using dividers in cinfo */
-static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
+static int dsi_calc_clock_rates(struct platform_device *dsidev,
                struct dsi_clock_info *cinfo)
 {
-       struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
        struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
        if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max)
@@ -1297,21 +1296,8 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
        if (cinfo->regm_dsi > dsi->regm_dsi_max)
                return -EINVAL;
 
-       if (cinfo->use_sys_clk) {
-               cinfo->clkin = clk_get_rate(dsi->sys_clk);
-               /* XXX it is unclear if highfreq should be used
-                * with DSS_SYS_CLK source also */
-               cinfo->highfreq = 0;
-       } else {
-               cinfo->clkin = dispc_mgr_pclk_rate(dssdev->manager->id);
-
-               if (cinfo->clkin < 32000000)
-                       cinfo->highfreq = 0;
-               else
-                       cinfo->highfreq = 1;
-       }
-
-       cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1));
+       cinfo->clkin = clk_get_rate(dsi->sys_clk);
+       cinfo->fint = cinfo->clkin / cinfo->regn;
 
        if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min)
                return -EINVAL;
@@ -1378,27 +1364,21 @@ retry:
 
        memset(&cur, 0, sizeof(cur));
        cur.clkin = dss_sys_clk;
-       cur.use_sys_clk = 1;
-       cur.highfreq = 0;
 
-       /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
-       /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
+       /* 0.75MHz < Fint = clkin / regn < 2.1MHz */
        /* To reduce PLL lock time, keep Fint high (around 2 MHz) */
        for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
-               if (cur.highfreq == 0)
-                       cur.fint = cur.clkin / cur.regn;
-               else
-                       cur.fint = cur.clkin / (2 * cur.regn);
+               cur.fint = cur.clkin / cur.regn;
 
                if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
                        continue;
 
-               /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
+               /* DSIPHY(MHz) = (2 * regm / regn) * clkin */
                for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
                        unsigned long a, b;
 
                        a = 2 * cur.regm * (cur.clkin/1000);
-                       b = cur.regn * (cur.highfreq + 1);
+                       b = cur.regn;
                        cur.clkin4ddr = a / b * 1000;
 
                        if (cur.clkin4ddr > 1800 * 1000 * 1000)
@@ -1486,9 +1466,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
 
        DSSDBGF();
 
-       dsi->current_cinfo.use_sys_clk = cinfo->use_sys_clk;
-       dsi->current_cinfo.highfreq = cinfo->highfreq;
-
+       dsi->current_cinfo.clkin = cinfo->clkin;
        dsi->current_cinfo.fint = cinfo->fint;
        dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr;
        dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk =
@@ -1503,17 +1481,13 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
 
        DSSDBG("DSI Fint %ld\n", cinfo->fint);
 
-       DSSDBG("clkin (%s) rate %ld, highfreq %d\n",
-                       cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree",
-                       cinfo->clkin,
-                       cinfo->highfreq);
+       DSSDBG("clkin rate %ld\n", cinfo->clkin);
 
        /* DSIPHY == CLKIN4DDR */
-       DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu / %d = %lu\n",
+       DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu = %lu\n",
                        cinfo->regm,
                        cinfo->regn,
                        cinfo->clkin,
-                       cinfo->highfreq + 1,
                        cinfo->clkin4ddr);
 
        DSSDBG("Data rate on 1 DSI lane %ld Mbps\n",
@@ -1568,10 +1542,6 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
 
        if (dss_has_feature(FEAT_DSI_PLL_FREQSEL))
                l = FLD_MOD(l, f, 4, 1);        /* DSI_PLL_FREQSEL */
-       l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1,
-                       11, 11);                /* DSI_PLL_CLKSEL */
-       l = FLD_MOD(l, cinfo->highfreq,
-                       12, 12);                /* DSI_PLL_HIGHFREQ */
        l = FLD_MOD(l, 1, 13, 13);              /* DSI_PLL_REFEN */
        l = FLD_MOD(l, 0, 14, 14);              /* DSIPHY_CLKINEN */
        l = FLD_MOD(l, 1, 20, 20);              /* DSI_HSDIVBYPASS */
@@ -1726,8 +1696,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
 
        seq_printf(s,   "- DSI%d PLL -\n", dsi_module + 1);
 
-       seq_printf(s,   "dsi pll source = %s\n",
-                       cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree");
+       seq_printf(s,   "dsi pll clkin\t%lu\n", cinfo->clkin);
 
        seq_printf(s,   "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
 
@@ -4192,10 +4161,6 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
        __cancel_delayed_work(&dsi->framedone_timeout_work);
 
        dsi_handle_framedone(dsidev, 0);
-
-#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
-       dispc_fake_vsync_irq();
-#endif
 }
 
 int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
@@ -4259,13 +4224,12 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
                dispc_mgr_enable_stallmode(dssdev->manager->id, true);
                dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1);
 
-               dispc_mgr_set_lcd_timings(dssdev->manager->id, &timings);
+               dss_mgr_set_timings(dssdev->manager, &timings);
        } else {
                dispc_mgr_enable_stallmode(dssdev->manager->id, false);
                dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0);
 
-               dispc_mgr_set_lcd_timings(dssdev->manager->id,
-                       &dssdev->panel.timings);
+               dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
        }
 
                dispc_mgr_set_lcd_display_type(dssdev->manager->id,
@@ -4294,13 +4258,11 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
        struct dsi_clock_info cinfo;
        int r;
 
-       /* we always use DSS_CLK_SYSCK as input clock */
-       cinfo.use_sys_clk = true;
        cinfo.regn  = dssdev->clocks.dsi.regn;
        cinfo.regm  = dssdev->clocks.dsi.regm;
        cinfo.regm_dispc = dssdev->clocks.dsi.regm_dispc;
        cinfo.regm_dsi = dssdev->clocks.dsi.regm_dsi;
-       r = dsi_calc_clock_rates(dssdev, &cinfo);
+       r = dsi_calc_clock_rates(dsidev, &cinfo);
        if (r) {
                DSSERR("Failed to calc dsi clocks\n");
                return r;
index bd2d5e159463c3c49a2f642a52814f8e8d83922f..e212acb1e7d5489de7a367e8b22098fec3afb5eb 100644 (file)
@@ -335,7 +335,7 @@ void dss_select_dsi_clk_source(int dsi_module,
                enum omap_dss_clk_source clk_src)
 {
        struct platform_device *dsidev;
-       int b;
+       int b, pos;
 
        switch (clk_src) {
        case OMAP_DSS_CLK_SRC_FCK:
@@ -357,7 +357,8 @@ void dss_select_dsi_clk_source(int dsi_module,
                BUG();
        }
 
-       REG_FLD_MOD(DSS_CONTROL, b, 1, 1);      /* DSI_CLK_SWITCH */
+       pos = dsi_module == 0 ? 1 : 10;
+       REG_FLD_MOD(DSS_CONTROL, b, pos, pos);  /* DSIx_CLK_SWITCH */
 
        dss.dsi_clk_source[dsi_module] = clk_src;
 }
@@ -829,11 +830,24 @@ static int omap_dsshw_remove(struct platform_device *pdev)
 static int dss_runtime_suspend(struct device *dev)
 {
        dss_save_context();
+       dss_set_min_bus_tput(dev, 0);
        return 0;
 }
 
 static int dss_runtime_resume(struct device *dev)
 {
+       int r;
+       /*
+        * Set an arbitrarily high tput request to ensure OPP100.
+        * What we should really do is to make a request to stay in OPP100,
+        * without any tput requirements, but that is not currently possible
+        * via the PM layer.
+        */
+
+       r = dss_set_min_bus_tput(dev, 1000000000);
+       if (r)
+               return r;
+
        dss_restore_context();
        return 0;
 }
index d4b3dff2ead338db918ce4801ac7380966f6b679..8e9e9a5765fad0b6994be332d29de11a03a753bd 100644 (file)
@@ -150,9 +150,6 @@ struct dsi_clock_info {
        u16 regm_dsi;   /* OMAP3: REGM4
                         * OMAP4: REGM5 */
        u16 lp_clk_div;
-
-       u8 highfreq;
-       bool use_sys_clk;
 };
 
 struct seq_file;
@@ -162,6 +159,7 @@ struct platform_device;
 struct bus_type *dss_get_bus(void);
 struct regulator *dss_get_vdds_dsi(void);
 struct regulator *dss_get_vdds_sdi(void);
+int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
 
 /* apply */
 void dss_apply_init(void);
@@ -179,6 +177,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
 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);
+void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
+               struct omap_video_timings *timings);
+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);
@@ -208,9 +209,11 @@ int dss_init_overlay_managers(struct platform_device *pdev);
 void dss_uninit_overlay_managers(struct platform_device *pdev);
 int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
                const struct omap_overlay_manager_info *info);
+int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
+               const struct omap_video_timings *timings);
 int dss_mgr_check(struct omap_overlay_manager *mgr,
-               struct omap_dss_device *dssdev,
                struct omap_overlay_manager_info *info,
+               const struct omap_video_timings *mgr_timings,
                struct omap_overlay_info **overlay_infos);
 
 /* overlay */
@@ -220,8 +223,8 @@ void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
 void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
 int dss_ovl_simple_check(struct omap_overlay *ovl,
                const struct omap_overlay_info *info);
-int dss_ovl_check(struct omap_overlay *ovl,
-               struct omap_overlay_info *info, struct omap_dss_device *dssdev);
+int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
+               const struct omap_video_timings *mgr_timings);
 
 /* DSS */
 int dss_init_platform_driver(void);
@@ -398,7 +401,6 @@ void dispc_dump_clocks(struct seq_file *s);
 void dispc_dump_irqs(struct seq_file *s);
 void dispc_dump_regs(struct seq_file *s);
 void dispc_irq_handler(void);
-void dispc_fake_vsync_irq(void);
 
 int dispc_runtime_get(void);
 void dispc_runtime_put(void);
@@ -409,12 +411,12 @@ 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_set_digit_size(u16 width, u16 height);
 void dispc_enable_fifomerge(bool enable);
 void dispc_enable_gamma_table(bool enable);
 void dispc_set_loadmode(enum omap_dss_load_mode mode);
 
-bool dispc_lcd_timings_ok(struct omap_video_timings *timings);
+bool dispc_mgr_timings_ok(enum omap_channel channel,
+               const struct omap_video_timings *timings);
 unsigned long dispc_fclk_rate(void);
 void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
                struct dispc_clock_info *cinfo);
@@ -426,13 +428,13 @@ 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);
 int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
-               bool ilace, bool replication);
+               bool ilace, bool replication,
+               const struct omap_video_timings *mgr_timings);
 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);
-void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
 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);
@@ -445,12 +447,13 @@ 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_display_type(enum omap_channel channel,
                enum omap_lcd_display_type type);
-void dispc_mgr_set_lcd_timings(enum omap_channel channel,
+void dispc_mgr_set_timings(enum omap_channel channel,
                struct omap_video_timings *timings);
 void dispc_mgr_set_pol_freq(enum omap_channel channel,
                enum omap_panel_config config, u8 acbi, u8 acb);
 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);
 int dispc_mgr_set_clock_div(enum omap_channel channel,
                struct dispc_clock_info *cinfo);
 int dispc_mgr_get_clock_div(enum omap_channel channel,
index ce14aa6dd672802dd61659cdfb13201c8fabba0c..1d10a014bc55795c0053765ec8c47640521b5372 100644 (file)
@@ -311,6 +311,8 @@ 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[] = {
@@ -324,6 +326,8 @@ static const struct dss_param_range omap3_dss_param_range[] = {
        [FEAT_PARAM_DSIPLL_LPDIV]               = { 1, (1 << 13) - 1},
        [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[] = {
@@ -337,6 +341,8 @@ static const struct dss_param_range omap4_dss_param_range[] = {
        [FEAT_PARAM_DSIPLL_LPDIV]               = { 0, (1 << 13) - 1 },
        [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[] = {
index c332e7ddfce14dfedfecad805f1eae2c5478d27e..3736367089a168c3f8275e4daa69b49983d1d97d 100644 (file)
@@ -91,6 +91,8 @@ enum dss_range_param {
        FEAT_PARAM_DSIPLL_LPDIV,
        FEAT_PARAM_DOWNSCALE,
        FEAT_PARAM_LINEWIDTH,
+       FEAT_PARAM_MGR_WIDTH,
+       FEAT_PARAM_MGR_HEIGHT,
 };
 
 /* DSS Feature Functions */
index c4b4f6950a9269a925b8617865f4a4a87fb89d06..32ad7124a9523623691b6913d2bd2454986ac3b2 100644 (file)
@@ -376,8 +376,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
        dispc_enable_gamma_table(0);
 
        /* tv size */
-       dispc_set_digit_size(dssdev->panel.timings.x_res,
-                       dssdev->panel.timings.y_res);
+       dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
 
        hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
 
@@ -436,6 +435,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
                r = hdmi_power_on(dssdev);
                if (r)
                        DSSERR("failed to power on device\n");
+       } else {
+               dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
        }
 }
 
index e7364603f6a1d09fa193e63ed007565388090e1b..0cbcde4c688a9e40925daf5c12f960f6bb75473b 100644 (file)
@@ -654,9 +654,20 @@ static int dss_mgr_check_zorder(struct omap_overlay_manager *mgr,
        return 0;
 }
 
+int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
+               const struct omap_video_timings *timings)
+{
+       if (!dispc_mgr_timings_ok(mgr->id, timings)) {
+               DSSERR("check_manager: invalid timings\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 int dss_mgr_check(struct omap_overlay_manager *mgr,
-               struct omap_dss_device *dssdev,
                struct omap_overlay_manager_info *info,
+               const struct omap_video_timings *mgr_timings,
                struct omap_overlay_info **overlay_infos)
 {
        struct omap_overlay *ovl;
@@ -668,6 +679,10 @@ int dss_mgr_check(struct omap_overlay_manager *mgr,
                        return r;
        }
 
+       r = dss_mgr_check_timings(mgr, mgr_timings);
+       if (r)
+               return r;
+
        list_for_each_entry(ovl, &mgr->overlays, list) {
                struct omap_overlay_info *oi;
                int r;
@@ -677,7 +692,7 @@ int dss_mgr_check(struct omap_overlay_manager *mgr,
                if (oi == NULL)
                        continue;
 
-               r = dss_ovl_check(ovl, oi, dssdev);
+               r = dss_ovl_check(ovl, oi, mgr_timings);
                if (r)
                        return r;
        }
index 6e821810deec092324a0f1013fbb3cb32bba72dd..0da5eb654ae9216ec548c24b55bb6802752cfc31 100644 (file)
@@ -631,16 +631,14 @@ int dss_ovl_simple_check(struct omap_overlay *ovl,
        return 0;
 }
 
-int dss_ovl_check(struct omap_overlay *ovl,
-               struct omap_overlay_info *info, struct omap_dss_device *dssdev)
+int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
+               const struct omap_video_timings *mgr_timings)
 {
        u16 outw, outh;
        u16 dw, dh;
 
-       if (dssdev == NULL)
-               return 0;
-
-       dssdev->driver->get_resolution(dssdev, &dw, &dh);
+       dw = mgr_timings->x_res;
+       dh = mgr_timings->y_res;
 
        if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
                outw = info->width;
index 788a0ef6323aef6e2784244b1825c5b72965abc5..feadfab27ec2500de3249d818b9b2800a3d4e69d 100644 (file)
@@ -304,13 +304,23 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
                u16 height, void (*callback)(void *data), void *data)
 {
        u32 l;
+       struct omap_video_timings timings = {
+               .hsw            = 1,
+               .hfp            = 1,
+               .hbp            = 1,
+               .vsw            = 1,
+               .vfp            = 0,
+               .vbp            = 0,
+               .x_res          = width,
+               .y_res          = height,
+       };
 
        /*BUG_ON(callback == 0);*/
        BUG_ON(rfbi.framedone_callback != NULL);
 
        DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
 
-       dispc_mgr_set_lcd_size(dssdev->manager->id, width, height);
+       dss_mgr_set_timings(dssdev->manager, &timings);
 
        dispc_mgr_enable(dssdev->manager->id, true);
 
@@ -766,6 +776,16 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
                u16 *x, u16 *y, u16 *w, u16 *h)
 {
        u16 dw, dh;
+       struct omap_video_timings timings = {
+               .hsw            = 1,
+               .hfp            = 1,
+               .hbp            = 1,
+               .vsw            = 1,
+               .vfp            = 0,
+               .vbp            = 0,
+               .x_res          = *w,
+               .y_res          = *h,
+       };
 
        dssdev->driver->get_resolution(dssdev, &dw, &dh);
 
@@ -784,7 +804,7 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
        if (*w == 0 || *h == 0)
                return -EINVAL;
 
-       dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
+       dss_mgr_set_timings(dssdev->manager, &timings);
 
        return 0;
 }
index 8266ca0d666bc2de7547a12c38eca9dc98aba11a..67fbe7cee412b40eaee1eca8e7540a1a1e1ab920 100644 (file)
@@ -107,7 +107,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
        }
 
 
-       dispc_mgr_set_lcd_timings(dssdev->manager->id, t);
+       dss_mgr_set_timings(dssdev->manager, t);
 
        r = dss_set_clock_div(&dss_cinfo);
        if (r)
index bfe6fe65c8becf4fa2bf0ed671612623effeeb19..35f59e47d7fe522df5eab6e7f053e3501125a40d 100644 (file)
@@ -886,10 +886,12 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)
 
 #define CORE_REG(i, name) name(i)
 #define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\
-               hdmi_read_reg(hdmi_pll_base(ip_data), r))
-#define DUMPCOREAV(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \
+               hdmi_read_reg(hdmi_core_sys_base(ip_data), r))
+#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), " ", \
-               hdmi_read_reg(hdmi_pll_base(ip_data), CORE_REG(i, r)))
+               hdmi_read_reg(hdmi_av_base(ip_data), CORE_REG(i, r)))
 
        DUMPCORE(HDMI_CORE_SYS_VND_IDL);
        DUMPCORE(HDMI_CORE_SYS_DEV_IDL);
@@ -898,6 +900,13 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)
        DUMPCORE(HDMI_CORE_SYS_SRST);
        DUMPCORE(HDMI_CORE_CTRL1);
        DUMPCORE(HDMI_CORE_SYS_SYS_STAT);
+       DUMPCORE(HDMI_CORE_SYS_DE_DLY);
+       DUMPCORE(HDMI_CORE_SYS_DE_CTRL);
+       DUMPCORE(HDMI_CORE_SYS_DE_TOP);
+       DUMPCORE(HDMI_CORE_SYS_DE_CNTL);
+       DUMPCORE(HDMI_CORE_SYS_DE_CNTH);
+       DUMPCORE(HDMI_CORE_SYS_DE_LINL);
+       DUMPCORE(HDMI_CORE_SYS_DE_LINH_1);
        DUMPCORE(HDMI_CORE_SYS_VID_ACEN);
        DUMPCORE(HDMI_CORE_SYS_VID_MODE);
        DUMPCORE(HDMI_CORE_SYS_INTR_STATE);
@@ -907,102 +916,91 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)
        DUMPCORE(HDMI_CORE_SYS_INTR4);
        DUMPCORE(HDMI_CORE_SYS_UMASK1);
        DUMPCORE(HDMI_CORE_SYS_TMDS_CTRL);
-       DUMPCORE(HDMI_CORE_SYS_DE_DLY);
-       DUMPCORE(HDMI_CORE_SYS_DE_CTRL);
-       DUMPCORE(HDMI_CORE_SYS_DE_TOP);
-       DUMPCORE(HDMI_CORE_SYS_DE_CNTL);
-       DUMPCORE(HDMI_CORE_SYS_DE_CNTH);
-       DUMPCORE(HDMI_CORE_SYS_DE_LINL);
-       DUMPCORE(HDMI_CORE_SYS_DE_LINH_1);
 
-       DUMPCORE(HDMI_CORE_DDC_CMD);
-       DUMPCORE(HDMI_CORE_DDC_STATUS);
        DUMPCORE(HDMI_CORE_DDC_ADDR);
+       DUMPCORE(HDMI_CORE_DDC_SEGM);
        DUMPCORE(HDMI_CORE_DDC_OFFSET);
        DUMPCORE(HDMI_CORE_DDC_COUNT1);
        DUMPCORE(HDMI_CORE_DDC_COUNT2);
+       DUMPCORE(HDMI_CORE_DDC_STATUS);
+       DUMPCORE(HDMI_CORE_DDC_CMD);
        DUMPCORE(HDMI_CORE_DDC_DATA);
-       DUMPCORE(HDMI_CORE_DDC_SEGM);
 
-       DUMPCORE(HDMI_CORE_AV_HDMI_CTRL);
-       DUMPCORE(HDMI_CORE_AV_DPD);
-       DUMPCORE(HDMI_CORE_AV_PB_CTRL1);
-       DUMPCORE(HDMI_CORE_AV_PB_CTRL2);
-       DUMPCORE(HDMI_CORE_AV_AVI_TYPE);
-       DUMPCORE(HDMI_CORE_AV_AVI_VERS);
-       DUMPCORE(HDMI_CORE_AV_AVI_LEN);
-       DUMPCORE(HDMI_CORE_AV_AVI_CHSUM);
+       DUMPCOREAV(HDMI_CORE_AV_ACR_CTRL);
+       DUMPCOREAV(HDMI_CORE_AV_FREQ_SVAL);
+       DUMPCOREAV(HDMI_CORE_AV_N_SVAL1);
+       DUMPCOREAV(HDMI_CORE_AV_N_SVAL2);
+       DUMPCOREAV(HDMI_CORE_AV_N_SVAL3);
+       DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL1);
+       DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL2);
+       DUMPCOREAV(HDMI_CORE_AV_CTS_SVAL3);
+       DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL1);
+       DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL2);
+       DUMPCOREAV(HDMI_CORE_AV_CTS_HVAL3);
+       DUMPCOREAV(HDMI_CORE_AV_AUD_MODE);
+       DUMPCOREAV(HDMI_CORE_AV_SPDIF_CTRL);
+       DUMPCOREAV(HDMI_CORE_AV_HW_SPDIF_FS);
+       DUMPCOREAV(HDMI_CORE_AV_SWAP_I2S);
+       DUMPCOREAV(HDMI_CORE_AV_SPDIF_ERTH);
+       DUMPCOREAV(HDMI_CORE_AV_I2S_IN_MAP);
+       DUMPCOREAV(HDMI_CORE_AV_I2S_IN_CTRL);
+       DUMPCOREAV(HDMI_CORE_AV_I2S_CHST0);
+       DUMPCOREAV(HDMI_CORE_AV_I2S_CHST1);
+       DUMPCOREAV(HDMI_CORE_AV_I2S_CHST2);
+       DUMPCOREAV(HDMI_CORE_AV_I2S_CHST4);
+       DUMPCOREAV(HDMI_CORE_AV_I2S_CHST5);
+       DUMPCOREAV(HDMI_CORE_AV_ASRC);
+       DUMPCOREAV(HDMI_CORE_AV_I2S_IN_LEN);
+       DUMPCOREAV(HDMI_CORE_AV_HDMI_CTRL);
+       DUMPCOREAV(HDMI_CORE_AV_AUDO_TXSTAT);
+       DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_1);
+       DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_2);
+       DUMPCOREAV(HDMI_CORE_AV_AUD_PAR_BUSCLK_3);
+       DUMPCOREAV(HDMI_CORE_AV_TEST_TXCTRL);
+       DUMPCOREAV(HDMI_CORE_AV_DPD);
+       DUMPCOREAV(HDMI_CORE_AV_PB_CTRL1);
+       DUMPCOREAV(HDMI_CORE_AV_PB_CTRL2);
+       DUMPCOREAV(HDMI_CORE_AV_AVI_TYPE);
+       DUMPCOREAV(HDMI_CORE_AV_AVI_VERS);
+       DUMPCOREAV(HDMI_CORE_AV_AVI_LEN);
+       DUMPCOREAV(HDMI_CORE_AV_AVI_CHSUM);
 
        for (i = 0; i < HDMI_CORE_AV_AVI_DBYTE_NELEMS; i++)
-               DUMPCOREAV(i, HDMI_CORE_AV_AVI_DBYTE);
+               DUMPCOREAV2(i, HDMI_CORE_AV_AVI_DBYTE);
+
+       DUMPCOREAV(HDMI_CORE_AV_SPD_TYPE);
+       DUMPCOREAV(HDMI_CORE_AV_SPD_VERS);
+       DUMPCOREAV(HDMI_CORE_AV_SPD_LEN);
+       DUMPCOREAV(HDMI_CORE_AV_SPD_CHSUM);
 
        for (i = 0; i < HDMI_CORE_AV_SPD_DBYTE_NELEMS; i++)
-               DUMPCOREAV(i, HDMI_CORE_AV_SPD_DBYTE);
+               DUMPCOREAV2(i, HDMI_CORE_AV_SPD_DBYTE);
+
+       DUMPCOREAV(HDMI_CORE_AV_AUDIO_TYPE);
+       DUMPCOREAV(HDMI_CORE_AV_AUDIO_VERS);
+       DUMPCOREAV(HDMI_CORE_AV_AUDIO_LEN);
+       DUMPCOREAV(HDMI_CORE_AV_AUDIO_CHSUM);
 
        for (i = 0; i < HDMI_CORE_AV_AUD_DBYTE_NELEMS; i++)
-               DUMPCOREAV(i, HDMI_CORE_AV_AUD_DBYTE);
+               DUMPCOREAV2(i, HDMI_CORE_AV_AUD_DBYTE);
+
+       DUMPCOREAV(HDMI_CORE_AV_MPEG_TYPE);
+       DUMPCOREAV(HDMI_CORE_AV_MPEG_VERS);
+       DUMPCOREAV(HDMI_CORE_AV_MPEG_LEN);
+       DUMPCOREAV(HDMI_CORE_AV_MPEG_CHSUM);
 
        for (i = 0; i < HDMI_CORE_AV_MPEG_DBYTE_NELEMS; i++)
-               DUMPCOREAV(i, HDMI_CORE_AV_MPEG_DBYTE);
+               DUMPCOREAV2(i, HDMI_CORE_AV_MPEG_DBYTE);
 
        for (i = 0; i < HDMI_CORE_AV_GEN_DBYTE_NELEMS; i++)
-               DUMPCOREAV(i, HDMI_CORE_AV_GEN_DBYTE);
+               DUMPCOREAV2(i, HDMI_CORE_AV_GEN_DBYTE);
+
+       DUMPCOREAV(HDMI_CORE_AV_CP_BYTE1);
 
        for (i = 0; i < HDMI_CORE_AV_GEN2_DBYTE_NELEMS; i++)
-               DUMPCOREAV(i, HDMI_CORE_AV_GEN2_DBYTE);
-
-       DUMPCORE(HDMI_CORE_AV_ACR_CTRL);
-       DUMPCORE(HDMI_CORE_AV_FREQ_SVAL);
-       DUMPCORE(HDMI_CORE_AV_N_SVAL1);
-       DUMPCORE(HDMI_CORE_AV_N_SVAL2);
-       DUMPCORE(HDMI_CORE_AV_N_SVAL3);
-       DUMPCORE(HDMI_CORE_AV_CTS_SVAL1);
-       DUMPCORE(HDMI_CORE_AV_CTS_SVAL2);
-       DUMPCORE(HDMI_CORE_AV_CTS_SVAL3);
-       DUMPCORE(HDMI_CORE_AV_CTS_HVAL1);
-       DUMPCORE(HDMI_CORE_AV_CTS_HVAL2);
-       DUMPCORE(HDMI_CORE_AV_CTS_HVAL3);
-       DUMPCORE(HDMI_CORE_AV_AUD_MODE);
-       DUMPCORE(HDMI_CORE_AV_SPDIF_CTRL);
-       DUMPCORE(HDMI_CORE_AV_HW_SPDIF_FS);
-       DUMPCORE(HDMI_CORE_AV_SWAP_I2S);
-       DUMPCORE(HDMI_CORE_AV_SPDIF_ERTH);
-       DUMPCORE(HDMI_CORE_AV_I2S_IN_MAP);
-       DUMPCORE(HDMI_CORE_AV_I2S_IN_CTRL);
-       DUMPCORE(HDMI_CORE_AV_I2S_CHST0);
-       DUMPCORE(HDMI_CORE_AV_I2S_CHST1);
-       DUMPCORE(HDMI_CORE_AV_I2S_CHST2);
-       DUMPCORE(HDMI_CORE_AV_I2S_CHST4);
-       DUMPCORE(HDMI_CORE_AV_I2S_CHST5);
-       DUMPCORE(HDMI_CORE_AV_ASRC);
-       DUMPCORE(HDMI_CORE_AV_I2S_IN_LEN);
-       DUMPCORE(HDMI_CORE_AV_HDMI_CTRL);
-       DUMPCORE(HDMI_CORE_AV_AUDO_TXSTAT);
-       DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_1);
-       DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_2);
-       DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_3);
-       DUMPCORE(HDMI_CORE_AV_TEST_TXCTRL);
-       DUMPCORE(HDMI_CORE_AV_DPD);
-       DUMPCORE(HDMI_CORE_AV_PB_CTRL1);
-       DUMPCORE(HDMI_CORE_AV_PB_CTRL2);
-       DUMPCORE(HDMI_CORE_AV_AVI_TYPE);
-       DUMPCORE(HDMI_CORE_AV_AVI_VERS);
-       DUMPCORE(HDMI_CORE_AV_AVI_LEN);
-       DUMPCORE(HDMI_CORE_AV_AVI_CHSUM);
-       DUMPCORE(HDMI_CORE_AV_SPD_TYPE);
-       DUMPCORE(HDMI_CORE_AV_SPD_VERS);
-       DUMPCORE(HDMI_CORE_AV_SPD_LEN);
-       DUMPCORE(HDMI_CORE_AV_SPD_CHSUM);
-       DUMPCORE(HDMI_CORE_AV_AUDIO_TYPE);
-       DUMPCORE(HDMI_CORE_AV_AUDIO_VERS);
-       DUMPCORE(HDMI_CORE_AV_AUDIO_LEN);
-       DUMPCORE(HDMI_CORE_AV_AUDIO_CHSUM);
-       DUMPCORE(HDMI_CORE_AV_MPEG_TYPE);
-       DUMPCORE(HDMI_CORE_AV_MPEG_VERS);
-       DUMPCORE(HDMI_CORE_AV_MPEG_LEN);
-       DUMPCORE(HDMI_CORE_AV_MPEG_CHSUM);
-       DUMPCORE(HDMI_CORE_AV_CP_BYTE1);
-       DUMPCORE(HDMI_CORE_AV_CEC_ADDR_ID);
+               DUMPCOREAV2(i, HDMI_CORE_AV_GEN2_DBYTE);
+
+       DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID);
 }
 
 void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)
index a14d1a0e6e4146d00a70a88645d7292ea1793288..b724bc68307a438f846dcbbaf475dd9a0f04d7ab 100644 (file)
 #define HDMI_CORE_SYS_SRST                     0x14
 #define HDMI_CORE_CTRL1                                0x20
 #define HDMI_CORE_SYS_SYS_STAT                 0x24
+#define HDMI_CORE_SYS_DE_DLY                   0xC8
+#define HDMI_CORE_SYS_DE_CTRL                  0xCC
+#define HDMI_CORE_SYS_DE_TOP                   0xD0
+#define HDMI_CORE_SYS_DE_CNTL                  0xD8
+#define HDMI_CORE_SYS_DE_CNTH                  0xDC
+#define HDMI_CORE_SYS_DE_LINL                  0xE0
+#define HDMI_CORE_SYS_DE_LINH_1                        0xE4
 #define HDMI_CORE_SYS_VID_ACEN                 0x124
 #define HDMI_CORE_SYS_VID_MODE                 0x128
 #define HDMI_CORE_SYS_INTR_STATE               0x1C0
 #define HDMI_CORE_SYS_INTR4                    0x1D0
 #define HDMI_CORE_SYS_UMASK1                   0x1D4
 #define HDMI_CORE_SYS_TMDS_CTRL                        0x208
-#define HDMI_CORE_SYS_DE_DLY                   0xC8
-#define HDMI_CORE_SYS_DE_CTRL                  0xCC
-#define HDMI_CORE_SYS_DE_TOP                   0xD0
-#define HDMI_CORE_SYS_DE_CNTL                  0xD8
-#define HDMI_CORE_SYS_DE_CNTH                  0xDC
-#define HDMI_CORE_SYS_DE_LINL                  0xE0
-#define HDMI_CORE_SYS_DE_LINH_1                        0xE4
+
 #define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC        0x1
 #define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC        0x1
-#define HDMI_CORE_CTRL1_BSEL_24BITBUS          0x1
+#define HDMI_CORE_CTRL1_BSEL_24BITBUS  0x1
 #define HDMI_CORE_CTRL1_EDGE_RISINGEDGE        0x1
 
 /* HDMI DDC E-DID */
-#define HDMI_CORE_DDC_CMD                      0x3CC
-#define HDMI_CORE_DDC_STATUS                   0x3C8
 #define HDMI_CORE_DDC_ADDR                     0x3B4
+#define HDMI_CORE_DDC_SEGM                     0x3B8
 #define HDMI_CORE_DDC_OFFSET                   0x3BC
 #define HDMI_CORE_DDC_COUNT1                   0x3C0
 #define HDMI_CORE_DDC_COUNT2                   0x3C4
+#define HDMI_CORE_DDC_STATUS                   0x3C8
+#define HDMI_CORE_DDC_CMD                      0x3CC
 #define HDMI_CORE_DDC_DATA                     0x3D0
-#define HDMI_CORE_DDC_SEGM                     0x3B8
 
 /* HDMI IP Core Audio Video */
 
-#define HDMI_CORE_AV_HDMI_CTRL                 0xBC
-#define HDMI_CORE_AV_DPD                       0xF4
-#define HDMI_CORE_AV_PB_CTRL1                  0xF8
-#define HDMI_CORE_AV_PB_CTRL2                  0xFC
-#define HDMI_CORE_AV_AVI_TYPE                  0x100
-#define HDMI_CORE_AV_AVI_VERS                  0x104
-#define HDMI_CORE_AV_AVI_LEN                   0x108
-#define HDMI_CORE_AV_AVI_CHSUM                 0x10C
-#define HDMI_CORE_AV_AVI_DBYTE(n)              (n * 4 + 0x110)
-#define HDMI_CORE_AV_AVI_DBYTE_NELEMS          15
-#define HDMI_CORE_AV_SPD_DBYTE(n)              (n * 4 + 0x190)
-#define HDMI_CORE_AV_SPD_DBYTE_NELEMS          27
-#define HDMI_CORE_AV_AUD_DBYTE(n)              (n * 4 + 0x210)
-#define HDMI_CORE_AV_AUD_DBYTE_NELEMS          10
-#define HDMI_CORE_AV_MPEG_DBYTE(n)             (n * 4 + 0x290)
-#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS         27
-#define HDMI_CORE_AV_GEN_DBYTE(n)              (n * 4 + 0x300)
-#define HDMI_CORE_AV_GEN_DBYTE_NELEMS          31
-#define HDMI_CORE_AV_GEN2_DBYTE(n)             (n * 4 + 0x380)
-#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS         31
 #define HDMI_CORE_AV_ACR_CTRL                  0x4
 #define HDMI_CORE_AV_FREQ_SVAL                 0x8
 #define HDMI_CORE_AV_N_SVAL1                   0xC
 #define HDMI_CORE_AV_AVI_VERS                  0x104
 #define HDMI_CORE_AV_AVI_LEN                   0x108
 #define HDMI_CORE_AV_AVI_CHSUM                 0x10C
+#define HDMI_CORE_AV_AVI_DBYTE(n)              (n * 4 + 0x110)
 #define HDMI_CORE_AV_SPD_TYPE                  0x180
 #define HDMI_CORE_AV_SPD_VERS                  0x184
 #define HDMI_CORE_AV_SPD_LEN                   0x188
 #define HDMI_CORE_AV_SPD_CHSUM                 0x18C
+#define HDMI_CORE_AV_SPD_DBYTE(n)              (n * 4 + 0x190)
 #define HDMI_CORE_AV_AUDIO_TYPE                        0x200
 #define HDMI_CORE_AV_AUDIO_VERS                        0x204
 #define HDMI_CORE_AV_AUDIO_LEN                 0x208
 #define HDMI_CORE_AV_AUDIO_CHSUM               0x20C
+#define HDMI_CORE_AV_AUD_DBYTE(n)              (n * 4 + 0x210)
 #define HDMI_CORE_AV_MPEG_TYPE                 0x280
 #define HDMI_CORE_AV_MPEG_VERS                 0x284
 #define HDMI_CORE_AV_MPEG_LEN                  0x288
 #define HDMI_CORE_AV_MPEG_CHSUM                        0x28C
+#define HDMI_CORE_AV_MPEG_DBYTE(n)             (n * 4 + 0x290)
+#define HDMI_CORE_AV_GEN_DBYTE(n)              (n * 4 + 0x300)
 #define HDMI_CORE_AV_CP_BYTE1                  0x37C
+#define HDMI_CORE_AV_GEN2_DBYTE(n)             (n * 4 + 0x380)
 #define HDMI_CORE_AV_CEC_ADDR_ID               0x3FC
+
 #define HDMI_CORE_AV_SPD_DBYTE_ELSIZE          0x4
 #define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE         0x4
 #define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE         0x4
 #define HDMI_CORE_AV_GEN_DBYTE_ELSIZE          0x4
 
+#define HDMI_CORE_AV_AVI_DBYTE_NELEMS          15
+#define HDMI_CORE_AV_SPD_DBYTE_NELEMS          27
+#define HDMI_CORE_AV_AUD_DBYTE_NELEMS          10
+#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS         27
+#define HDMI_CORE_AV_GEN_DBYTE_NELEMS          31
+#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS         31
+
 /* PLL */
 
 #define PLLCTRL_PLL_CONTROL                    0x0
index 9c3daf71750c769057d3a03f05019e950a3b5ed8..e2374645a44243dc44be4bce48f584c765838f11 100644 (file)
@@ -421,6 +421,7 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 {
        u32 l;
        int r;
+       struct omap_video_timings timings;
 
        venc_reset();
        venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
@@ -440,10 +441,14 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 
        venc_write_reg(VENC_OUTPUT_CONTROL, l);
 
-       dispc_set_digit_size(dssdev->panel.timings.x_res,
-                       dssdev->panel.timings.y_res/2);
+       timings = dssdev->panel.timings;
+       timings.y_res /= 2;
 
-       regulator_enable(venc.vdda_dac_reg);
+       dss_mgr_set_timings(dssdev->manager, &timings);
+
+       r = regulator_enable(venc.vdda_dac_reg);
+       if (r)
+               goto err;
 
        if (dssdev->platform_enable)
                dssdev->platform_enable(dssdev);
@@ -577,12 +582,6 @@ static int venc_panel_resume(struct omap_dss_device *dssdev)
        return venc_panel_enable(dssdev);
 }
 
-static void venc_get_timings(struct omap_dss_device *dssdev,
-                       struct omap_video_timings *timings)
-{
-       *timings = dssdev->panel.timings;
-}
-
 static void venc_set_timings(struct omap_dss_device *dssdev,
                        struct omap_video_timings *timings)
 {
@@ -661,7 +660,6 @@ static struct omap_dss_driver venc_driver = {
        .get_resolution = omapdss_default_get_resolution,
        .get_recommended_bpp = omapdss_default_get_recommended_bpp,
 
-       .get_timings    = venc_get_timings,
        .set_timings    = venc_set_timings,
        .check_timings  = venc_check_timings,
 
index 6a09ef87e14fae9886461bb7855c9d97350707e0..27a85813c6001e147ad065b5580df4d5370d1010 100644 (file)
@@ -225,6 +225,9 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
        down_write_nested(&rg->lock, rg->id);
        atomic_inc(&rg->lock_count);
 
+       if (rg->size == size && rg->type == mi->type)
+               goto out;
+
        if (atomic_read(&rg->map_count)) {
                r = -EBUSY;
                goto out;
@@ -247,12 +250,10 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
                }
        }
 
-       if (rg->size != size || rg->type != mi->type) {
-               r = omapfb_realloc_fbmem(fbi, size, mi->type);
-               if (r) {
-                       dev_err(fbdev->dev, "realloc fbmem failed\n");
-                       goto out;
-               }
+       r = omapfb_realloc_fbmem(fbi, size, mi->type);
+       if (r) {
+               dev_err(fbdev->dev, "realloc fbmem failed\n");
+               goto out;
        }
 
  out:
index 1c46a14341dd9892816a4398a274a7aa43cb5db1..1cbb2dd5fbba52c8c37837da7fa41de7a0232f0e 100644 (file)
@@ -309,6 +309,7 @@ struct omap_dss_board_info {
        struct omap_dss_device *default_device;
        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);
 };
 
 /* Init with the board info */
@@ -670,6 +671,8 @@ struct omap_overlay *omap_dss_get_overlay(int num);
 void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
                u16 *xres, u16 *yres);
 int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
+void omapdss_default_get_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings);
 
 typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
 int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);