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 u32 fifo_low, fifo_high;
76 * True if overlay is to be enabled. Used to check and calculate configs
77 * for the overlay before it is enabled in the HW.
82 struct mgr_priv_data {
85 struct omap_overlay_manager_info user_info;
88 struct omap_overlay_manager_info info;
90 bool shadow_info_dirty;
92 /* If true, GO bit is up and shadow registers cannot be written.
93 * Never true for manual update displays */
96 /* If true, dispc output is enabled */
99 /* If true, a display is enabled using this manager */
102 bool extra_info_dirty;
103 bool shadow_extra_info_dirty;
105 struct omap_video_timings timings;
106 struct dss_lcd_mgr_config lcd_config;
110 struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
111 struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
116 /* protects dss_data */
117 static spinlock_t data_lock;
118 /* lock for blocking functions */
119 static DEFINE_MUTEX(apply_lock);
120 static DECLARE_COMPLETION(extra_updated_completion);
122 static void dss_register_vsync_isr(void);
124 static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
126 return &dss_data.ovl_priv_data_array[ovl->id];
129 static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
131 return &dss_data.mgr_priv_data_array[mgr->id];
134 void dss_apply_init(void)
136 const int num_ovls = dss_feat_get_num_ovls();
137 struct mgr_priv_data *mp;
140 spin_lock_init(&data_lock);
142 for (i = 0; i < num_ovls; ++i) {
143 struct ovl_priv_data *op;
145 op = &dss_data.ovl_priv_data_array[i];
147 op->info.global_alpha = 255;
155 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
159 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
163 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
167 op->user_info = op->info;
171 * Initialize some of the lcd_config fields for TV manager, this lets
172 * us prevent checking if the manager is LCD or TV at some places
174 mp = &dss_data.mgr_priv_data_array[OMAP_DSS_CHANNEL_DIGIT];
176 mp->lcd_config.video_port_width = 24;
177 mp->lcd_config.clock_info.lck_div = 1;
178 mp->lcd_config.clock_info.pck_div = 1;
182 * A LCD manager's stallmode decides whether it is in manual or auto update. TV
183 * manager is always auto update, stallmode field for TV manager is false by
186 static bool ovl_manual_update(struct omap_overlay *ovl)
188 struct mgr_priv_data *mp = get_mgr_priv(ovl->manager);
190 return mp->lcd_config.stallmode;
193 static bool mgr_manual_update(struct omap_overlay_manager *mgr)
195 struct mgr_priv_data *mp = get_mgr_priv(mgr);
197 return mp->lcd_config.stallmode;
200 static int dss_check_settings_low(struct omap_overlay_manager *mgr,
203 struct omap_overlay_info *oi;
204 struct omap_overlay_manager_info *mi;
205 struct omap_overlay *ovl;
206 struct omap_overlay_info *ois[MAX_DSS_OVERLAYS];
207 struct ovl_priv_data *op;
208 struct mgr_priv_data *mp;
210 mp = get_mgr_priv(mgr);
215 if (applying && mp->user_info_dirty)
220 /* collect the infos to be tested into the array */
221 list_for_each_entry(ovl, &mgr->overlays, list) {
222 op = get_ovl_priv(ovl);
224 if (!op->enabled && !op->enabling)
226 else if (applying && op->user_info_dirty)
234 return dss_mgr_check(mgr, mi, &mp->timings, &mp->lcd_config, ois);
238 * check manager and overlay settings using overlay_info from data->info
240 static int dss_check_settings(struct omap_overlay_manager *mgr)
242 return dss_check_settings_low(mgr, false);
246 * check manager and overlay settings using overlay_info from ovl->info if
247 * dirty and from data->info otherwise
249 static int dss_check_settings_apply(struct omap_overlay_manager *mgr)
251 return dss_check_settings_low(mgr, true);
254 static bool need_isr(void)
256 const int num_mgrs = dss_feat_get_num_mgrs();
259 for (i = 0; i < num_mgrs; ++i) {
260 struct omap_overlay_manager *mgr;
261 struct mgr_priv_data *mp;
262 struct omap_overlay *ovl;
264 mgr = omap_dss_get_overlay_manager(i);
265 mp = get_mgr_priv(mgr);
270 if (mgr_manual_update(mgr)) {
271 /* to catch FRAMEDONE */
275 /* to catch GO bit going down */
279 /* to write new values to registers */
284 if (mp->shadow_info_dirty)
288 * NOTE: we don't check extra_info flags for disabled
289 * managers, once the manager is enabled, the extra_info
290 * related manager changes will be taken in by HW.
293 /* to write new values to registers */
294 if (mp->extra_info_dirty)
298 if (mp->shadow_extra_info_dirty)
301 list_for_each_entry(ovl, &mgr->overlays, list) {
302 struct ovl_priv_data *op;
304 op = get_ovl_priv(ovl);
307 * NOTE: we check extra_info flags even for
308 * disabled overlays, as extra_infos need to be
312 /* to write new values to registers */
313 if (op->extra_info_dirty)
317 if (op->shadow_extra_info_dirty)
323 /* to write new values to registers */
328 if (op->shadow_info_dirty)
337 static bool need_go(struct omap_overlay_manager *mgr)
339 struct omap_overlay *ovl;
340 struct mgr_priv_data *mp;
341 struct ovl_priv_data *op;
343 mp = get_mgr_priv(mgr);
345 if (mp->shadow_info_dirty || mp->shadow_extra_info_dirty)
348 list_for_each_entry(ovl, &mgr->overlays, list) {
349 op = get_ovl_priv(ovl);
350 if (op->shadow_info_dirty || op->shadow_extra_info_dirty)
357 /* returns true if an extra_info field is currently being updated */
358 static bool extra_info_update_ongoing(void)
360 const int num_mgrs = dss_feat_get_num_mgrs();
363 for (i = 0; i < num_mgrs; ++i) {
364 struct omap_overlay_manager *mgr;
365 struct omap_overlay *ovl;
366 struct mgr_priv_data *mp;
368 mgr = omap_dss_get_overlay_manager(i);
369 mp = get_mgr_priv(mgr);
377 if (mp->extra_info_dirty || mp->shadow_extra_info_dirty)
380 list_for_each_entry(ovl, &mgr->overlays, list) {
381 struct ovl_priv_data *op = get_ovl_priv(ovl);
383 if (op->extra_info_dirty || op->shadow_extra_info_dirty)
391 /* wait until no extra_info updates are pending */
392 static void wait_pending_extra_info_updates(void)
399 spin_lock_irqsave(&data_lock, flags);
401 updating = extra_info_update_ongoing();
404 spin_unlock_irqrestore(&data_lock, flags);
408 init_completion(&extra_updated_completion);
410 spin_unlock_irqrestore(&data_lock, flags);
412 t = msecs_to_jiffies(500);
413 r = wait_for_completion_timeout(&extra_updated_completion, t);
415 DSSWARN("timeout in wait_pending_extra_info_updates\n");
418 int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
420 unsigned long timeout = msecs_to_jiffies(500);
421 struct mgr_priv_data *mp = get_mgr_priv(mgr);
427 spin_lock_irqsave(&data_lock, flags);
429 if (mgr_manual_update(mgr)) {
430 spin_unlock_irqrestore(&data_lock, flags);
435 spin_unlock_irqrestore(&data_lock, flags);
439 spin_unlock_irqrestore(&data_lock, flags);
441 r = dispc_runtime_get();
445 irq = dispc_mgr_get_vsync_irq(mgr->id);
449 bool shadow_dirty, dirty;
451 spin_lock_irqsave(&data_lock, flags);
452 dirty = mp->info_dirty;
453 shadow_dirty = mp->shadow_info_dirty;
454 spin_unlock_irqrestore(&data_lock, flags);
456 if (!dirty && !shadow_dirty) {
461 /* 4 iterations is the worst case:
462 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
463 * 2 - first VSYNC, dirty = true
464 * 3 - dirty = false, shadow_dirty = true
465 * 4 - shadow_dirty = false */
467 DSSERR("mgr(%d)->wait_for_go() not finishing\n",
473 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
474 if (r == -ERESTARTSYS)
478 DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id);
488 int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
490 unsigned long timeout = msecs_to_jiffies(500);
491 struct ovl_priv_data *op;
492 struct mgr_priv_data *mp;
501 mp = get_mgr_priv(ovl->manager);
503 spin_lock_irqsave(&data_lock, flags);
505 if (ovl_manual_update(ovl)) {
506 spin_unlock_irqrestore(&data_lock, flags);
511 spin_unlock_irqrestore(&data_lock, flags);
515 spin_unlock_irqrestore(&data_lock, flags);
517 r = dispc_runtime_get();
521 irq = dispc_mgr_get_vsync_irq(ovl->manager->id);
523 op = get_ovl_priv(ovl);
526 bool shadow_dirty, dirty;
528 spin_lock_irqsave(&data_lock, flags);
529 dirty = op->info_dirty;
530 shadow_dirty = op->shadow_info_dirty;
531 spin_unlock_irqrestore(&data_lock, flags);
533 if (!dirty && !shadow_dirty) {
538 /* 4 iterations is the worst case:
539 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
540 * 2 - first VSYNC, dirty = true
541 * 3 - dirty = false, shadow_dirty = true
542 * 4 - shadow_dirty = false */
544 DSSERR("ovl(%d)->wait_for_go() not finishing\n",
550 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
551 if (r == -ERESTARTSYS)
555 DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id);
565 static void dss_ovl_write_regs(struct omap_overlay *ovl)
567 struct ovl_priv_data *op = get_ovl_priv(ovl);
568 struct omap_overlay_info *oi;
570 struct mgr_priv_data *mp;
573 DSSDBG("writing ovl %d regs", ovl->id);
575 if (!op->enabled || !op->info_dirty)
580 mp = get_mgr_priv(ovl->manager);
582 replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode);
584 r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings, false);
587 * We can't do much here, as this function can be called from
590 DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl->id);
592 /* This will leave fifo configurations in a nonoptimal state */
594 dispc_ovl_enable(ovl->id, false);
598 op->info_dirty = false;
600 op->shadow_info_dirty = true;
603 static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
605 struct ovl_priv_data *op = get_ovl_priv(ovl);
606 struct mgr_priv_data *mp;
608 DSSDBG("writing ovl %d regs extra", ovl->id);
610 if (!op->extra_info_dirty)
613 /* note: write also when op->enabled == false, so that the ovl gets
616 dispc_ovl_enable(ovl->id, op->enabled);
617 dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
619 mp = get_mgr_priv(ovl->manager);
621 op->extra_info_dirty = false;
623 op->shadow_extra_info_dirty = true;
626 static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
628 struct mgr_priv_data *mp = get_mgr_priv(mgr);
629 struct omap_overlay *ovl;
631 DSSDBG("writing mgr %d regs", mgr->id);
638 /* Commit overlay settings */
639 list_for_each_entry(ovl, &mgr->overlays, list) {
640 dss_ovl_write_regs(ovl);
641 dss_ovl_write_regs_extra(ovl);
644 if (mp->info_dirty) {
645 dispc_mgr_setup(mgr->id, &mp->info);
647 mp->info_dirty = false;
649 mp->shadow_info_dirty = true;
653 static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
655 struct mgr_priv_data *mp = get_mgr_priv(mgr);
657 DSSDBG("writing mgr %d regs extra", mgr->id);
659 if (!mp->extra_info_dirty)
662 dispc_mgr_set_timings(mgr->id, &mp->timings);
664 /* lcd_config parameters */
665 if (dss_mgr_is_lcd(mgr->id))
666 dispc_mgr_set_lcd_config(mgr->id, &mp->lcd_config);
668 mp->extra_info_dirty = false;
670 mp->shadow_extra_info_dirty = true;
673 static void dss_write_regs(void)
675 const int num_mgrs = omap_dss_get_num_overlay_managers();
678 for (i = 0; i < num_mgrs; ++i) {
679 struct omap_overlay_manager *mgr;
680 struct mgr_priv_data *mp;
683 mgr = omap_dss_get_overlay_manager(i);
684 mp = get_mgr_priv(mgr);
686 if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
689 r = dss_check_settings(mgr);
691 DSSERR("cannot write registers for manager %s: "
692 "illegal configuration\n", mgr->name);
696 dss_mgr_write_regs(mgr);
697 dss_mgr_write_regs_extra(mgr);
701 static void dss_set_go_bits(void)
703 const int num_mgrs = omap_dss_get_num_overlay_managers();
706 for (i = 0; i < num_mgrs; ++i) {
707 struct omap_overlay_manager *mgr;
708 struct mgr_priv_data *mp;
710 mgr = omap_dss_get_overlay_manager(i);
711 mp = get_mgr_priv(mgr);
713 if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
721 if (!dss_data.irq_enabled && need_isr())
722 dss_register_vsync_isr();
724 dispc_mgr_go(mgr->id);
729 static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
731 struct omap_overlay *ovl;
732 struct mgr_priv_data *mp;
733 struct ovl_priv_data *op;
735 mp = get_mgr_priv(mgr);
736 mp->shadow_info_dirty = false;
737 mp->shadow_extra_info_dirty = false;
739 list_for_each_entry(ovl, &mgr->overlays, list) {
740 op = get_ovl_priv(ovl);
741 op->shadow_info_dirty = false;
742 op->shadow_extra_info_dirty = false;
746 void dss_mgr_start_update(struct omap_overlay_manager *mgr)
748 struct mgr_priv_data *mp = get_mgr_priv(mgr);
752 spin_lock_irqsave(&data_lock, flags);
754 WARN_ON(mp->updating);
756 r = dss_check_settings(mgr);
758 DSSERR("cannot start manual update: illegal configuration\n");
759 spin_unlock_irqrestore(&data_lock, flags);
763 dss_mgr_write_regs(mgr);
764 dss_mgr_write_regs_extra(mgr);
768 if (!dss_data.irq_enabled && need_isr())
769 dss_register_vsync_isr();
771 dispc_mgr_enable_sync(mgr->id);
773 mgr_clear_shadow_dirty(mgr);
775 spin_unlock_irqrestore(&data_lock, flags);
778 static void dss_apply_irq_handler(void *data, u32 mask);
780 static void dss_register_vsync_isr(void)
782 const int num_mgrs = dss_feat_get_num_mgrs();
787 for (i = 0; i < num_mgrs; ++i)
788 mask |= dispc_mgr_get_vsync_irq(i);
790 for (i = 0; i < num_mgrs; ++i)
791 mask |= dispc_mgr_get_framedone_irq(i);
793 r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
796 dss_data.irq_enabled = true;
799 static void dss_unregister_vsync_isr(void)
801 const int num_mgrs = dss_feat_get_num_mgrs();
806 for (i = 0; i < num_mgrs; ++i)
807 mask |= dispc_mgr_get_vsync_irq(i);
809 for (i = 0; i < num_mgrs; ++i)
810 mask |= dispc_mgr_get_framedone_irq(i);
812 r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
815 dss_data.irq_enabled = false;
818 static void dss_apply_irq_handler(void *data, u32 mask)
820 const int num_mgrs = dss_feat_get_num_mgrs();
824 spin_lock(&data_lock);
826 /* clear busy, updating flags, shadow_dirty flags */
827 for (i = 0; i < num_mgrs; i++) {
828 struct omap_overlay_manager *mgr;
829 struct mgr_priv_data *mp;
831 mgr = omap_dss_get_overlay_manager(i);
832 mp = get_mgr_priv(mgr);
837 mp->updating = dispc_mgr_is_enabled(i);
839 if (!mgr_manual_update(mgr)) {
840 bool was_busy = mp->busy;
841 mp->busy = dispc_mgr_go_busy(i);
843 if (was_busy && !mp->busy)
844 mgr_clear_shadow_dirty(mgr);
851 extra_updating = extra_info_update_ongoing();
853 complete_all(&extra_updated_completion);
856 dss_unregister_vsync_isr();
858 spin_unlock(&data_lock);
861 static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
863 struct ovl_priv_data *op;
865 op = get_ovl_priv(ovl);
867 if (!op->user_info_dirty)
870 op->user_info_dirty = false;
871 op->info_dirty = true;
872 op->info = op->user_info;
875 static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
877 struct mgr_priv_data *mp;
879 mp = get_mgr_priv(mgr);
881 if (!mp->user_info_dirty)
884 mp->user_info_dirty = false;
885 mp->info_dirty = true;
886 mp->info = mp->user_info;
889 int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
892 struct omap_overlay *ovl;
895 DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
897 spin_lock_irqsave(&data_lock, flags);
899 r = dss_check_settings_apply(mgr);
901 spin_unlock_irqrestore(&data_lock, flags);
902 DSSERR("failed to apply settings: illegal configuration.\n");
906 /* Configure overlays */
907 list_for_each_entry(ovl, &mgr->overlays, list)
908 omap_dss_mgr_apply_ovl(ovl);
910 /* Configure manager */
911 omap_dss_mgr_apply_mgr(mgr);
916 spin_unlock_irqrestore(&data_lock, flags);
921 static void dss_apply_ovl_enable(struct omap_overlay *ovl, bool enable)
923 struct ovl_priv_data *op;
925 op = get_ovl_priv(ovl);
927 if (op->enabled == enable)
930 op->enabled = enable;
931 op->extra_info_dirty = true;
934 static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
935 u32 fifo_low, u32 fifo_high)
937 struct ovl_priv_data *op = get_ovl_priv(ovl);
939 if (op->fifo_low == fifo_low && op->fifo_high == fifo_high)
942 op->fifo_low = fifo_low;
943 op->fifo_high = fifo_high;
944 op->extra_info_dirty = true;
947 static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
949 struct ovl_priv_data *op = get_ovl_priv(ovl);
950 u32 fifo_low, fifo_high;
951 bool use_fifo_merge = false;
953 if (!op->enabled && !op->enabling)
956 dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high,
957 use_fifo_merge, ovl_manual_update(ovl));
959 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
962 static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
964 struct omap_overlay *ovl;
965 struct mgr_priv_data *mp;
967 mp = get_mgr_priv(mgr);
972 list_for_each_entry(ovl, &mgr->overlays, list)
973 dss_ovl_setup_fifo(ovl);
976 static void dss_setup_fifos(void)
978 const int num_mgrs = omap_dss_get_num_overlay_managers();
979 struct omap_overlay_manager *mgr;
982 for (i = 0; i < num_mgrs; ++i) {
983 mgr = omap_dss_get_overlay_manager(i);
984 dss_mgr_setup_fifos(mgr);
988 int dss_mgr_enable(struct omap_overlay_manager *mgr)
990 struct mgr_priv_data *mp = get_mgr_priv(mgr);
994 mutex_lock(&apply_lock);
999 spin_lock_irqsave(&data_lock, flags);
1003 r = dss_check_settings(mgr);
1005 DSSERR("failed to enable manager %d: check_settings failed\n",
1015 if (!mgr_manual_update(mgr))
1016 mp->updating = true;
1018 if (!dss_data.irq_enabled && need_isr())
1019 dss_register_vsync_isr();
1021 spin_unlock_irqrestore(&data_lock, flags);
1023 if (!mgr_manual_update(mgr))
1024 dispc_mgr_enable_sync(mgr->id);
1027 mutex_unlock(&apply_lock);
1032 mp->enabled = false;
1033 spin_unlock_irqrestore(&data_lock, flags);
1034 mutex_unlock(&apply_lock);
1038 void dss_mgr_disable(struct omap_overlay_manager *mgr)
1040 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1041 unsigned long flags;
1043 mutex_lock(&apply_lock);
1048 if (!mgr_manual_update(mgr))
1049 dispc_mgr_disable_sync(mgr->id);
1051 spin_lock_irqsave(&data_lock, flags);
1053 mp->updating = false;
1054 mp->enabled = false;
1056 spin_unlock_irqrestore(&data_lock, flags);
1059 mutex_unlock(&apply_lock);
1062 int dss_mgr_set_info(struct omap_overlay_manager *mgr,
1063 struct omap_overlay_manager_info *info)
1065 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1066 unsigned long flags;
1069 r = dss_mgr_simple_check(mgr, info);
1073 spin_lock_irqsave(&data_lock, flags);
1075 mp->user_info = *info;
1076 mp->user_info_dirty = true;
1078 spin_unlock_irqrestore(&data_lock, flags);
1083 void dss_mgr_get_info(struct omap_overlay_manager *mgr,
1084 struct omap_overlay_manager_info *info)
1086 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1087 unsigned long flags;
1089 spin_lock_irqsave(&data_lock, flags);
1091 *info = mp->user_info;
1093 spin_unlock_irqrestore(&data_lock, flags);
1096 int dss_mgr_set_output(struct omap_overlay_manager *mgr,
1097 struct omap_dss_output *output)
1101 mutex_lock(&apply_lock);
1104 DSSERR("manager %s is already connected to an output\n",
1110 if ((mgr->supported_outputs & output->id) == 0) {
1111 DSSERR("output does not support manager %s\n",
1117 output->manager = mgr;
1118 mgr->output = output;
1120 mutex_unlock(&apply_lock);
1124 mutex_unlock(&apply_lock);
1128 int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
1131 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1132 unsigned long flags;
1134 mutex_lock(&apply_lock);
1137 DSSERR("failed to unset output, output not set\n");
1142 spin_lock_irqsave(&data_lock, flags);
1145 DSSERR("output can't be unset when manager is enabled\n");
1150 spin_unlock_irqrestore(&data_lock, flags);
1152 mgr->output->manager = NULL;
1155 mutex_unlock(&apply_lock);
1159 spin_unlock_irqrestore(&data_lock, flags);
1161 mutex_unlock(&apply_lock);
1166 static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
1167 const struct omap_video_timings *timings)
1169 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1171 mp->timings = *timings;
1172 mp->extra_info_dirty = true;
1175 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
1176 const struct omap_video_timings *timings)
1178 unsigned long flags;
1179 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1181 spin_lock_irqsave(&data_lock, flags);
1184 DSSERR("cannot set timings for %s: manager needs to be disabled\n",
1189 dss_apply_mgr_timings(mgr, timings);
1191 spin_unlock_irqrestore(&data_lock, flags);
1194 static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
1195 const struct dss_lcd_mgr_config *config)
1197 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1199 mp->lcd_config = *config;
1200 mp->extra_info_dirty = true;
1203 void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
1204 const struct dss_lcd_mgr_config *config)
1206 unsigned long flags;
1207 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1209 spin_lock_irqsave(&data_lock, flags);
1212 DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
1217 dss_apply_mgr_lcd_config(mgr, config);
1219 spin_unlock_irqrestore(&data_lock, flags);
1222 int dss_ovl_set_info(struct omap_overlay *ovl,
1223 struct omap_overlay_info *info)
1225 struct ovl_priv_data *op = get_ovl_priv(ovl);
1226 unsigned long flags;
1229 r = dss_ovl_simple_check(ovl, info);
1233 spin_lock_irqsave(&data_lock, flags);
1235 op->user_info = *info;
1236 op->user_info_dirty = true;
1238 spin_unlock_irqrestore(&data_lock, flags);
1243 void dss_ovl_get_info(struct omap_overlay *ovl,
1244 struct omap_overlay_info *info)
1246 struct ovl_priv_data *op = get_ovl_priv(ovl);
1247 unsigned long flags;
1249 spin_lock_irqsave(&data_lock, flags);
1251 *info = op->user_info;
1253 spin_unlock_irqrestore(&data_lock, flags);
1256 int dss_ovl_set_manager(struct omap_overlay *ovl,
1257 struct omap_overlay_manager *mgr)
1259 struct ovl_priv_data *op = get_ovl_priv(ovl);
1260 unsigned long flags;
1266 mutex_lock(&apply_lock);
1269 DSSERR("overlay '%s' already has a manager '%s'\n",
1270 ovl->name, ovl->manager->name);
1275 r = dispc_runtime_get();
1279 spin_lock_irqsave(&data_lock, flags);
1282 spin_unlock_irqrestore(&data_lock, flags);
1283 DSSERR("overlay has to be disabled to change the manager\n");
1288 dispc_ovl_set_channel_out(ovl->id, mgr->id);
1291 list_add_tail(&ovl->list, &mgr->overlays);
1293 spin_unlock_irqrestore(&data_lock, flags);
1295 dispc_runtime_put();
1297 mutex_unlock(&apply_lock);
1302 dispc_runtime_put();
1304 mutex_unlock(&apply_lock);
1308 int dss_ovl_unset_manager(struct omap_overlay *ovl)
1310 struct ovl_priv_data *op = get_ovl_priv(ovl);
1311 unsigned long flags;
1314 mutex_lock(&apply_lock);
1316 if (!ovl->manager) {
1317 DSSERR("failed to detach overlay: manager not set\n");
1322 spin_lock_irqsave(&data_lock, flags);
1325 spin_unlock_irqrestore(&data_lock, flags);
1326 DSSERR("overlay has to be disabled to unset the manager\n");
1331 spin_unlock_irqrestore(&data_lock, flags);
1333 /* wait for pending extra_info updates to ensure the ovl is disabled */
1334 wait_pending_extra_info_updates();
1337 * For a manual update display, there is no guarantee that the overlay
1338 * is really disabled in HW, we may need an extra update from this
1339 * manager before the configurations can go in. Return an error if the
1340 * overlay needed an update from the manager.
1342 * TODO: Instead of returning an error, try to do a dummy manager update
1343 * here to disable the overlay in hardware. Use the *GATED fields in
1344 * the DISPC_CONFIG registers to do a dummy update.
1346 spin_lock_irqsave(&data_lock, flags);
1348 if (ovl_manual_update(ovl) && op->extra_info_dirty) {
1349 spin_unlock_irqrestore(&data_lock, flags);
1350 DSSERR("need an update to change the manager\n");
1355 ovl->manager = NULL;
1356 list_del(&ovl->list);
1358 spin_unlock_irqrestore(&data_lock, flags);
1360 mutex_unlock(&apply_lock);
1364 mutex_unlock(&apply_lock);
1368 bool dss_ovl_is_enabled(struct omap_overlay *ovl)
1370 struct ovl_priv_data *op = get_ovl_priv(ovl);
1371 unsigned long flags;
1374 spin_lock_irqsave(&data_lock, flags);
1378 spin_unlock_irqrestore(&data_lock, flags);
1383 int dss_ovl_enable(struct omap_overlay *ovl)
1385 struct ovl_priv_data *op = get_ovl_priv(ovl);
1386 unsigned long flags;
1389 mutex_lock(&apply_lock);
1396 if (ovl->manager == NULL || ovl->manager->output == NULL) {
1401 spin_lock_irqsave(&data_lock, flags);
1403 op->enabling = true;
1405 r = dss_check_settings(ovl->manager);
1407 DSSERR("failed to enable overlay %d: check_settings failed\n",
1414 op->enabling = false;
1415 dss_apply_ovl_enable(ovl, true);
1420 spin_unlock_irqrestore(&data_lock, flags);
1422 mutex_unlock(&apply_lock);
1426 op->enabling = false;
1427 spin_unlock_irqrestore(&data_lock, flags);
1429 mutex_unlock(&apply_lock);
1433 int dss_ovl_disable(struct omap_overlay *ovl)
1435 struct ovl_priv_data *op = get_ovl_priv(ovl);
1436 unsigned long flags;
1439 mutex_lock(&apply_lock);
1446 if (ovl->manager == NULL || ovl->manager->output == NULL) {
1451 spin_lock_irqsave(&data_lock, flags);
1453 dss_apply_ovl_enable(ovl, false);
1457 spin_unlock_irqrestore(&data_lock, flags);
1459 mutex_unlock(&apply_lock);
1464 mutex_unlock(&apply_lock);