aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/omap/omap_vout.c33
-rw-r--r--drivers/video/omap2/dss/apply.c163
-rw-r--r--drivers/video/omap2/dss/dss.h3
-rw-r--r--drivers/video/omap2/dss/overlay.c20
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c30
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c2
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c4
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h11
-rw-r--r--include/video/omapdss.h6
9 files changed, 190 insertions, 82 deletions
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 9c5c19f142de..27c19fe78686 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -423,7 +423,7 @@ static int omapvid_setup_overlay(struct omap_vout_device *vout,
423 "%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n" 423 "%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n"
424 "rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n" 424 "rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
425 "out_height=%d rotation_type=%d screen_width=%d\n", 425 "out_height=%d rotation_type=%d screen_width=%d\n",
426 __func__, info.enabled, info.paddr, info.width, info.height, 426 __func__, ovl->is_enabled(ovl), info.paddr, info.width, info.height,
427 info.color_mode, info.rotation, info.mirror, info.pos_x, 427 info.color_mode, info.rotation, info.mirror, info.pos_x,
428 info.pos_y, info.out_width, info.out_height, info.rotation_type, 428 info.pos_y, info.out_width, info.out_height, info.rotation_type,
429 info.screen_width); 429 info.screen_width);
@@ -942,12 +942,8 @@ static int omap_vout_release(struct file *file)
942 /* Disable all the overlay managers connected with this interface */ 942 /* Disable all the overlay managers connected with this interface */
943 for (i = 0; i < ovid->num_overlays; i++) { 943 for (i = 0; i < ovid->num_overlays; i++) {
944 struct omap_overlay *ovl = ovid->overlays[i]; 944 struct omap_overlay *ovl = ovid->overlays[i];
945 if (ovl->manager && ovl->manager->device) { 945 if (ovl->manager && ovl->manager->device)
946 struct omap_overlay_info info; 946 ovl->disable(ovl);
947 ovl->get_overlay_info(ovl, &info);
948 info.enabled = 0;
949 ovl->set_overlay_info(ovl, &info);
950 }
951 } 947 }
952 /* Turn off the pipeline */ 948 /* Turn off the pipeline */
953 ret = omapvid_apply_changes(vout); 949 ret = omapvid_apply_changes(vout);
@@ -1667,7 +1663,6 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1667 if (ovl->manager && ovl->manager->device) { 1663 if (ovl->manager && ovl->manager->device) {
1668 struct omap_overlay_info info; 1664 struct omap_overlay_info info;
1669 ovl->get_overlay_info(ovl, &info); 1665 ovl->get_overlay_info(ovl, &info);
1670 info.enabled = 1;
1671 info.paddr = addr; 1666 info.paddr = addr;
1672 if (ovl->set_overlay_info(ovl, &info)) { 1667 if (ovl->set_overlay_info(ovl, &info)) {
1673 ret = -EINVAL; 1668 ret = -EINVAL;
@@ -1686,6 +1681,16 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1686 if (ret) 1681 if (ret)
1687 v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n"); 1682 v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
1688 1683
1684 for (j = 0; j < ovid->num_overlays; j++) {
1685 struct omap_overlay *ovl = ovid->overlays[j];
1686
1687 if (ovl->manager && ovl->manager->device) {
1688 ret = ovl->enable(ovl);
1689 if (ret)
1690 goto streamon_err1;
1691 }
1692 }
1693
1689 ret = 0; 1694 ret = 0;
1690 1695
1691streamon_err1: 1696streamon_err1:
@@ -1715,16 +1720,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1715 for (j = 0; j < ovid->num_overlays; j++) { 1720 for (j = 0; j < ovid->num_overlays; j++) {
1716 struct omap_overlay *ovl = ovid->overlays[j]; 1721 struct omap_overlay *ovl = ovid->overlays[j];
1717 1722
1718 if (ovl->manager && ovl->manager->device) { 1723 if (ovl->manager && ovl->manager->device)
1719 struct omap_overlay_info info; 1724 ovl->disable(ovl);
1720
1721 ovl->get_overlay_info(ovl, &info);
1722 info.enabled = 0;
1723 ret = ovl->set_overlay_info(ovl, &info);
1724 if (ret)
1725 v4l2_err(&vout->vid_dev->v4l2_dev,
1726 "failed to update overlay info in streamoff\n");
1727 }
1728 } 1725 }
1729 1726
1730 /* Turn of the pipeline */ 1727 /* Turn of the pipeline */
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 107a4ae6e5ac..eb28a7f178dd 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -63,14 +63,18 @@ struct ovl_priv_data {
63 * VSYNC/EVSYNC */ 63 * VSYNC/EVSYNC */
64 bool shadow_dirty; 64 bool shadow_dirty;
65 65
66 bool enabled;
67
68 struct omap_overlay_info info; 66 struct omap_overlay_info info;
69 67
70 enum omap_channel channel; 68 enum omap_channel channel;
71 69
72 u32 fifo_low; 70 u32 fifo_low;
73 u32 fifo_high; 71 u32 fifo_high;
72
73 bool extra_info_dirty;
74 bool shadow_extra_info_dirty;
75
76 bool enabled;
77
74}; 78};
75 79
76struct mgr_priv_data { 80struct mgr_priv_data {
@@ -132,11 +136,6 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr)
132 return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 136 return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
133} 137}
134 138
135static int overlay_enabled(struct omap_overlay *ovl)
136{
137 return ovl->info.enabled && ovl->manager && ovl->manager->device;
138}
139
140int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) 139int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
141{ 140{
142 unsigned long timeout = msecs_to_jiffies(500); 141 unsigned long timeout = msecs_to_jiffies(500);
@@ -270,10 +269,8 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl)
270 op = get_ovl_priv(ovl); 269 op = get_ovl_priv(ovl);
271 oi = &op->info; 270 oi = &op->info;
272 271
273 if (!op->enabled) { 272 if (!op->enabled)
274 dispc_ovl_enable(ovl->id, 0);
275 return 0; 273 return 0;
276 }
277 274
278 replication = dss_use_replication(ovl->manager->device, oi->color_mode); 275 replication = dss_use_replication(ovl->manager->device, oi->color_mode);
279 276
@@ -291,11 +288,21 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl)
291 288
292 dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high); 289 dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
293 290
294 dispc_ovl_enable(ovl->id, 1);
295
296 return 0; 291 return 0;
297} 292}
298 293
294static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
295{
296 struct ovl_priv_data *op = get_ovl_priv(ovl);
297
298 DSSDBGF("%d", ovl->id);
299
300 /* note: write also when op->enabled == false, so that the ovl gets
301 * disabled */
302
303 dispc_ovl_enable(ovl->id, op->enabled);
304}
305
299static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) 306static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
300{ 307{
301 struct mgr_priv_data *mp; 308 struct mgr_priv_data *mp;
@@ -356,6 +363,30 @@ static int dss_write_regs(void)
356 mgr_go[op->channel] = true; 363 mgr_go[op->channel] = true;
357 } 364 }
358 365
366 for (i = 0; i < num_ovls; ++i) {
367 ovl = omap_dss_get_overlay(i);
368 op = get_ovl_priv(ovl);
369
370 if (!op->extra_info_dirty)
371 continue;
372
373 mp = get_mgr_priv(ovl->manager);
374
375 if (mp->manual_update && !mp->do_manual_update)
376 continue;
377
378 if (mp->busy) {
379 busy = true;
380 continue;
381 }
382
383 dss_ovl_write_regs_extra(ovl);
384
385 op->extra_info_dirty = false;
386 op->shadow_extra_info_dirty = true;
387 mgr_go[op->channel] = true;
388 }
389
359 /* Commit manager settings */ 390 /* Commit manager settings */
360 for (i = 0; i < num_mgrs; ++i) { 391 for (i = 0; i < num_mgrs; ++i) {
361 mgr = omap_dss_get_overlay_manager(i); 392 mgr = omap_dss_get_overlay_manager(i);
@@ -419,6 +450,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
419 list_for_each_entry(ovl, &mgr->overlays, list) { 450 list_for_each_entry(ovl, &mgr->overlays, list) {
420 op = get_ovl_priv(ovl); 451 op = get_ovl_priv(ovl);
421 op->shadow_dirty = false; 452 op->shadow_dirty = false;
453 op->shadow_extra_info_dirty = false;
422 } 454 }
423 455
424 mp->shadow_dirty = false; 456 mp->shadow_dirty = false;
@@ -490,8 +522,10 @@ static void dss_apply_irq_handler(void *data, u32 mask)
490 522
491 mp = get_mgr_priv(ovl->manager); 523 mp = get_mgr_priv(ovl->manager);
492 524
493 if (!mp->busy) 525 if (!mp->busy) {
494 op->shadow_dirty = false; 526 op->shadow_dirty = false;
527 op->shadow_extra_info_dirty = false;
528 }
495 } 529 }
496 530
497 for (i = 0; i < num_mgrs; ++i) { 531 for (i = 0; i < num_mgrs; ++i) {
@@ -541,14 +575,6 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
541 ovl->info_dirty = true; 575 ovl->info_dirty = true;
542 } 576 }
543 577
544 if (!overlay_enabled(ovl)) {
545 if (op->enabled) {
546 op->enabled = false;
547 op->dirty = true;
548 }
549 return;
550 }
551
552 if (!ovl->info_dirty) 578 if (!ovl->info_dirty)
553 return; 579 return;
554 580
@@ -557,8 +583,6 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
557 op->info = ovl->info; 583 op->info = ovl->info;
558 584
559 op->channel = ovl->manager->id; 585 op->channel = ovl->manager->id;
560
561 op->enabled = true;
562} 586}
563 587
564static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr) 588static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
@@ -593,9 +617,6 @@ static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
593 617
594 op = get_ovl_priv(ovl); 618 op = get_ovl_priv(ovl);
595 619
596 if (!op->enabled)
597 return;
598
599 dssdev = ovl->manager->device; 620 dssdev = ovl->manager->device;
600 621
601 size = dispc_ovl_get_fifo_size(ovl->id); 622 size = dispc_ovl_get_fifo_size(ovl->id);
@@ -828,6 +849,8 @@ void dss_ovl_get_info(struct omap_overlay *ovl,
828int dss_ovl_set_manager(struct omap_overlay *ovl, 849int dss_ovl_set_manager(struct omap_overlay *ovl,
829 struct omap_overlay_manager *mgr) 850 struct omap_overlay_manager *mgr)
830{ 851{
852 struct ovl_priv_data *op = get_ovl_priv(ovl);
853 unsigned long flags;
831 int r; 854 int r;
832 855
833 if (!mgr) 856 if (!mgr)
@@ -842,7 +865,10 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
842 goto err; 865 goto err;
843 } 866 }
844 867
845 if (ovl->info.enabled) { 868 spin_lock_irqsave(&data_lock, flags);
869
870 if (op->enabled) {
871 spin_unlock_irqrestore(&data_lock, flags);
846 DSSERR("overlay has to be disabled to change the manager\n"); 872 DSSERR("overlay has to be disabled to change the manager\n");
847 r = -EINVAL; 873 r = -EINVAL;
848 goto err; 874 goto err;
@@ -852,6 +878,8 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
852 list_add_tail(&ovl->list, &mgr->overlays); 878 list_add_tail(&ovl->list, &mgr->overlays);
853 ovl->manager_changed = true; 879 ovl->manager_changed = true;
854 880
881 spin_unlock_irqrestore(&data_lock, flags);
882
855 /* XXX: When there is an overlay on a DSI manual update display, and 883 /* XXX: When there is an overlay on a DSI manual update display, and
856 * the overlay is first disabled, then moved to tv, and enabled, we 884 * the overlay is first disabled, then moved to tv, and enabled, we
857 * seem to get SYNC_LOST_DIGIT error. 885 * seem to get SYNC_LOST_DIGIT error.
@@ -875,6 +903,8 @@ err:
875 903
876int dss_ovl_unset_manager(struct omap_overlay *ovl) 904int dss_ovl_unset_manager(struct omap_overlay *ovl)
877{ 905{
906 struct ovl_priv_data *op = get_ovl_priv(ovl);
907 unsigned long flags;
878 int r; 908 int r;
879 909
880 mutex_lock(&apply_lock); 910 mutex_lock(&apply_lock);
@@ -885,7 +915,10 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
885 goto err; 915 goto err;
886 } 916 }
887 917
888 if (ovl->info.enabled) { 918 spin_lock_irqsave(&data_lock, flags);
919
920 if (op->enabled) {
921 spin_unlock_irqrestore(&data_lock, flags);
889 DSSERR("overlay has to be disabled to unset the manager\n"); 922 DSSERR("overlay has to be disabled to unset the manager\n");
890 r = -EINVAL; 923 r = -EINVAL;
891 goto err; 924 goto err;
@@ -895,9 +928,83 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
895 list_del(&ovl->list); 928 list_del(&ovl->list);
896 ovl->manager_changed = true; 929 ovl->manager_changed = true;
897 930
931 spin_unlock_irqrestore(&data_lock, flags);
932
933 mutex_unlock(&apply_lock);
934
935 return 0;
936err:
937 mutex_unlock(&apply_lock);
938 return r;
939}
940
941bool dss_ovl_is_enabled(struct omap_overlay *ovl)
942{
943 struct ovl_priv_data *op = get_ovl_priv(ovl);
944 unsigned long flags;
945 bool e;
946
947 spin_lock_irqsave(&data_lock, flags);
948
949 e = op->enabled;
950
951 spin_unlock_irqrestore(&data_lock, flags);
952
953 return e;
954}
955
956int dss_ovl_enable(struct omap_overlay *ovl)
957{
958 struct ovl_priv_data *op = get_ovl_priv(ovl);
959 unsigned long flags;
960 int r;
961
962 mutex_lock(&apply_lock);
963
964 if (ovl->manager == NULL || ovl->manager->device == NULL) {
965 r = -EINVAL;
966 goto err;
967 }
968
969 spin_lock_irqsave(&data_lock, flags);
970
971 op->enabled = true;
972 op->extra_info_dirty = true;
973
974 spin_unlock_irqrestore(&data_lock, flags);
975
976 mutex_unlock(&apply_lock);
977
978 return 0;
979err:
980 mutex_unlock(&apply_lock);
981 return r;
982}
983
984int dss_ovl_disable(struct omap_overlay *ovl)
985{
986 struct ovl_priv_data *op = get_ovl_priv(ovl);
987 unsigned long flags;
988 int r;
989
990 mutex_lock(&apply_lock);
991
992 if (ovl->manager == NULL || ovl->manager->device == NULL) {
993 r = -EINVAL;
994 goto err;
995 }
996
997 spin_lock_irqsave(&data_lock, flags);
998
999 op->enabled = false;
1000 op->extra_info_dirty = true;
1001
1002 spin_unlock_irqrestore(&data_lock, flags);
1003
898 mutex_unlock(&apply_lock); 1004 mutex_unlock(&apply_lock);
899 1005
900 return 0; 1006 return 0;
1007
901err: 1008err:
902 mutex_unlock(&apply_lock); 1009 mutex_unlock(&apply_lock);
903 return r; 1010 return r;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index a5493df14eee..7aac8a3367bc 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -180,6 +180,9 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
180 struct omap_dss_device *dssdev); 180 struct omap_dss_device *dssdev);
181int dss_mgr_unset_device(struct omap_overlay_manager *mgr); 181int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
182 182
183bool dss_ovl_is_enabled(struct omap_overlay *ovl);
184int dss_ovl_enable(struct omap_overlay *ovl);
185int dss_ovl_disable(struct omap_overlay *ovl);
183int dss_ovl_set_info(struct omap_overlay *ovl, 186int dss_ovl_set_info(struct omap_overlay *ovl,
184 struct omap_overlay_info *info); 187 struct omap_overlay_info *info);
185void dss_ovl_get_info(struct omap_overlay *ovl, 188void dss_ovl_get_info(struct omap_overlay *ovl,
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 4dc6b92592d0..7d7cdf62059b 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -205,7 +205,7 @@ static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
205 205
206static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf) 206static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
207{ 207{
208 return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.enabled); 208 return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
209} 209}
210 210
211static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, 211static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
@@ -213,26 +213,19 @@ static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
213{ 213{
214 int r; 214 int r;
215 bool enable; 215 bool enable;
216 struct omap_overlay_info info;
217
218 ovl->get_overlay_info(ovl, &info);
219 216
220 r = strtobool(buf, &enable); 217 r = strtobool(buf, &enable);
221 if (r) 218 if (r)
222 return r; 219 return r;
223 220
224 info.enabled = enable; 221 if (enable)
222 r = ovl->enable(ovl);
223 else
224 r = ovl->disable(ovl);
225 225
226 r = ovl->set_overlay_info(ovl, &info);
227 if (r) 226 if (r)
228 return r; 227 return r;
229 228
230 if (ovl->manager) {
231 r = ovl->manager->apply(ovl->manager);
232 if (r)
233 return r;
234 }
235
236 return size; 229 return size;
237} 230}
238 231
@@ -489,6 +482,9 @@ void dss_init_overlays(struct platform_device *pdev)
489 break; 482 break;
490 } 483 }
491 484
485 ovl->is_enabled = &dss_ovl_is_enabled;
486 ovl->enable = &dss_ovl_enable;
487 ovl->disable = &dss_ovl_disable;
492 ovl->set_manager = &dss_ovl_set_manager; 488 ovl->set_manager = &dss_ovl_set_manager;
493 ovl->unset_manager = &dss_ovl_unset_manager; 489 ovl->unset_manager = &dss_ovl_unset_manager;
494 ovl->set_overlay_info = &dss_ovl_set_info; 490 ovl->set_overlay_info = &dss_ovl_set_info;
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index df7bcce5b107..562b5cc07609 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -111,28 +111,22 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
111 set_fb_fix(fbi); 111 set_fb_fix(fbi);
112 } 112 }
113 113
114 if (pi->enabled) { 114 if (!pi->enabled) {
115 struct omap_overlay_info info; 115 r = ovl->disable(ovl);
116 if (r)
117 goto undo;
118 }
116 119
120 if (pi->enabled) {
117 r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y, 121 r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y,
118 pi->out_width, pi->out_height); 122 pi->out_width, pi->out_height);
119 if (r) 123 if (r)
120 goto undo; 124 goto undo;
121
122 ovl->get_overlay_info(ovl, &info);
123
124 if (!info.enabled) {
125 info.enabled = pi->enabled;
126 r = ovl->set_overlay_info(ovl, &info);
127 if (r)
128 goto undo;
129 }
130 } else { 125 } else {
131 struct omap_overlay_info info; 126 struct omap_overlay_info info;
132 127
133 ovl->get_overlay_info(ovl, &info); 128 ovl->get_overlay_info(ovl, &info);
134 129
135 info.enabled = pi->enabled;
136 info.pos_x = pi->pos_x; 130 info.pos_x = pi->pos_x;
137 info.pos_y = pi->pos_y; 131 info.pos_y = pi->pos_y;
138 info.out_width = pi->out_width; 132 info.out_width = pi->out_width;
@@ -146,6 +140,12 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
146 if (ovl->manager) 140 if (ovl->manager)
147 ovl->manager->apply(ovl->manager); 141 ovl->manager->apply(ovl->manager);
148 142
143 if (pi->enabled) {
144 r = ovl->enable(ovl);
145 if (r)
146 goto undo;
147 }
148
149 /* Release the locks in a specific order to keep lockdep happy */ 149 /* Release the locks in a specific order to keep lockdep happy */
150 if (old_rg->id > new_rg->id) { 150 if (old_rg->id > new_rg->id) {
151 omapfb_put_mem_region(old_rg); 151 omapfb_put_mem_region(old_rg);
@@ -196,7 +196,7 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
196 196
197 pi->pos_x = ovli->pos_x; 197 pi->pos_x = ovli->pos_x;
198 pi->pos_y = ovli->pos_y; 198 pi->pos_y = ovli->pos_y;
199 pi->enabled = ovli->enabled; 199 pi->enabled = ovl->is_enabled(ovl);
200 pi->channel_out = 0; /* xxx */ 200 pi->channel_out = 0; /* xxx */
201 pi->mirror = 0; 201 pi->mirror = 0;
202 pi->mem_idx = get_mem_idx(ofbi); 202 pi->mem_idx = get_mem_idx(ofbi);
@@ -238,7 +238,9 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
238 continue; 238 continue;
239 239
240 for (j = 0; j < ofbi2->num_overlays; j++) { 240 for (j = 0; j < ofbi2->num_overlays; j++) {
241 if (ofbi2->overlays[j]->info.enabled) { 241 struct omap_overlay *ovl;
242 ovl = ofbi2->overlays[j];
243 if (ovl->is_enabled(ovl)) {
242 r = -EBUSY; 244 r = -EBUSY;
243 goto out; 245 goto out;
244 } 246 }
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 70aa47de7146..91b49b530695 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2067,6 +2067,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
2067 if (ofbi->num_overlays > 0) { 2067 if (ofbi->num_overlays > 0) {
2068 struct omap_overlay *ovl = ofbi->overlays[0]; 2068 struct omap_overlay *ovl = ofbi->overlays[0];
2069 2069
2070 ovl->manager->apply(ovl->manager);
2071
2070 r = omapfb_overlay_enable(ovl, 1); 2072 r = omapfb_overlay_enable(ovl, 1);
2071 2073
2072 if (r) { 2074 if (r) {
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 1694d5148f32..e8d8cc76a435 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -473,7 +473,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
473 continue; 473 continue;
474 474
475 for (j = 0; j < ofbi2->num_overlays; j++) { 475 for (j = 0; j < ofbi2->num_overlays; j++) {
476 if (ofbi2->overlays[j]->info.enabled) { 476 struct omap_overlay *ovl;
477 ovl = ofbi2->overlays[j];
478 if (ovl->is_enabled(ovl)) {
477 r = -EBUSY; 479 r = -EBUSY;
478 goto out; 480 goto out;
479 } 481 }
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index fdf0edeccf4e..b03fb1365ce2 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -181,13 +181,10 @@ static inline void omapfb_unlock(struct omapfb2_device *fbdev)
181static inline int omapfb_overlay_enable(struct omap_overlay *ovl, 181static inline int omapfb_overlay_enable(struct omap_overlay *ovl,
182 int enable) 182 int enable)
183{ 183{
184 struct omap_overlay_info info; 184 if (enable)
185 185 return ovl->enable(ovl);
186 ovl->get_overlay_info(ovl, &info); 186 else
187 if (info.enabled == enable) 187 return ovl->disable(ovl);
188 return 0;
189 info.enabled = enable;
190 return ovl->set_overlay_info(ovl, &info);
191} 188}
192 189
193static inline struct omapfb2_mem_region * 190static inline struct omapfb2_mem_region *
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 6e3e7a716838..9d01ff66659f 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -352,8 +352,6 @@ struct omap_dss_cpr_coefs {
352}; 352};
353 353
354struct omap_overlay_info { 354struct omap_overlay_info {
355 bool enabled;
356
357 u32 paddr; 355 u32 paddr;
358 u32 p_uv_addr; /* for NV12 format */ 356 u32 p_uv_addr; /* for NV12 format */
359 u16 screen_width; 357 u16 screen_width;
@@ -391,6 +389,10 @@ struct omap_overlay {
391 /* if true, info has been changed, but not applied() yet */ 389 /* if true, info has been changed, but not applied() yet */
392 bool info_dirty; 390 bool info_dirty;
393 391
392 int (*enable)(struct omap_overlay *ovl);
393 int (*disable)(struct omap_overlay *ovl);
394 bool (*is_enabled)(struct omap_overlay *ovl);
395
394 int (*set_manager)(struct omap_overlay *ovl, 396 int (*set_manager)(struct omap_overlay *ovl,
395 struct omap_overlay_manager *mgr); 397 struct omap_overlay_manager *mgr);
396 int (*unset_manager)(struct omap_overlay *ovl); 398 int (*unset_manager)(struct omap_overlay *ovl);