2 * Copyright (C) 2011 Texas Instruments
3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
18 #define DSS_SUBSYS_NAME "APPLY"
20 #include <linux/kernel.h>
21 #include <linux/slab.h>
22 #include <linux/spinlock.h>
23 #include <linux/jiffies.h>
25 #include <video/omapdss.h>
28 #include "dss_features.h"
31 * We have 4 levels of cache for the dispc settings. First two are in SW and
32 * the latter two in HW.
36 * +--------------------+
38 * +--------------------+
42 * +--------------------+
44 * +--------------------+
48 * +--------------------+
49 * | shadow registers |
50 * +--------------------+
52 * VFP or lcd/digit_enable
54 * +--------------------+
56 * +--------------------+
59 struct ovl_priv_data {
62 struct omap_overlay_info user_info;
65 struct omap_overlay_info info;
67 bool shadow_info_dirty;
69 bool extra_info_dirty;
70 bool shadow_extra_info_dirty;
73 enum omap_channel channel;
74 u32 fifo_low, fifo_high;
77 * True if overlay is to be enabled. Used to check and calculate configs
78 * for the overlay before it is enabled in the HW.
83 struct mgr_priv_data {
86 struct omap_overlay_manager_info user_info;
89 struct omap_overlay_manager_info info;
91 bool shadow_info_dirty;
93 /* If true, GO bit is up and shadow registers cannot be written.
94 * Never true for manual update displays */
97 /* If true, dispc output is enabled */
100 /* If true, a display is enabled using this manager */
103 bool extra_info_dirty;
104 bool shadow_extra_info_dirty;
106 struct omap_video_timings timings;
110 struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
111 struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
113 bool fifo_merge_dirty;
119 /* protects dss_data */
120 static spinlock_t data_lock;
121 /* lock for blocking functions */
122 static DEFINE_MUTEX(apply_lock);
123 static DECLARE_COMPLETION(extra_updated_completion);
125 static void dss_register_vsync_isr(void);
127 static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
129 return &dss_data.ovl_priv_data_array[ovl->id];
132 static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
134 return &dss_data.mgr_priv_data_array[mgr->id];
137 void dss_apply_init(void)
139 const int num_ovls = dss_feat_get_num_ovls();
142 spin_lock_init(&data_lock);
144 for (i = 0; i < num_ovls; ++i) {
145 struct ovl_priv_data *op;
147 op = &dss_data.ovl_priv_data_array[i];
149 op->info.global_alpha = 255;
157 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
161 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
165 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
169 op->user_info = op->info;
173 static bool ovl_manual_update(struct omap_overlay *ovl)
175 return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
178 static bool mgr_manual_update(struct omap_overlay_manager *mgr)
180 return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
183 static int dss_check_settings_low(struct omap_overlay_manager *mgr,
186 struct omap_overlay_info *oi;
187 struct omap_overlay_manager_info *mi;
188 struct omap_overlay *ovl;
189 struct omap_overlay_info *ois[MAX_DSS_OVERLAYS];
190 struct ovl_priv_data *op;
191 struct mgr_priv_data *mp;
193 mp = get_mgr_priv(mgr);
198 if (applying && mp->user_info_dirty)
203 /* collect the infos to be tested into the array */
204 list_for_each_entry(ovl, &mgr->overlays, list) {
205 op = get_ovl_priv(ovl);
207 if (!op->enabled && !op->enabling)
209 else if (applying && op->user_info_dirty)
217 return dss_mgr_check(mgr, mi, &mp->timings, ois);
221 * check manager and overlay settings using overlay_info from data->info
223 static int dss_check_settings(struct omap_overlay_manager *mgr)
225 return dss_check_settings_low(mgr, false);
229 * check manager and overlay settings using overlay_info from ovl->info if
230 * dirty and from data->info otherwise
232 static int dss_check_settings_apply(struct omap_overlay_manager *mgr)
234 return dss_check_settings_low(mgr, true);
237 static bool need_isr(void)
239 const int num_mgrs = dss_feat_get_num_mgrs();
242 for (i = 0; i < num_mgrs; ++i) {
243 struct omap_overlay_manager *mgr;
244 struct mgr_priv_data *mp;
245 struct omap_overlay *ovl;
247 mgr = omap_dss_get_overlay_manager(i);
248 mp = get_mgr_priv(mgr);
253 if (mgr_manual_update(mgr)) {
254 /* to catch FRAMEDONE */
258 /* to catch GO bit going down */
262 /* to write new values to registers */
267 if (mp->shadow_info_dirty)
271 * NOTE: we don't check extra_info flags for disabled
272 * managers, once the manager is enabled, the extra_info
273 * related manager changes will be taken in by HW.
276 /* to write new values to registers */
277 if (mp->extra_info_dirty)
281 if (mp->shadow_extra_info_dirty)
284 list_for_each_entry(ovl, &mgr->overlays, list) {
285 struct ovl_priv_data *op;
287 op = get_ovl_priv(ovl);
290 * NOTE: we check extra_info flags even for
291 * disabled overlays, as extra_infos need to be
295 /* to write new values to registers */
296 if (op->extra_info_dirty)
300 if (op->shadow_extra_info_dirty)
306 /* to write new values to registers */
311 if (op->shadow_info_dirty)
320 static bool need_go(struct omap_overlay_manager *mgr)
322 struct omap_overlay *ovl;
323 struct mgr_priv_data *mp;
324 struct ovl_priv_data *op;
326 mp = get_mgr_priv(mgr);
328 if (mp->shadow_info_dirty || mp->shadow_extra_info_dirty)
331 list_for_each_entry(ovl, &mgr->overlays, list) {
332 op = get_ovl_priv(ovl);
333 if (op->shadow_info_dirty || op->shadow_extra_info_dirty)
340 /* returns true if an extra_info field is currently being updated */
341 static bool extra_info_update_ongoing(void)
343 const int num_mgrs = dss_feat_get_num_mgrs();
346 for (i = 0; i < num_mgrs; ++i) {
347 struct omap_overlay_manager *mgr;
348 struct omap_overlay *ovl;
349 struct mgr_priv_data *mp;
351 mgr = omap_dss_get_overlay_manager(i);
352 mp = get_mgr_priv(mgr);
360 if (mp->extra_info_dirty || mp->shadow_extra_info_dirty)
363 list_for_each_entry(ovl, &mgr->overlays, list) {
364 struct ovl_priv_data *op = get_ovl_priv(ovl);
366 if (op->extra_info_dirty || op->shadow_extra_info_dirty)
374 /* wait until no extra_info updates are pending */
375 static void wait_pending_extra_info_updates(void)
382 spin_lock_irqsave(&data_lock, flags);
384 updating = extra_info_update_ongoing();
387 spin_unlock_irqrestore(&data_lock, flags);
391 init_completion(&extra_updated_completion);
393 spin_unlock_irqrestore(&data_lock, flags);
395 t = msecs_to_jiffies(500);
396 r = wait_for_completion_timeout(&extra_updated_completion, t);
398 DSSWARN("timeout in wait_pending_extra_info_updates\n");
400 DSSERR("wait_pending_extra_info_updates failed: %d\n", r);
403 int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
405 unsigned long timeout = msecs_to_jiffies(500);
406 struct mgr_priv_data *mp;
410 struct omap_dss_device *dssdev = mgr->device;
412 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
415 if (mgr_manual_update(mgr))
418 r = dispc_runtime_get();
422 irq = dispc_mgr_get_vsync_irq(mgr->id);
424 mp = get_mgr_priv(mgr);
428 bool shadow_dirty, dirty;
430 spin_lock_irqsave(&data_lock, flags);
431 dirty = mp->info_dirty;
432 shadow_dirty = mp->shadow_info_dirty;
433 spin_unlock_irqrestore(&data_lock, flags);
435 if (!dirty && !shadow_dirty) {
440 /* 4 iterations is the worst case:
441 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
442 * 2 - first VSYNC, dirty = true
443 * 3 - dirty = false, shadow_dirty = true
444 * 4 - shadow_dirty = false */
446 DSSERR("mgr(%d)->wait_for_go() not finishing\n",
452 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
453 if (r == -ERESTARTSYS)
457 DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id);
467 int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
469 unsigned long timeout = msecs_to_jiffies(500);
470 struct ovl_priv_data *op;
471 struct omap_dss_device *dssdev;
479 dssdev = ovl->manager->device;
481 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
484 if (ovl_manual_update(ovl))
487 r = dispc_runtime_get();
491 irq = dispc_mgr_get_vsync_irq(ovl->manager->id);
493 op = get_ovl_priv(ovl);
497 bool shadow_dirty, dirty;
499 spin_lock_irqsave(&data_lock, flags);
500 dirty = op->info_dirty;
501 shadow_dirty = op->shadow_info_dirty;
502 spin_unlock_irqrestore(&data_lock, flags);
504 if (!dirty && !shadow_dirty) {
509 /* 4 iterations is the worst case:
510 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
511 * 2 - first VSYNC, dirty = true
512 * 3 - dirty = false, shadow_dirty = true
513 * 4 - shadow_dirty = false */
515 DSSERR("ovl(%d)->wait_for_go() not finishing\n",
521 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
522 if (r == -ERESTARTSYS)
526 DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id);
536 static void dss_ovl_write_regs(struct omap_overlay *ovl)
538 struct ovl_priv_data *op = get_ovl_priv(ovl);
539 struct omap_overlay_info *oi;
540 bool ilace, replication;
541 struct mgr_priv_data *mp;
544 DSSDBGF("%d", ovl->id);
546 if (!op->enabled || !op->info_dirty)
551 mp = get_mgr_priv(ovl->manager);
553 replication = dss_use_replication(ovl->manager->device, oi->color_mode);
555 ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC;
557 r = dispc_ovl_setup(ovl->id, oi, ilace, replication, &mp->timings);
560 * We can't do much here, as this function can be called from
563 DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl->id);
565 /* This will leave fifo configurations in a nonoptimal state */
567 dispc_ovl_enable(ovl->id, false);
571 op->info_dirty = false;
573 op->shadow_info_dirty = true;
576 static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
578 struct ovl_priv_data *op = get_ovl_priv(ovl);
579 struct mgr_priv_data *mp;
581 DSSDBGF("%d", ovl->id);
583 if (!op->extra_info_dirty)
586 /* note: write also when op->enabled == false, so that the ovl gets
589 dispc_ovl_enable(ovl->id, op->enabled);
590 dispc_ovl_set_channel_out(ovl->id, op->channel);
591 dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
593 mp = get_mgr_priv(ovl->manager);
595 op->extra_info_dirty = false;
597 op->shadow_extra_info_dirty = true;
600 static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
602 struct mgr_priv_data *mp = get_mgr_priv(mgr);
603 struct omap_overlay *ovl;
605 DSSDBGF("%d", mgr->id);
612 /* Commit overlay settings */
613 list_for_each_entry(ovl, &mgr->overlays, list) {
614 dss_ovl_write_regs(ovl);
615 dss_ovl_write_regs_extra(ovl);
618 if (mp->info_dirty) {
619 dispc_mgr_setup(mgr->id, &mp->info);
621 mp->info_dirty = false;
623 mp->shadow_info_dirty = true;
627 static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
629 struct mgr_priv_data *mp = get_mgr_priv(mgr);
631 DSSDBGF("%d", mgr->id);
633 if (!mp->extra_info_dirty)
636 dispc_mgr_set_timings(mgr->id, &mp->timings);
638 mp->extra_info_dirty = false;
640 mp->shadow_extra_info_dirty = true;
643 static void dss_write_regs_common(void)
645 const int num_mgrs = omap_dss_get_num_overlay_managers();
648 if (!dss_data.fifo_merge_dirty)
651 for (i = 0; i < num_mgrs; ++i) {
652 struct omap_overlay_manager *mgr;
653 struct mgr_priv_data *mp;
655 mgr = omap_dss_get_overlay_manager(i);
656 mp = get_mgr_priv(mgr);
659 if (dss_data.fifo_merge_dirty) {
660 dispc_enable_fifomerge(dss_data.fifo_merge);
661 dss_data.fifo_merge_dirty = false;
665 mp->shadow_info_dirty = true;
670 static void dss_write_regs(void)
672 const int num_mgrs = omap_dss_get_num_overlay_managers();
675 dss_write_regs_common();
677 for (i = 0; i < num_mgrs; ++i) {
678 struct omap_overlay_manager *mgr;
679 struct mgr_priv_data *mp;
682 mgr = omap_dss_get_overlay_manager(i);
683 mp = get_mgr_priv(mgr);
685 if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
688 r = dss_check_settings(mgr);
690 DSSERR("cannot write registers for manager %s: "
691 "illegal configuration\n", mgr->name);
695 dss_mgr_write_regs(mgr);
696 dss_mgr_write_regs_extra(mgr);
700 static void dss_set_go_bits(void)
702 const int num_mgrs = omap_dss_get_num_overlay_managers();
705 for (i = 0; i < num_mgrs; ++i) {
706 struct omap_overlay_manager *mgr;
707 struct mgr_priv_data *mp;
709 mgr = omap_dss_get_overlay_manager(i);
710 mp = get_mgr_priv(mgr);
712 if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
720 if (!dss_data.irq_enabled && need_isr())
721 dss_register_vsync_isr();
723 dispc_mgr_go(mgr->id);
728 static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
730 struct omap_overlay *ovl;
731 struct mgr_priv_data *mp;
732 struct ovl_priv_data *op;
734 mp = get_mgr_priv(mgr);
735 mp->shadow_info_dirty = false;
736 mp->shadow_extra_info_dirty = false;
738 list_for_each_entry(ovl, &mgr->overlays, list) {
739 op = get_ovl_priv(ovl);
740 op->shadow_info_dirty = false;
741 op->shadow_extra_info_dirty = false;
745 void dss_mgr_start_update(struct omap_overlay_manager *mgr)
747 struct mgr_priv_data *mp = get_mgr_priv(mgr);
751 spin_lock_irqsave(&data_lock, flags);
753 WARN_ON(mp->updating);
755 r = dss_check_settings(mgr);
757 DSSERR("cannot start manual update: illegal configuration\n");
758 spin_unlock_irqrestore(&data_lock, flags);
762 dss_mgr_write_regs(mgr);
763 dss_mgr_write_regs_extra(mgr);
765 dss_write_regs_common();
769 if (!dss_data.irq_enabled && need_isr())
770 dss_register_vsync_isr();
772 dispc_mgr_enable(mgr->id, true);
774 mgr_clear_shadow_dirty(mgr);
776 spin_unlock_irqrestore(&data_lock, flags);
779 static void dss_apply_irq_handler(void *data, u32 mask);
781 static void dss_register_vsync_isr(void)
783 const int num_mgrs = dss_feat_get_num_mgrs();
788 for (i = 0; i < num_mgrs; ++i)
789 mask |= dispc_mgr_get_vsync_irq(i);
791 for (i = 0; i < num_mgrs; ++i)
792 mask |= dispc_mgr_get_framedone_irq(i);
794 r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
797 dss_data.irq_enabled = true;
800 static void dss_unregister_vsync_isr(void)
802 const int num_mgrs = dss_feat_get_num_mgrs();
807 for (i = 0; i < num_mgrs; ++i)
808 mask |= dispc_mgr_get_vsync_irq(i);
810 for (i = 0; i < num_mgrs; ++i)
811 mask |= dispc_mgr_get_framedone_irq(i);
813 r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
816 dss_data.irq_enabled = false;
819 static void dss_apply_irq_handler(void *data, u32 mask)
821 const int num_mgrs = dss_feat_get_num_mgrs();
825 spin_lock(&data_lock);
827 /* clear busy, updating flags, shadow_dirty flags */
828 for (i = 0; i < num_mgrs; i++) {
829 struct omap_overlay_manager *mgr;
830 struct mgr_priv_data *mp;
833 mgr = omap_dss_get_overlay_manager(i);
834 mp = get_mgr_priv(mgr);
839 was_updating = mp->updating;
840 mp->updating = dispc_mgr_is_enabled(i);
842 if (!mgr_manual_update(mgr)) {
843 bool was_busy = mp->busy;
844 mp->busy = dispc_mgr_go_busy(i);
846 if (was_busy && !mp->busy)
847 mgr_clear_shadow_dirty(mgr);
854 extra_updating = extra_info_update_ongoing();
856 complete_all(&extra_updated_completion);
859 dss_unregister_vsync_isr();
861 spin_unlock(&data_lock);
864 static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
866 struct ovl_priv_data *op;
868 op = get_ovl_priv(ovl);
870 if (!op->user_info_dirty)
873 op->user_info_dirty = false;
874 op->info_dirty = true;
875 op->info = op->user_info;
878 static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
880 struct mgr_priv_data *mp;
882 mp = get_mgr_priv(mgr);
884 if (!mp->user_info_dirty)
887 mp->user_info_dirty = false;
888 mp->info_dirty = true;
889 mp->info = mp->user_info;
892 int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
895 struct omap_overlay *ovl;
898 DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
900 spin_lock_irqsave(&data_lock, flags);
902 r = dss_check_settings_apply(mgr);
904 spin_unlock_irqrestore(&data_lock, flags);
905 DSSERR("failed to apply settings: illegal configuration.\n");
909 /* Configure overlays */
910 list_for_each_entry(ovl, &mgr->overlays, list)
911 omap_dss_mgr_apply_ovl(ovl);
913 /* Configure manager */
914 omap_dss_mgr_apply_mgr(mgr);
919 spin_unlock_irqrestore(&data_lock, flags);
924 static void dss_apply_ovl_enable(struct omap_overlay *ovl, bool enable)
926 struct ovl_priv_data *op;
928 op = get_ovl_priv(ovl);
930 if (op->enabled == enable)
933 op->enabled = enable;
934 op->extra_info_dirty = true;
937 static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
938 u32 fifo_low, u32 fifo_high)
940 struct ovl_priv_data *op = get_ovl_priv(ovl);
942 if (op->fifo_low == fifo_low && op->fifo_high == fifo_high)
945 op->fifo_low = fifo_low;
946 op->fifo_high = fifo_high;
947 op->extra_info_dirty = true;
950 static void dss_apply_fifo_merge(bool use_fifo_merge)
952 if (dss_data.fifo_merge == use_fifo_merge)
955 dss_data.fifo_merge = use_fifo_merge;
956 dss_data.fifo_merge_dirty = true;
959 static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
962 struct ovl_priv_data *op = get_ovl_priv(ovl);
963 u32 fifo_low, fifo_high;
965 if (!op->enabled && !op->enabling)
968 dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high,
969 use_fifo_merge, ovl_manual_update(ovl));
971 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
974 static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
977 struct omap_overlay *ovl;
978 struct mgr_priv_data *mp;
980 mp = get_mgr_priv(mgr);
985 list_for_each_entry(ovl, &mgr->overlays, list)
986 dss_ovl_setup_fifo(ovl, use_fifo_merge);
989 static void dss_setup_fifos(bool use_fifo_merge)
991 const int num_mgrs = omap_dss_get_num_overlay_managers();
992 struct omap_overlay_manager *mgr;
995 for (i = 0; i < num_mgrs; ++i) {
996 mgr = omap_dss_get_overlay_manager(i);
997 dss_mgr_setup_fifos(mgr, use_fifo_merge);
1001 static int get_num_used_managers(void)
1003 const int num_mgrs = omap_dss_get_num_overlay_managers();
1004 struct omap_overlay_manager *mgr;
1005 struct mgr_priv_data *mp;
1011 for (i = 0; i < num_mgrs; ++i) {
1012 mgr = omap_dss_get_overlay_manager(i);
1013 mp = get_mgr_priv(mgr);
1021 return enabled_mgrs;
1024 static int get_num_used_overlays(void)
1026 const int num_ovls = omap_dss_get_num_overlays();
1027 struct omap_overlay *ovl;
1028 struct ovl_priv_data *op;
1029 struct mgr_priv_data *mp;
1035 for (i = 0; i < num_ovls; ++i) {
1036 ovl = omap_dss_get_overlay(i);
1037 op = get_ovl_priv(ovl);
1039 if (!op->enabled && !op->enabling)
1042 mp = get_mgr_priv(ovl->manager);
1050 return enabled_ovls;
1053 static bool get_use_fifo_merge(void)
1055 int enabled_mgrs = get_num_used_managers();
1056 int enabled_ovls = get_num_used_overlays();
1058 if (!dss_has_feature(FEAT_FIFO_MERGE))
1062 * In theory the only requirement for fifomerge is enabled_ovls <= 1.
1063 * However, if we have two managers enabled and set/unset the fifomerge,
1064 * we need to set the GO bits in particular sequence for the managers,
1065 * and wait in between.
1067 * This is rather difficult as new apply calls can happen at any time,
1068 * so we simplify the problem by requiring also that enabled_mgrs <= 1.
1069 * In practice this shouldn't matter, because when only one overlay is
1070 * enabled, most likely only one output is enabled.
1073 return enabled_mgrs <= 1 && enabled_ovls <= 1;
1076 int dss_mgr_enable(struct omap_overlay_manager *mgr)
1078 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1079 unsigned long flags;
1083 mutex_lock(&apply_lock);
1088 spin_lock_irqsave(&data_lock, flags);
1092 r = dss_check_settings(mgr);
1094 DSSERR("failed to enable manager %d: check_settings failed\n",
1099 /* step 1: setup fifos/fifomerge before enabling the manager */
1101 fifo_merge = get_use_fifo_merge();
1102 dss_setup_fifos(fifo_merge);
1103 dss_apply_fifo_merge(fifo_merge);
1108 spin_unlock_irqrestore(&data_lock, flags);
1110 /* wait until fifo config is in */
1111 wait_pending_extra_info_updates();
1113 /* step 2: enable the manager */
1114 spin_lock_irqsave(&data_lock, flags);
1116 if (!mgr_manual_update(mgr))
1117 mp->updating = true;
1119 spin_unlock_irqrestore(&data_lock, flags);
1121 if (!mgr_manual_update(mgr))
1122 dispc_mgr_enable(mgr->id, true);
1125 mutex_unlock(&apply_lock);
1130 mp->enabled = false;
1131 spin_unlock_irqrestore(&data_lock, flags);
1132 mutex_unlock(&apply_lock);
1136 void dss_mgr_disable(struct omap_overlay_manager *mgr)
1138 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1139 unsigned long flags;
1142 mutex_lock(&apply_lock);
1147 if (!mgr_manual_update(mgr))
1148 dispc_mgr_enable(mgr->id, false);
1150 spin_lock_irqsave(&data_lock, flags);
1152 mp->updating = false;
1153 mp->enabled = false;
1155 fifo_merge = get_use_fifo_merge();
1156 dss_setup_fifos(fifo_merge);
1157 dss_apply_fifo_merge(fifo_merge);
1162 spin_unlock_irqrestore(&data_lock, flags);
1164 wait_pending_extra_info_updates();
1166 mutex_unlock(&apply_lock);
1169 int dss_mgr_set_info(struct omap_overlay_manager *mgr,
1170 struct omap_overlay_manager_info *info)
1172 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1173 unsigned long flags;
1176 r = dss_mgr_simple_check(mgr, info);
1180 spin_lock_irqsave(&data_lock, flags);
1182 mp->user_info = *info;
1183 mp->user_info_dirty = true;
1185 spin_unlock_irqrestore(&data_lock, flags);
1190 void dss_mgr_get_info(struct omap_overlay_manager *mgr,
1191 struct omap_overlay_manager_info *info)
1193 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1194 unsigned long flags;
1196 spin_lock_irqsave(&data_lock, flags);
1198 *info = mp->user_info;
1200 spin_unlock_irqrestore(&data_lock, flags);
1203 int dss_mgr_set_device(struct omap_overlay_manager *mgr,
1204 struct omap_dss_device *dssdev)
1208 mutex_lock(&apply_lock);
1210 if (dssdev->manager) {
1211 DSSERR("display '%s' already has a manager '%s'\n",
1212 dssdev->name, dssdev->manager->name);
1217 if ((mgr->supported_displays & dssdev->type) == 0) {
1218 DSSERR("display '%s' does not support manager '%s'\n",
1219 dssdev->name, mgr->name);
1224 dssdev->manager = mgr;
1225 mgr->device = dssdev;
1227 mutex_unlock(&apply_lock);
1231 mutex_unlock(&apply_lock);
1235 int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
1239 mutex_lock(&apply_lock);
1242 DSSERR("failed to unset display, display not set.\n");
1248 * Don't allow currently enabled displays to have the overlay manager
1249 * pulled out from underneath them
1251 if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
1256 mgr->device->manager = NULL;
1259 mutex_unlock(&apply_lock);
1263 mutex_unlock(&apply_lock);
1267 static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
1268 struct omap_video_timings *timings)
1270 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1272 mp->timings = *timings;
1273 mp->extra_info_dirty = true;
1276 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
1277 struct omap_video_timings *timings)
1279 unsigned long flags;
1281 mutex_lock(&apply_lock);
1283 spin_lock_irqsave(&data_lock, flags);
1285 dss_apply_mgr_timings(mgr, timings);
1290 spin_unlock_irqrestore(&data_lock, flags);
1292 wait_pending_extra_info_updates();
1294 mutex_unlock(&apply_lock);
1297 int dss_ovl_set_info(struct omap_overlay *ovl,
1298 struct omap_overlay_info *info)
1300 struct ovl_priv_data *op = get_ovl_priv(ovl);
1301 unsigned long flags;
1304 r = dss_ovl_simple_check(ovl, info);
1308 spin_lock_irqsave(&data_lock, flags);
1310 op->user_info = *info;
1311 op->user_info_dirty = true;
1313 spin_unlock_irqrestore(&data_lock, flags);
1318 void dss_ovl_get_info(struct omap_overlay *ovl,
1319 struct omap_overlay_info *info)
1321 struct ovl_priv_data *op = get_ovl_priv(ovl);
1322 unsigned long flags;
1324 spin_lock_irqsave(&data_lock, flags);
1326 *info = op->user_info;
1328 spin_unlock_irqrestore(&data_lock, flags);
1331 int dss_ovl_set_manager(struct omap_overlay *ovl,
1332 struct omap_overlay_manager *mgr)
1334 struct ovl_priv_data *op = get_ovl_priv(ovl);
1335 unsigned long flags;
1341 mutex_lock(&apply_lock);
1344 DSSERR("overlay '%s' already has a manager '%s'\n",
1345 ovl->name, ovl->manager->name);
1350 spin_lock_irqsave(&data_lock, flags);
1353 spin_unlock_irqrestore(&data_lock, flags);
1354 DSSERR("overlay has to be disabled to change the manager\n");
1359 op->channel = mgr->id;
1360 op->extra_info_dirty = true;
1363 list_add_tail(&ovl->list, &mgr->overlays);
1365 spin_unlock_irqrestore(&data_lock, flags);
1367 /* XXX: When there is an overlay on a DSI manual update display, and
1368 * the overlay is first disabled, then moved to tv, and enabled, we
1369 * seem to get SYNC_LOST_DIGIT error.
1371 * Waiting doesn't seem to help, but updating the manual update display
1372 * after disabling the overlay seems to fix this. This hints that the
1373 * overlay is perhaps somehow tied to the LCD output until the output
1376 * Userspace workaround for this is to update the LCD after disabling
1377 * the overlay, but before moving the overlay to TV.
1380 mutex_unlock(&apply_lock);
1384 mutex_unlock(&apply_lock);
1388 int dss_ovl_unset_manager(struct omap_overlay *ovl)
1390 struct ovl_priv_data *op = get_ovl_priv(ovl);
1391 unsigned long flags;
1394 mutex_lock(&apply_lock);
1396 if (!ovl->manager) {
1397 DSSERR("failed to detach overlay: manager not set\n");
1402 spin_lock_irqsave(&data_lock, flags);
1405 spin_unlock_irqrestore(&data_lock, flags);
1406 DSSERR("overlay has to be disabled to unset the manager\n");
1413 ovl->manager = NULL;
1414 list_del(&ovl->list);
1416 spin_unlock_irqrestore(&data_lock, flags);
1418 mutex_unlock(&apply_lock);
1422 mutex_unlock(&apply_lock);
1426 bool dss_ovl_is_enabled(struct omap_overlay *ovl)
1428 struct ovl_priv_data *op = get_ovl_priv(ovl);
1429 unsigned long flags;
1432 spin_lock_irqsave(&data_lock, flags);
1436 spin_unlock_irqrestore(&data_lock, flags);
1441 int dss_ovl_enable(struct omap_overlay *ovl)
1443 struct ovl_priv_data *op = get_ovl_priv(ovl);
1444 unsigned long flags;
1448 mutex_lock(&apply_lock);
1455 if (ovl->manager == NULL || ovl->manager->device == NULL) {
1460 spin_lock_irqsave(&data_lock, flags);
1462 op->enabling = true;
1464 r = dss_check_settings(ovl->manager);
1466 DSSERR("failed to enable overlay %d: check_settings failed\n",
1471 /* step 1: configure fifos/fifomerge for currently enabled ovls */
1473 fifo_merge = get_use_fifo_merge();
1474 dss_setup_fifos(fifo_merge);
1475 dss_apply_fifo_merge(fifo_merge);
1480 spin_unlock_irqrestore(&data_lock, flags);
1482 /* wait for fifo configs to go in */
1483 wait_pending_extra_info_updates();
1485 /* step 2: enable the overlay */
1486 spin_lock_irqsave(&data_lock, flags);
1488 op->enabling = false;
1489 dss_apply_ovl_enable(ovl, true);
1494 spin_unlock_irqrestore(&data_lock, flags);
1496 /* wait for overlay to be enabled */
1497 wait_pending_extra_info_updates();
1499 mutex_unlock(&apply_lock);
1503 op->enabling = false;
1504 spin_unlock_irqrestore(&data_lock, flags);
1506 mutex_unlock(&apply_lock);
1510 int dss_ovl_disable(struct omap_overlay *ovl)
1512 struct ovl_priv_data *op = get_ovl_priv(ovl);
1513 unsigned long flags;
1517 mutex_lock(&apply_lock);
1524 if (ovl->manager == NULL || ovl->manager->device == NULL) {
1529 /* step 1: disable the overlay */
1530 spin_lock_irqsave(&data_lock, flags);
1532 dss_apply_ovl_enable(ovl, false);
1537 spin_unlock_irqrestore(&data_lock, flags);
1539 /* wait for the overlay to be disabled */
1540 wait_pending_extra_info_updates();
1542 /* step 2: configure fifos/fifomerge */
1543 spin_lock_irqsave(&data_lock, flags);
1545 fifo_merge = get_use_fifo_merge();
1546 dss_setup_fifos(fifo_merge);
1547 dss_apply_fifo_merge(fifo_merge);
1552 spin_unlock_irqrestore(&data_lock, flags);
1554 /* wait for fifo config to go in */
1555 wait_pending_extra_info_updates();
1557 mutex_unlock(&apply_lock);
1562 mutex_unlock(&apply_lock);