OMAP: DSS2: Introduce omap_channel as an omap_dss_device parameter, add new overlay...
authorSumit Semwal <sumit.semwal@ti.com>
Thu, 2 Dec 2010 11:27:14 +0000 (11:27 +0000)
committerTomi Valkeinen <tomi.valkeinen@nokia.com>
Mon, 10 Jan 2011 09:36:51 +0000 (11:36 +0200)
A panel connects to one of the overlay managers of DSS through some interface block.
On OMAP4, specifying the type of the display is not sufficient to conclude which manager
the panel should be connected to.
Hence, a new member 'channel' is introduced in omap_dss_device structure to determine
which manager the panel uses. The dss_recheck_connections() called in dss_driver_probe()
uses this channel parameter to set the correct manager to the corresponding omap_dss_device.

The channel parameter is used only once to ensure the correct managers are set for each
panel. The parameter dssdev->manager->id will take care of ensuring that the panel and
then the interface driver configures the correct DISPC channel.

Also, add a new Overlay Manager in manager.c, make other changes needed for LCD2 channel.

Signed-off-by: Sumit Semwal <sumit.semwal@ti.com>
Signed-off-by: Mukund Mittal <mmittal@ti.com>
Signed-off-by: Samreen <samreen@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
arch/arm/plat-omap/include/plat/display.h
drivers/video/omap2/dss/dispc.c
drivers/video/omap2/dss/dss.h
drivers/video/omap2/dss/manager.c
drivers/video/omap2/dss/overlay.c

index 0180f25d1c8bf8d2270e2e93adc9dd502a5b7ed4..537f4e449f50b429b05f3c21ac74e9f7920b18c9 100644 (file)
@@ -358,6 +358,8 @@ struct omap_dss_device {
 
        enum omap_display_type type;
 
+       enum omap_channel channel;
+
        union {
                struct {
                        u8 data_lines;
index 6171bcc589f802ec1f3b8f514d34e0cd56cf8418..9f8c69f16e619dd1eec954f5ae5eba13c659ec06 100644 (file)
@@ -1610,8 +1610,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
                bool ilace,
                enum omap_dss_rotation_type rotation_type,
                u8 rotation, int mirror,
-               u8 global_alpha,
-               u8 pre_mult_alpha)
+               u8 global_alpha, u8 pre_mult_alpha,
+               enum omap_channel channel)
 {
        const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
        bool five_taps = 0;
@@ -1667,8 +1667,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
                five_taps = height > out_height * 2;
 
                if (!five_taps) {
-                       fclk = calc_fclk(OMAP_DSS_CHANNEL_LCD, width, height,
-                                       out_width, out_height);
+                       fclk = calc_fclk(channel, width, height, out_width,
+                                       out_height);
 
                        /* Try 5-tap filter if 3-tap fclk is too high */
                        if (cpu_is_omap34xx() && height > out_height &&
@@ -1682,9 +1682,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
                }
 
                if (five_taps)
-                       fclk = calc_fclk_five_taps(OMAP_DSS_CHANNEL_LCD, width,
-                                       height, out_width, out_height,
-                                       color_mode);
+                       fclk = calc_fclk_five_taps(channel, width, height,
+                                       out_width, out_height, color_mode);
 
                DSSDBG("required fclk rate = %lu Hz\n", fclk);
                DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
@@ -3331,17 +3330,17 @@ int dispc_setup_plane(enum omap_plane plane,
                       bool ilace,
                       enum omap_dss_rotation_type rotation_type,
                       u8 rotation, bool mirror, u8 global_alpha,
-                      u8 pre_mult_alpha)
+                      u8 pre_mult_alpha, enum omap_channel channel)
 {
        int r = 0;
 
        DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> "
-              "%dx%d, ilace %d, cmode %x, rot %d, mir %d\n",
+              "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n",
               plane, paddr, screen_width, pos_x, pos_y,
               width, height,
               out_width, out_height,
               ilace, color_mode,
-              rotation, mirror);
+              rotation, mirror, channel);
 
        enable_clocks(1);
 
@@ -3354,7 +3353,7 @@ int dispc_setup_plane(enum omap_plane plane,
                           rotation_type,
                           rotation, mirror,
                           global_alpha,
-                          pre_mult_alpha);
+                          pre_mult_alpha, channel);
 
        enable_clocks(0);
 
index 3fcb8ab781af7073990263572c8195d23d60557e..b394951120ac349a5bf78f702f89af8a9fc2bb9f 100644 (file)
@@ -359,8 +359,8 @@ int dispc_setup_plane(enum omap_plane plane,
                      bool ilace,
                      enum omap_dss_rotation_type rotation_type,
                      u8 rotation, bool mirror,
-                     u8 global_alpha,
-                     u8 pre_mult_alpha);
+                     u8 global_alpha, u8 pre_mult_alpha,
+                     enum omap_channel channel);
 
 bool dispc_go_busy(enum omap_channel channel);
 void dispc_go(enum omap_channel channel);
index 873b33469060c8b6e3b609b2f26d5781d8476b58..172d4e69730917e3a2a4630c8bdcaf4d24c60e92 100644 (file)
@@ -513,11 +513,14 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
        unsigned long timeout = msecs_to_jiffies(500);
        u32 irq;
 
-       if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
+       if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
                irq = DISPC_IRQ_EVSYNC_ODD;
-       else
-               irq = DISPC_IRQ_VSYNC;
-
+       } else {
+               if (mgr->id == OMAP_DSS_CHANNEL_LCD)
+                       irq = DISPC_IRQ_VSYNC;
+               else
+                       irq = DISPC_IRQ_VSYNC2;
+       }
        return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
 }
 
@@ -525,7 +528,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
 {
        unsigned long timeout = msecs_to_jiffies(500);
        struct manager_cache_data *mc;
-       enum omap_channel channel;
        u32 irq;
        int r;
        int i;
@@ -536,7 +538,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
 
        if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
                irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
-               channel = OMAP_DSS_CHANNEL_DIGIT;
        } else {
                if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
                        enum omap_dss_update_mode mode;
@@ -544,11 +545,14 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
                        if (mode != OMAP_DSS_UPDATE_AUTO)
                                return 0;
 
-                       irq = DISPC_IRQ_FRAMEDONE;
+                       irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
+                               DISPC_IRQ_FRAMEDONE
+                               : DISPC_IRQ_FRAMEDONE2;
                } else {
-                       irq = DISPC_IRQ_VSYNC;
+                       irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
+                               DISPC_IRQ_VSYNC
+                               : DISPC_IRQ_VSYNC2;
                }
-               channel = OMAP_DSS_CHANNEL_LCD;
        }
 
        mc = &dss_cache.manager_cache[mgr->id];
@@ -595,7 +599,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
 int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
 {
        unsigned long timeout = msecs_to_jiffies(500);
-       enum omap_channel channel;
        struct overlay_cache_data *oc;
        struct omap_dss_device *dssdev;
        u32 irq;
@@ -612,7 +615,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
 
        if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
                irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
-               channel = OMAP_DSS_CHANNEL_DIGIT;
        } else {
                if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
                        enum omap_dss_update_mode mode;
@@ -620,11 +622,14 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
                        if (mode != OMAP_DSS_UPDATE_AUTO)
                                return 0;
 
-                       irq = DISPC_IRQ_FRAMEDONE;
+                       irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
+                               DISPC_IRQ_FRAMEDONE
+                               : DISPC_IRQ_FRAMEDONE2;
                } else {
-                       irq = DISPC_IRQ_VSYNC;
+                       irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
+                               DISPC_IRQ_VSYNC
+                               : DISPC_IRQ_VSYNC2;
                }
-               channel = OMAP_DSS_CHANNEL_LCD;
        }
 
        oc = &dss_cache.overlay_cache[ovl->id];
@@ -844,7 +849,8 @@ static int configure_overlay(enum omap_plane plane)
                        c->rotation,
                        c->mirror,
                        c->global_alpha,
-                       c->pre_mult_alpha);
+                       c->pre_mult_alpha,
+                       c->channel);
 
        if (r) {
                /* this shouldn't happen */
@@ -896,10 +902,10 @@ static int configure_dispc(void)
        r = 0;
        busy = false;
 
-       mgr_busy[0] = dispc_go_busy(0);
-       mgr_busy[1] = dispc_go_busy(1);
-       mgr_go[0] = false;
-       mgr_go[1] = false;
+       for (i = 0; i < num_mgrs; i++) {
+               mgr_busy[i] = dispc_go_busy(i);
+               mgr_go[i] = false;
+       }
 
        /* Commit overlay settings */
        for (i = 0; i < num_ovls; ++i) {
@@ -1158,9 +1164,10 @@ static void dss_apply_irq_handler(void *data, u32 mask)
        const int num_mgrs = dss_feat_get_num_mgrs();
        int i, r;
        bool mgr_busy[MAX_DSS_MANAGERS];
+       u32 irq_mask;
 
-       mgr_busy[0] = dispc_go_busy(0);
-       mgr_busy[1] = dispc_go_busy(1);
+       for (i = 0; i < num_mgrs; i++)
+               mgr_busy[i] = dispc_go_busy(i);
 
        spin_lock(&dss_cache.lock);
 
@@ -1181,8 +1188,8 @@ static void dss_apply_irq_handler(void *data, u32 mask)
                goto end;
 
        /* re-read busy flags */
-       mgr_busy[0] = dispc_go_busy(0);
-       mgr_busy[1] = dispc_go_busy(1);
+       for (i = 0; i < num_mgrs; i++)
+               mgr_busy[i] = dispc_go_busy(i);
 
        /* keep running as long as there are busy managers, so that
         * we can collect overlay-applied information */
@@ -1191,9 +1198,12 @@ static void dss_apply_irq_handler(void *data, u32 mask)
                        goto end;
        }
 
-       omap_dispc_unregister_isr(dss_apply_irq_handler, NULL,
-                       DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
-                       DISPC_IRQ_EVSYNC_EVEN);
+       irq_mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
+                       DISPC_IRQ_EVSYNC_EVEN;
+       if (dss_has_feature(FEAT_MGR_LCD2))
+               irq_mask |= DISPC_IRQ_VSYNC2;
+
+       omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, irq_mask);
        dss_cache.irq_enabled = false;
 
 end:
@@ -1386,9 +1396,14 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
        r = 0;
        dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
        if (!dss_cache.irq_enabled) {
-               r = omap_dispc_register_isr(dss_apply_irq_handler, NULL,
-                               DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
-                               DISPC_IRQ_EVSYNC_EVEN);
+               u32 mask;
+
+               mask = DISPC_IRQ_VSYNC  | DISPC_IRQ_EVSYNC_ODD |
+                       DISPC_IRQ_EVSYNC_EVEN;
+               if (dss_has_feature(FEAT_MGR_LCD2))
+                       mask |= DISPC_IRQ_VSYNC2;
+
+               r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
                dss_cache.irq_enabled = true;
        }
        configure_dispc();
@@ -1480,6 +1495,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
                        mgr->name = "tv";
                        mgr->id = OMAP_DSS_CHANNEL_DIGIT;
                        break;
+               case 2:
+                       mgr->name = "lcd2";
+                       mgr->id = OMAP_DSS_CHANNEL_LCD2;
+                       break;
                }
 
                mgr->set_device = &omap_dss_set_device;
index 41a29024a8d0d8ac689ac95622eb149af7422793..456efef03c20c6de3a30bcd6aa1355862c4e6c05 100644 (file)
@@ -664,12 +664,22 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
        int i;
        struct omap_overlay_manager *lcd_mgr;
        struct omap_overlay_manager *tv_mgr;
+       struct omap_overlay_manager *lcd2_mgr = NULL;
        struct omap_overlay_manager *mgr = NULL;
 
        lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
        tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
-
-       if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) {
+       if (dss_has_feature(FEAT_MGR_LCD2))
+               lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2);
+
+       if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
+               if (!lcd2_mgr->device || force) {
+                       if (lcd2_mgr->device)
+                               lcd2_mgr->unset_device(lcd2_mgr);
+                       lcd2_mgr->set_device(lcd2_mgr, dssdev);
+                       mgr = lcd2_mgr;
+               }
+       } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) {
                if (!lcd_mgr->device || force) {
                        if (lcd_mgr->device)
                                lcd_mgr->unset_device(lcd_mgr);
This page took 0.035568 seconds and 5 git commands to generate.