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/module.h>
22 #include <linux/slab.h>
23 #include <linux/spinlock.h>
24 #include <linux/jiffies.h>
26 #include <video/omapdss.h>
29 #include "dss_features.h"
30 #include "dispc-compat.h"
33 * We have 4 levels of cache for the dispc settings. First two are in SW and
34 * the latter two in HW.
38 * +--------------------+
40 * +--------------------+
44 * +--------------------+
46 * +--------------------+
50 * +--------------------+
51 * | shadow registers |
52 * +--------------------+
54 * VFP or lcd/digit_enable
56 * +--------------------+
58 * +--------------------+
61 struct ovl_priv_data
{
64 struct omap_overlay_info user_info
;
67 struct omap_overlay_info info
;
69 bool shadow_info_dirty
;
71 bool extra_info_dirty
;
72 bool shadow_extra_info_dirty
;
75 u32 fifo_low
, fifo_high
;
78 * True if overlay is to be enabled. Used to check and calculate configs
79 * for the overlay before it is enabled in the HW.
84 struct mgr_priv_data
{
87 struct omap_overlay_manager_info user_info
;
90 struct omap_overlay_manager_info info
;
92 bool shadow_info_dirty
;
94 /* If true, GO bit is up and shadow registers cannot be written.
95 * Never true for manual update displays */
98 /* If true, dispc output is enabled */
101 /* If true, a display is enabled using this manager */
104 bool extra_info_dirty
;
105 bool shadow_extra_info_dirty
;
107 struct omap_video_timings timings
;
108 struct dss_lcd_mgr_config lcd_config
;
110 void (*framedone_handler
)(void *);
111 void *framedone_handler_data
;
115 struct ovl_priv_data ovl_priv_data_array
[MAX_DSS_OVERLAYS
];
116 struct mgr_priv_data mgr_priv_data_array
[MAX_DSS_MANAGERS
];
121 /* protects dss_data */
122 static spinlock_t data_lock
;
123 /* lock for blocking functions */
124 static DEFINE_MUTEX(apply_lock
);
125 static DECLARE_COMPLETION(extra_updated_completion
);
127 static void dss_register_vsync_isr(void);
129 static struct ovl_priv_data
*get_ovl_priv(struct omap_overlay
*ovl
)
131 return &dss_data
.ovl_priv_data_array
[ovl
->id
];
134 static struct mgr_priv_data
*get_mgr_priv(struct omap_overlay_manager
*mgr
)
136 return &dss_data
.mgr_priv_data_array
[mgr
->id
];
139 static void apply_init_priv(void)
141 const int num_ovls
= dss_feat_get_num_ovls();
142 struct mgr_priv_data
*mp
;
145 spin_lock_init(&data_lock
);
147 for (i
= 0; i
< num_ovls
; ++i
) {
148 struct ovl_priv_data
*op
;
150 op
= &dss_data
.ovl_priv_data_array
[i
];
152 op
->info
.global_alpha
= 255;
160 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 3 : 0;
164 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 2 : 0;
168 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 1 : 0;
172 op
->user_info
= op
->info
;
176 * Initialize some of the lcd_config fields for TV manager, this lets
177 * us prevent checking if the manager is LCD or TV at some places
179 mp
= &dss_data
.mgr_priv_data_array
[OMAP_DSS_CHANNEL_DIGIT
];
181 mp
->lcd_config
.video_port_width
= 24;
182 mp
->lcd_config
.clock_info
.lck_div
= 1;
183 mp
->lcd_config
.clock_info
.pck_div
= 1;
187 * A LCD manager's stallmode decides whether it is in manual or auto update. TV
188 * manager is always auto update, stallmode field for TV manager is false by
191 static bool ovl_manual_update(struct omap_overlay
*ovl
)
193 struct mgr_priv_data
*mp
= get_mgr_priv(ovl
->manager
);
195 return mp
->lcd_config
.stallmode
;
198 static bool mgr_manual_update(struct omap_overlay_manager
*mgr
)
200 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
202 return mp
->lcd_config
.stallmode
;
205 static int dss_check_settings_low(struct omap_overlay_manager
*mgr
,
208 struct omap_overlay_info
*oi
;
209 struct omap_overlay_manager_info
*mi
;
210 struct omap_overlay
*ovl
;
211 struct omap_overlay_info
*ois
[MAX_DSS_OVERLAYS
];
212 struct ovl_priv_data
*op
;
213 struct mgr_priv_data
*mp
;
215 mp
= get_mgr_priv(mgr
);
220 if (applying
&& mp
->user_info_dirty
)
225 /* collect the infos to be tested into the array */
226 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
227 op
= get_ovl_priv(ovl
);
229 if (!op
->enabled
&& !op
->enabling
)
231 else if (applying
&& op
->user_info_dirty
)
239 return dss_mgr_check(mgr
, mi
, &mp
->timings
, &mp
->lcd_config
, ois
);
243 * check manager and overlay settings using overlay_info from data->info
245 static int dss_check_settings(struct omap_overlay_manager
*mgr
)
247 return dss_check_settings_low(mgr
, false);
251 * check manager and overlay settings using overlay_info from ovl->info if
252 * dirty and from data->info otherwise
254 static int dss_check_settings_apply(struct omap_overlay_manager
*mgr
)
256 return dss_check_settings_low(mgr
, true);
259 static bool need_isr(void)
261 const int num_mgrs
= dss_feat_get_num_mgrs();
264 for (i
= 0; i
< num_mgrs
; ++i
) {
265 struct omap_overlay_manager
*mgr
;
266 struct mgr_priv_data
*mp
;
267 struct omap_overlay
*ovl
;
269 mgr
= omap_dss_get_overlay_manager(i
);
270 mp
= get_mgr_priv(mgr
);
275 if (mgr_manual_update(mgr
)) {
276 /* to catch FRAMEDONE */
280 /* to catch GO bit going down */
284 /* to write new values to registers */
289 if (mp
->shadow_info_dirty
)
293 * NOTE: we don't check extra_info flags for disabled
294 * managers, once the manager is enabled, the extra_info
295 * related manager changes will be taken in by HW.
298 /* to write new values to registers */
299 if (mp
->extra_info_dirty
)
303 if (mp
->shadow_extra_info_dirty
)
306 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
307 struct ovl_priv_data
*op
;
309 op
= get_ovl_priv(ovl
);
312 * NOTE: we check extra_info flags even for
313 * disabled overlays, as extra_infos need to be
317 /* to write new values to registers */
318 if (op
->extra_info_dirty
)
322 if (op
->shadow_extra_info_dirty
)
328 /* to write new values to registers */
333 if (op
->shadow_info_dirty
)
342 static bool need_go(struct omap_overlay_manager
*mgr
)
344 struct omap_overlay
*ovl
;
345 struct mgr_priv_data
*mp
;
346 struct ovl_priv_data
*op
;
348 mp
= get_mgr_priv(mgr
);
350 if (mp
->shadow_info_dirty
|| mp
->shadow_extra_info_dirty
)
353 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
354 op
= get_ovl_priv(ovl
);
355 if (op
->shadow_info_dirty
|| op
->shadow_extra_info_dirty
)
362 /* returns true if an extra_info field is currently being updated */
363 static bool extra_info_update_ongoing(void)
365 const int num_mgrs
= dss_feat_get_num_mgrs();
368 for (i
= 0; i
< num_mgrs
; ++i
) {
369 struct omap_overlay_manager
*mgr
;
370 struct omap_overlay
*ovl
;
371 struct mgr_priv_data
*mp
;
373 mgr
= omap_dss_get_overlay_manager(i
);
374 mp
= get_mgr_priv(mgr
);
382 if (mp
->extra_info_dirty
|| mp
->shadow_extra_info_dirty
)
385 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
386 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
388 if (op
->extra_info_dirty
|| op
->shadow_extra_info_dirty
)
396 /* wait until no extra_info updates are pending */
397 static void wait_pending_extra_info_updates(void)
404 spin_lock_irqsave(&data_lock
, flags
);
406 updating
= extra_info_update_ongoing();
409 spin_unlock_irqrestore(&data_lock
, flags
);
413 init_completion(&extra_updated_completion
);
415 spin_unlock_irqrestore(&data_lock
, flags
);
417 t
= msecs_to_jiffies(500);
418 r
= wait_for_completion_timeout(&extra_updated_completion
, t
);
420 DSSWARN("timeout in wait_pending_extra_info_updates\n");
423 static struct omap_dss_device
*dss_mgr_get_device(struct omap_overlay_manager
*mgr
)
425 struct omap_dss_device
*dssdev
;
427 dssdev
= mgr
->output
;
432 dssdev
= dssdev
->dst
;
440 static struct omap_dss_device
*dss_ovl_get_device(struct omap_overlay
*ovl
)
442 return ovl
->manager
? dss_mgr_get_device(ovl
->manager
) : NULL
;
445 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager
*mgr
)
447 unsigned long timeout
= msecs_to_jiffies(500);
451 if (mgr
->output
== NULL
)
454 r
= dispc_runtime_get();
458 switch (mgr
->output
->id
) {
459 case OMAP_DSS_OUTPUT_VENC
:
460 irq
= DISPC_IRQ_EVSYNC_ODD
;
462 case OMAP_DSS_OUTPUT_HDMI
:
463 irq
= DISPC_IRQ_EVSYNC_EVEN
;
466 irq
= dispc_mgr_get_vsync_irq(mgr
->id
);
470 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
477 static int dss_mgr_wait_for_go(struct omap_overlay_manager
*mgr
)
479 unsigned long timeout
= msecs_to_jiffies(500);
480 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
486 spin_lock_irqsave(&data_lock
, flags
);
488 if (mgr_manual_update(mgr
)) {
489 spin_unlock_irqrestore(&data_lock
, flags
);
494 spin_unlock_irqrestore(&data_lock
, flags
);
498 spin_unlock_irqrestore(&data_lock
, flags
);
500 r
= dispc_runtime_get();
504 irq
= dispc_mgr_get_vsync_irq(mgr
->id
);
508 bool shadow_dirty
, dirty
;
510 spin_lock_irqsave(&data_lock
, flags
);
511 dirty
= mp
->info_dirty
;
512 shadow_dirty
= mp
->shadow_info_dirty
;
513 spin_unlock_irqrestore(&data_lock
, flags
);
515 if (!dirty
&& !shadow_dirty
) {
520 /* 4 iterations is the worst case:
521 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
522 * 2 - first VSYNC, dirty = true
523 * 3 - dirty = false, shadow_dirty = true
524 * 4 - shadow_dirty = false */
526 DSSERR("mgr(%d)->wait_for_go() not finishing\n",
532 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
533 if (r
== -ERESTARTSYS
)
537 DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr
->id
);
547 static int dss_mgr_wait_for_go_ovl(struct omap_overlay
*ovl
)
549 unsigned long timeout
= msecs_to_jiffies(500);
550 struct ovl_priv_data
*op
;
551 struct mgr_priv_data
*mp
;
560 mp
= get_mgr_priv(ovl
->manager
);
562 spin_lock_irqsave(&data_lock
, flags
);
564 if (ovl_manual_update(ovl
)) {
565 spin_unlock_irqrestore(&data_lock
, flags
);
570 spin_unlock_irqrestore(&data_lock
, flags
);
574 spin_unlock_irqrestore(&data_lock
, flags
);
576 r
= dispc_runtime_get();
580 irq
= dispc_mgr_get_vsync_irq(ovl
->manager
->id
);
582 op
= get_ovl_priv(ovl
);
585 bool shadow_dirty
, dirty
;
587 spin_lock_irqsave(&data_lock
, flags
);
588 dirty
= op
->info_dirty
;
589 shadow_dirty
= op
->shadow_info_dirty
;
590 spin_unlock_irqrestore(&data_lock
, flags
);
592 if (!dirty
&& !shadow_dirty
) {
597 /* 4 iterations is the worst case:
598 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
599 * 2 - first VSYNC, dirty = true
600 * 3 - dirty = false, shadow_dirty = true
601 * 4 - shadow_dirty = false */
603 DSSERR("ovl(%d)->wait_for_go() not finishing\n",
609 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
610 if (r
== -ERESTARTSYS
)
614 DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl
->id
);
624 static void dss_ovl_write_regs(struct omap_overlay
*ovl
)
626 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
627 struct omap_overlay_info
*oi
;
629 struct mgr_priv_data
*mp
;
632 DSSDBG("writing ovl %d regs", ovl
->id
);
634 if (!op
->enabled
|| !op
->info_dirty
)
639 mp
= get_mgr_priv(ovl
->manager
);
641 replication
= dss_ovl_use_replication(mp
->lcd_config
, oi
->color_mode
);
643 r
= dispc_ovl_setup(ovl
->id
, oi
, replication
, &mp
->timings
, false);
646 * We can't do much here, as this function can be called from
649 DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl
->id
);
651 /* This will leave fifo configurations in a nonoptimal state */
653 dispc_ovl_enable(ovl
->id
, false);
657 op
->info_dirty
= false;
659 op
->shadow_info_dirty
= true;
662 static void dss_ovl_write_regs_extra(struct omap_overlay
*ovl
)
664 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
665 struct mgr_priv_data
*mp
;
667 DSSDBG("writing ovl %d regs extra", ovl
->id
);
669 if (!op
->extra_info_dirty
)
672 /* note: write also when op->enabled == false, so that the ovl gets
675 dispc_ovl_enable(ovl
->id
, op
->enabled
);
676 dispc_ovl_set_fifo_threshold(ovl
->id
, op
->fifo_low
, op
->fifo_high
);
678 mp
= get_mgr_priv(ovl
->manager
);
680 op
->extra_info_dirty
= false;
682 op
->shadow_extra_info_dirty
= true;
685 static void dss_mgr_write_regs(struct omap_overlay_manager
*mgr
)
687 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
688 struct omap_overlay
*ovl
;
690 DSSDBG("writing mgr %d regs", mgr
->id
);
697 /* Commit overlay settings */
698 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
699 dss_ovl_write_regs(ovl
);
700 dss_ovl_write_regs_extra(ovl
);
703 if (mp
->info_dirty
) {
704 dispc_mgr_setup(mgr
->id
, &mp
->info
);
706 mp
->info_dirty
= false;
708 mp
->shadow_info_dirty
= true;
712 static void dss_mgr_write_regs_extra(struct omap_overlay_manager
*mgr
)
714 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
716 DSSDBG("writing mgr %d regs extra", mgr
->id
);
718 if (!mp
->extra_info_dirty
)
721 dispc_mgr_set_timings(mgr
->id
, &mp
->timings
);
723 /* lcd_config parameters */
724 if (dss_mgr_is_lcd(mgr
->id
))
725 dispc_mgr_set_lcd_config(mgr
->id
, &mp
->lcd_config
);
727 mp
->extra_info_dirty
= false;
729 mp
->shadow_extra_info_dirty
= true;
732 static void dss_write_regs(void)
734 const int num_mgrs
= omap_dss_get_num_overlay_managers();
737 for (i
= 0; i
< num_mgrs
; ++i
) {
738 struct omap_overlay_manager
*mgr
;
739 struct mgr_priv_data
*mp
;
742 mgr
= omap_dss_get_overlay_manager(i
);
743 mp
= get_mgr_priv(mgr
);
745 if (!mp
->enabled
|| mgr_manual_update(mgr
) || mp
->busy
)
748 r
= dss_check_settings(mgr
);
750 DSSERR("cannot write registers for manager %s: "
751 "illegal configuration\n", mgr
->name
);
755 dss_mgr_write_regs(mgr
);
756 dss_mgr_write_regs_extra(mgr
);
760 static void dss_set_go_bits(void)
762 const int num_mgrs
= omap_dss_get_num_overlay_managers();
765 for (i
= 0; i
< num_mgrs
; ++i
) {
766 struct omap_overlay_manager
*mgr
;
767 struct mgr_priv_data
*mp
;
769 mgr
= omap_dss_get_overlay_manager(i
);
770 mp
= get_mgr_priv(mgr
);
772 if (!mp
->enabled
|| mgr_manual_update(mgr
) || mp
->busy
)
780 if (!dss_data
.irq_enabled
&& need_isr())
781 dss_register_vsync_isr();
783 dispc_mgr_go(mgr
->id
);
788 static void mgr_clear_shadow_dirty(struct omap_overlay_manager
*mgr
)
790 struct omap_overlay
*ovl
;
791 struct mgr_priv_data
*mp
;
792 struct ovl_priv_data
*op
;
794 mp
= get_mgr_priv(mgr
);
795 mp
->shadow_info_dirty
= false;
796 mp
->shadow_extra_info_dirty
= false;
798 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
799 op
= get_ovl_priv(ovl
);
800 op
->shadow_info_dirty
= false;
801 op
->shadow_extra_info_dirty
= false;
805 static int dss_mgr_connect_compat(struct omap_overlay_manager
*mgr
,
806 struct omap_dss_device
*dst
)
808 return mgr
->set_output(mgr
, dst
);
811 static void dss_mgr_disconnect_compat(struct omap_overlay_manager
*mgr
,
812 struct omap_dss_device
*dst
)
814 mgr
->unset_output(mgr
);
817 static void dss_mgr_start_update_compat(struct omap_overlay_manager
*mgr
)
819 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
823 spin_lock_irqsave(&data_lock
, flags
);
825 WARN_ON(mp
->updating
);
827 r
= dss_check_settings(mgr
);
829 DSSERR("cannot start manual update: illegal configuration\n");
830 spin_unlock_irqrestore(&data_lock
, flags
);
834 dss_mgr_write_regs(mgr
);
835 dss_mgr_write_regs_extra(mgr
);
839 if (!dss_data
.irq_enabled
&& need_isr())
840 dss_register_vsync_isr();
842 dispc_mgr_enable_sync(mgr
->id
);
844 spin_unlock_irqrestore(&data_lock
, flags
);
847 static void dss_apply_irq_handler(void *data
, u32 mask
);
849 static void dss_register_vsync_isr(void)
851 const int num_mgrs
= dss_feat_get_num_mgrs();
856 for (i
= 0; i
< num_mgrs
; ++i
)
857 mask
|= dispc_mgr_get_vsync_irq(i
);
859 for (i
= 0; i
< num_mgrs
; ++i
)
860 mask
|= dispc_mgr_get_framedone_irq(i
);
862 r
= omap_dispc_register_isr(dss_apply_irq_handler
, NULL
, mask
);
865 dss_data
.irq_enabled
= true;
868 static void dss_unregister_vsync_isr(void)
870 const int num_mgrs
= dss_feat_get_num_mgrs();
875 for (i
= 0; i
< num_mgrs
; ++i
)
876 mask
|= dispc_mgr_get_vsync_irq(i
);
878 for (i
= 0; i
< num_mgrs
; ++i
)
879 mask
|= dispc_mgr_get_framedone_irq(i
);
881 r
= omap_dispc_unregister_isr(dss_apply_irq_handler
, NULL
, mask
);
884 dss_data
.irq_enabled
= false;
887 static void dss_apply_irq_handler(void *data
, u32 mask
)
889 const int num_mgrs
= dss_feat_get_num_mgrs();
893 spin_lock(&data_lock
);
895 /* clear busy, updating flags, shadow_dirty flags */
896 for (i
= 0; i
< num_mgrs
; i
++) {
897 struct omap_overlay_manager
*mgr
;
898 struct mgr_priv_data
*mp
;
900 mgr
= omap_dss_get_overlay_manager(i
);
901 mp
= get_mgr_priv(mgr
);
906 mp
->updating
= dispc_mgr_is_enabled(i
);
908 if (!mgr_manual_update(mgr
)) {
909 bool was_busy
= mp
->busy
;
910 mp
->busy
= dispc_mgr_go_busy(i
);
912 if (was_busy
&& !mp
->busy
)
913 mgr_clear_shadow_dirty(mgr
);
920 extra_updating
= extra_info_update_ongoing();
922 complete_all(&extra_updated_completion
);
924 /* call framedone handlers for manual update displays */
925 for (i
= 0; i
< num_mgrs
; i
++) {
926 struct omap_overlay_manager
*mgr
;
927 struct mgr_priv_data
*mp
;
929 mgr
= omap_dss_get_overlay_manager(i
);
930 mp
= get_mgr_priv(mgr
);
932 if (!mgr_manual_update(mgr
) || !mp
->framedone_handler
)
935 if (mask
& dispc_mgr_get_framedone_irq(i
))
936 mp
->framedone_handler(mp
->framedone_handler_data
);
940 dss_unregister_vsync_isr();
942 spin_unlock(&data_lock
);
945 static void omap_dss_mgr_apply_ovl(struct omap_overlay
*ovl
)
947 struct ovl_priv_data
*op
;
949 op
= get_ovl_priv(ovl
);
951 if (!op
->user_info_dirty
)
954 op
->user_info_dirty
= false;
955 op
->info_dirty
= true;
956 op
->info
= op
->user_info
;
959 static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager
*mgr
)
961 struct mgr_priv_data
*mp
;
963 mp
= get_mgr_priv(mgr
);
965 if (!mp
->user_info_dirty
)
968 mp
->user_info_dirty
= false;
969 mp
->info_dirty
= true;
970 mp
->info
= mp
->user_info
;
973 static int omap_dss_mgr_apply(struct omap_overlay_manager
*mgr
)
976 struct omap_overlay
*ovl
;
979 DSSDBG("omap_dss_mgr_apply(%s)\n", mgr
->name
);
981 spin_lock_irqsave(&data_lock
, flags
);
983 r
= dss_check_settings_apply(mgr
);
985 spin_unlock_irqrestore(&data_lock
, flags
);
986 DSSERR("failed to apply settings: illegal configuration.\n");
990 /* Configure overlays */
991 list_for_each_entry(ovl
, &mgr
->overlays
, list
)
992 omap_dss_mgr_apply_ovl(ovl
);
994 /* Configure manager */
995 omap_dss_mgr_apply_mgr(mgr
);
1000 spin_unlock_irqrestore(&data_lock
, flags
);
1005 static void dss_apply_ovl_enable(struct omap_overlay
*ovl
, bool enable
)
1007 struct ovl_priv_data
*op
;
1009 op
= get_ovl_priv(ovl
);
1011 if (op
->enabled
== enable
)
1014 op
->enabled
= enable
;
1015 op
->extra_info_dirty
= true;
1018 static void dss_apply_ovl_fifo_thresholds(struct omap_overlay
*ovl
,
1019 u32 fifo_low
, u32 fifo_high
)
1021 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1023 if (op
->fifo_low
== fifo_low
&& op
->fifo_high
== fifo_high
)
1026 op
->fifo_low
= fifo_low
;
1027 op
->fifo_high
= fifo_high
;
1028 op
->extra_info_dirty
= true;
1031 static void dss_ovl_setup_fifo(struct omap_overlay
*ovl
)
1033 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1034 u32 fifo_low
, fifo_high
;
1035 bool use_fifo_merge
= false;
1037 if (!op
->enabled
&& !op
->enabling
)
1040 dispc_ovl_compute_fifo_thresholds(ovl
->id
, &fifo_low
, &fifo_high
,
1041 use_fifo_merge
, ovl_manual_update(ovl
));
1043 dss_apply_ovl_fifo_thresholds(ovl
, fifo_low
, fifo_high
);
1046 static void dss_mgr_setup_fifos(struct omap_overlay_manager
*mgr
)
1048 struct omap_overlay
*ovl
;
1049 struct mgr_priv_data
*mp
;
1051 mp
= get_mgr_priv(mgr
);
1056 list_for_each_entry(ovl
, &mgr
->overlays
, list
)
1057 dss_ovl_setup_fifo(ovl
);
1060 static void dss_setup_fifos(void)
1062 const int num_mgrs
= omap_dss_get_num_overlay_managers();
1063 struct omap_overlay_manager
*mgr
;
1066 for (i
= 0; i
< num_mgrs
; ++i
) {
1067 mgr
= omap_dss_get_overlay_manager(i
);
1068 dss_mgr_setup_fifos(mgr
);
1072 static int dss_mgr_enable_compat(struct omap_overlay_manager
*mgr
)
1074 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1075 unsigned long flags
;
1078 mutex_lock(&apply_lock
);
1083 spin_lock_irqsave(&data_lock
, flags
);
1087 r
= dss_check_settings(mgr
);
1089 DSSERR("failed to enable manager %d: check_settings failed\n",
1099 if (!mgr_manual_update(mgr
))
1100 mp
->updating
= true;
1102 if (!dss_data
.irq_enabled
&& need_isr())
1103 dss_register_vsync_isr();
1105 spin_unlock_irqrestore(&data_lock
, flags
);
1107 if (!mgr_manual_update(mgr
))
1108 dispc_mgr_enable_sync(mgr
->id
);
1111 mutex_unlock(&apply_lock
);
1116 mp
->enabled
= false;
1117 spin_unlock_irqrestore(&data_lock
, flags
);
1118 mutex_unlock(&apply_lock
);
1122 static void dss_mgr_disable_compat(struct omap_overlay_manager
*mgr
)
1124 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1125 unsigned long flags
;
1127 mutex_lock(&apply_lock
);
1132 if (!mgr_manual_update(mgr
))
1133 dispc_mgr_disable_sync(mgr
->id
);
1135 spin_lock_irqsave(&data_lock
, flags
);
1137 mp
->updating
= false;
1138 mp
->enabled
= false;
1140 spin_unlock_irqrestore(&data_lock
, flags
);
1143 mutex_unlock(&apply_lock
);
1146 static int dss_mgr_set_info(struct omap_overlay_manager
*mgr
,
1147 struct omap_overlay_manager_info
*info
)
1149 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1150 unsigned long flags
;
1153 r
= dss_mgr_simple_check(mgr
, info
);
1157 spin_lock_irqsave(&data_lock
, flags
);
1159 mp
->user_info
= *info
;
1160 mp
->user_info_dirty
= true;
1162 spin_unlock_irqrestore(&data_lock
, flags
);
1167 static void dss_mgr_get_info(struct omap_overlay_manager
*mgr
,
1168 struct omap_overlay_manager_info
*info
)
1170 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1171 unsigned long flags
;
1173 spin_lock_irqsave(&data_lock
, flags
);
1175 *info
= mp
->user_info
;
1177 spin_unlock_irqrestore(&data_lock
, flags
);
1180 static int dss_mgr_set_output(struct omap_overlay_manager
*mgr
,
1181 struct omap_dss_device
*output
)
1185 mutex_lock(&apply_lock
);
1188 DSSERR("manager %s is already connected to an output\n",
1194 if ((mgr
->supported_outputs
& output
->id
) == 0) {
1195 DSSERR("output does not support manager %s\n",
1201 output
->manager
= mgr
;
1202 mgr
->output
= output
;
1204 mutex_unlock(&apply_lock
);
1208 mutex_unlock(&apply_lock
);
1212 static int dss_mgr_unset_output(struct omap_overlay_manager
*mgr
)
1215 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1216 unsigned long flags
;
1218 mutex_lock(&apply_lock
);
1221 DSSERR("failed to unset output, output not set\n");
1226 spin_lock_irqsave(&data_lock
, flags
);
1229 DSSERR("output can't be unset when manager is enabled\n");
1234 spin_unlock_irqrestore(&data_lock
, flags
);
1236 mgr
->output
->manager
= NULL
;
1239 mutex_unlock(&apply_lock
);
1243 spin_unlock_irqrestore(&data_lock
, flags
);
1245 mutex_unlock(&apply_lock
);
1250 static void dss_apply_mgr_timings(struct omap_overlay_manager
*mgr
,
1251 const struct omap_video_timings
*timings
)
1253 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1255 mp
->timings
= *timings
;
1256 mp
->extra_info_dirty
= true;
1259 static void dss_mgr_set_timings_compat(struct omap_overlay_manager
*mgr
,
1260 const struct omap_video_timings
*timings
)
1262 unsigned long flags
;
1263 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1265 spin_lock_irqsave(&data_lock
, flags
);
1268 DSSERR("cannot set timings for %s: manager needs to be disabled\n",
1273 dss_apply_mgr_timings(mgr
, timings
);
1275 spin_unlock_irqrestore(&data_lock
, flags
);
1278 static void dss_apply_mgr_lcd_config(struct omap_overlay_manager
*mgr
,
1279 const struct dss_lcd_mgr_config
*config
)
1281 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1283 mp
->lcd_config
= *config
;
1284 mp
->extra_info_dirty
= true;
1287 static void dss_mgr_set_lcd_config_compat(struct omap_overlay_manager
*mgr
,
1288 const struct dss_lcd_mgr_config
*config
)
1290 unsigned long flags
;
1291 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1293 spin_lock_irqsave(&data_lock
, flags
);
1296 DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
1301 dss_apply_mgr_lcd_config(mgr
, config
);
1303 spin_unlock_irqrestore(&data_lock
, flags
);
1306 static int dss_ovl_set_info(struct omap_overlay
*ovl
,
1307 struct omap_overlay_info
*info
)
1309 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1310 unsigned long flags
;
1313 r
= dss_ovl_simple_check(ovl
, info
);
1317 spin_lock_irqsave(&data_lock
, flags
);
1319 op
->user_info
= *info
;
1320 op
->user_info_dirty
= true;
1322 spin_unlock_irqrestore(&data_lock
, flags
);
1327 static void dss_ovl_get_info(struct omap_overlay
*ovl
,
1328 struct omap_overlay_info
*info
)
1330 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1331 unsigned long flags
;
1333 spin_lock_irqsave(&data_lock
, flags
);
1335 *info
= op
->user_info
;
1337 spin_unlock_irqrestore(&data_lock
, flags
);
1340 static int dss_ovl_set_manager(struct omap_overlay
*ovl
,
1341 struct omap_overlay_manager
*mgr
)
1343 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1344 unsigned long flags
;
1350 mutex_lock(&apply_lock
);
1353 DSSERR("overlay '%s' already has a manager '%s'\n",
1354 ovl
->name
, ovl
->manager
->name
);
1359 r
= dispc_runtime_get();
1363 spin_lock_irqsave(&data_lock
, flags
);
1366 spin_unlock_irqrestore(&data_lock
, flags
);
1367 DSSERR("overlay has to be disabled to change the manager\n");
1372 dispc_ovl_set_channel_out(ovl
->id
, mgr
->id
);
1375 list_add_tail(&ovl
->list
, &mgr
->overlays
);
1377 spin_unlock_irqrestore(&data_lock
, flags
);
1379 dispc_runtime_put();
1381 mutex_unlock(&apply_lock
);
1386 dispc_runtime_put();
1388 mutex_unlock(&apply_lock
);
1392 static int dss_ovl_unset_manager(struct omap_overlay
*ovl
)
1394 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1395 unsigned long flags
;
1398 mutex_lock(&apply_lock
);
1400 if (!ovl
->manager
) {
1401 DSSERR("failed to detach overlay: manager not set\n");
1406 spin_lock_irqsave(&data_lock
, flags
);
1409 spin_unlock_irqrestore(&data_lock
, flags
);
1410 DSSERR("overlay has to be disabled to unset the manager\n");
1415 spin_unlock_irqrestore(&data_lock
, flags
);
1417 /* wait for pending extra_info updates to ensure the ovl is disabled */
1418 wait_pending_extra_info_updates();
1421 * For a manual update display, there is no guarantee that the overlay
1422 * is really disabled in HW, we may need an extra update from this
1423 * manager before the configurations can go in. Return an error if the
1424 * overlay needed an update from the manager.
1426 * TODO: Instead of returning an error, try to do a dummy manager update
1427 * here to disable the overlay in hardware. Use the *GATED fields in
1428 * the DISPC_CONFIG registers to do a dummy update.
1430 spin_lock_irqsave(&data_lock
, flags
);
1432 if (ovl_manual_update(ovl
) && op
->extra_info_dirty
) {
1433 spin_unlock_irqrestore(&data_lock
, flags
);
1434 DSSERR("need an update to change the manager\n");
1439 ovl
->manager
= NULL
;
1440 list_del(&ovl
->list
);
1442 spin_unlock_irqrestore(&data_lock
, flags
);
1444 mutex_unlock(&apply_lock
);
1448 mutex_unlock(&apply_lock
);
1452 static bool dss_ovl_is_enabled(struct omap_overlay
*ovl
)
1454 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1455 unsigned long flags
;
1458 spin_lock_irqsave(&data_lock
, flags
);
1462 spin_unlock_irqrestore(&data_lock
, flags
);
1467 static int dss_ovl_enable(struct omap_overlay
*ovl
)
1469 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1470 unsigned long flags
;
1473 mutex_lock(&apply_lock
);
1480 if (ovl
->manager
== NULL
|| ovl
->manager
->output
== NULL
) {
1485 spin_lock_irqsave(&data_lock
, flags
);
1487 op
->enabling
= true;
1489 r
= dss_check_settings(ovl
->manager
);
1491 DSSERR("failed to enable overlay %d: check_settings failed\n",
1498 op
->enabling
= false;
1499 dss_apply_ovl_enable(ovl
, true);
1504 spin_unlock_irqrestore(&data_lock
, flags
);
1506 mutex_unlock(&apply_lock
);
1510 op
->enabling
= false;
1511 spin_unlock_irqrestore(&data_lock
, flags
);
1513 mutex_unlock(&apply_lock
);
1517 static int dss_ovl_disable(struct omap_overlay
*ovl
)
1519 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1520 unsigned long flags
;
1523 mutex_lock(&apply_lock
);
1530 if (ovl
->manager
== NULL
|| ovl
->manager
->output
== NULL
) {
1535 spin_lock_irqsave(&data_lock
, flags
);
1537 dss_apply_ovl_enable(ovl
, false);
1541 spin_unlock_irqrestore(&data_lock
, flags
);
1543 mutex_unlock(&apply_lock
);
1548 mutex_unlock(&apply_lock
);
1552 static int dss_mgr_register_framedone_handler_compat(struct omap_overlay_manager
*mgr
,
1553 void (*handler
)(void *), void *data
)
1555 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1557 if (mp
->framedone_handler
)
1560 mp
->framedone_handler
= handler
;
1561 mp
->framedone_handler_data
= data
;
1566 static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_manager
*mgr
,
1567 void (*handler
)(void *), void *data
)
1569 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1571 WARN_ON(mp
->framedone_handler
!= handler
||
1572 mp
->framedone_handler_data
!= data
);
1574 mp
->framedone_handler
= NULL
;
1575 mp
->framedone_handler_data
= NULL
;
1578 static const struct dss_mgr_ops apply_mgr_ops
= {
1579 .connect
= dss_mgr_connect_compat
,
1580 .disconnect
= dss_mgr_disconnect_compat
,
1581 .start_update
= dss_mgr_start_update_compat
,
1582 .enable
= dss_mgr_enable_compat
,
1583 .disable
= dss_mgr_disable_compat
,
1584 .set_timings
= dss_mgr_set_timings_compat
,
1585 .set_lcd_config
= dss_mgr_set_lcd_config_compat
,
1586 .register_framedone_handler
= dss_mgr_register_framedone_handler_compat
,
1587 .unregister_framedone_handler
= dss_mgr_unregister_framedone_handler_compat
,
1590 static int compat_refcnt
;
1591 static DEFINE_MUTEX(compat_init_lock
);
1593 int omapdss_compat_init(void)
1595 struct platform_device
*pdev
= dss_get_core_pdev();
1598 mutex_lock(&compat_init_lock
);
1600 if (compat_refcnt
++ > 0)
1605 dss_init_overlay_managers_sysfs(pdev
);
1606 dss_init_overlays(pdev
);
1608 for (i
= 0; i
< omap_dss_get_num_overlay_managers(); i
++) {
1609 struct omap_overlay_manager
*mgr
;
1611 mgr
= omap_dss_get_overlay_manager(i
);
1613 mgr
->set_output
= &dss_mgr_set_output
;
1614 mgr
->unset_output
= &dss_mgr_unset_output
;
1615 mgr
->apply
= &omap_dss_mgr_apply
;
1616 mgr
->set_manager_info
= &dss_mgr_set_info
;
1617 mgr
->get_manager_info
= &dss_mgr_get_info
;
1618 mgr
->wait_for_go
= &dss_mgr_wait_for_go
;
1619 mgr
->wait_for_vsync
= &dss_mgr_wait_for_vsync
;
1620 mgr
->get_device
= &dss_mgr_get_device
;
1623 for (i
= 0; i
< omap_dss_get_num_overlays(); i
++) {
1624 struct omap_overlay
*ovl
= omap_dss_get_overlay(i
);
1626 ovl
->is_enabled
= &dss_ovl_is_enabled
;
1627 ovl
->enable
= &dss_ovl_enable
;
1628 ovl
->disable
= &dss_ovl_disable
;
1629 ovl
->set_manager
= &dss_ovl_set_manager
;
1630 ovl
->unset_manager
= &dss_ovl_unset_manager
;
1631 ovl
->set_overlay_info
= &dss_ovl_set_info
;
1632 ovl
->get_overlay_info
= &dss_ovl_get_info
;
1633 ovl
->wait_for_go
= &dss_mgr_wait_for_go_ovl
;
1634 ovl
->get_device
= &dss_ovl_get_device
;
1637 r
= dss_install_mgr_ops(&apply_mgr_ops
);
1641 r
= display_init_sysfs(pdev
);
1643 goto err_disp_sysfs
;
1645 dispc_runtime_get();
1647 r
= dss_dispc_initialize_irq();
1651 dispc_runtime_put();
1654 mutex_unlock(&compat_init_lock
);
1659 dispc_runtime_put();
1660 display_uninit_sysfs(pdev
);
1663 dss_uninstall_mgr_ops();
1666 dss_uninit_overlay_managers_sysfs(pdev
);
1667 dss_uninit_overlays(pdev
);
1671 mutex_unlock(&compat_init_lock
);
1675 EXPORT_SYMBOL(omapdss_compat_init
);
1677 void omapdss_compat_uninit(void)
1679 struct platform_device
*pdev
= dss_get_core_pdev();
1681 mutex_lock(&compat_init_lock
);
1683 if (--compat_refcnt
> 0)
1686 dss_dispc_uninitialize_irq();
1688 display_uninit_sysfs(pdev
);
1690 dss_uninstall_mgr_ops();
1692 dss_uninit_overlay_managers_sysfs(pdev
);
1693 dss_uninit_overlays(pdev
);
1695 mutex_unlock(&compat_init_lock
);
1697 EXPORT_SYMBOL(omapdss_compat_uninit
);