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/omapfb_dss.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
.color_mode
= OMAP_DSS_COLOR_RGB16
;
153 op
->info
.rotation_type
= OMAP_DSS_ROT_DMA
;
155 op
->info
.global_alpha
= 255;
163 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 3 : 0;
167 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 2 : 0;
171 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 1 : 0;
175 op
->user_info
= op
->info
;
179 * Initialize some of the lcd_config fields for TV manager, this lets
180 * us prevent checking if the manager is LCD or TV at some places
182 mp
= &dss_data
.mgr_priv_data_array
[OMAP_DSS_CHANNEL_DIGIT
];
184 mp
->lcd_config
.video_port_width
= 24;
185 mp
->lcd_config
.clock_info
.lck_div
= 1;
186 mp
->lcd_config
.clock_info
.pck_div
= 1;
190 * A LCD manager's stallmode decides whether it is in manual or auto update. TV
191 * manager is always auto update, stallmode field for TV manager is false by
194 static bool ovl_manual_update(struct omap_overlay
*ovl
)
196 struct mgr_priv_data
*mp
= get_mgr_priv(ovl
->manager
);
198 return mp
->lcd_config
.stallmode
;
201 static bool mgr_manual_update(struct omap_overlay_manager
*mgr
)
203 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
205 return mp
->lcd_config
.stallmode
;
208 static int dss_check_settings_low(struct omap_overlay_manager
*mgr
,
211 struct omap_overlay_info
*oi
;
212 struct omap_overlay_manager_info
*mi
;
213 struct omap_overlay
*ovl
;
214 struct omap_overlay_info
*ois
[MAX_DSS_OVERLAYS
];
215 struct ovl_priv_data
*op
;
216 struct mgr_priv_data
*mp
;
218 mp
= get_mgr_priv(mgr
);
223 if (applying
&& mp
->user_info_dirty
)
228 /* collect the infos to be tested into the array */
229 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
230 op
= get_ovl_priv(ovl
);
232 if (!op
->enabled
&& !op
->enabling
)
234 else if (applying
&& op
->user_info_dirty
)
242 return dss_mgr_check(mgr
, mi
, &mp
->timings
, &mp
->lcd_config
, ois
);
246 * check manager and overlay settings using overlay_info from data->info
248 static int dss_check_settings(struct omap_overlay_manager
*mgr
)
250 return dss_check_settings_low(mgr
, false);
254 * check manager and overlay settings using overlay_info from ovl->info if
255 * dirty and from data->info otherwise
257 static int dss_check_settings_apply(struct omap_overlay_manager
*mgr
)
259 return dss_check_settings_low(mgr
, true);
262 static bool need_isr(void)
264 const int num_mgrs
= dss_feat_get_num_mgrs();
267 for (i
= 0; i
< num_mgrs
; ++i
) {
268 struct omap_overlay_manager
*mgr
;
269 struct mgr_priv_data
*mp
;
270 struct omap_overlay
*ovl
;
272 mgr
= omap_dss_get_overlay_manager(i
);
273 mp
= get_mgr_priv(mgr
);
278 if (mgr_manual_update(mgr
)) {
279 /* to catch FRAMEDONE */
283 /* to catch GO bit going down */
287 /* to write new values to registers */
292 if (mp
->shadow_info_dirty
)
296 * NOTE: we don't check extra_info flags for disabled
297 * managers, once the manager is enabled, the extra_info
298 * related manager changes will be taken in by HW.
301 /* to write new values to registers */
302 if (mp
->extra_info_dirty
)
306 if (mp
->shadow_extra_info_dirty
)
309 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
310 struct ovl_priv_data
*op
;
312 op
= get_ovl_priv(ovl
);
315 * NOTE: we check extra_info flags even for
316 * disabled overlays, as extra_infos need to be
320 /* to write new values to registers */
321 if (op
->extra_info_dirty
)
325 if (op
->shadow_extra_info_dirty
)
331 /* to write new values to registers */
336 if (op
->shadow_info_dirty
)
345 static bool need_go(struct omap_overlay_manager
*mgr
)
347 struct omap_overlay
*ovl
;
348 struct mgr_priv_data
*mp
;
349 struct ovl_priv_data
*op
;
351 mp
= get_mgr_priv(mgr
);
353 if (mp
->shadow_info_dirty
|| mp
->shadow_extra_info_dirty
)
356 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
357 op
= get_ovl_priv(ovl
);
358 if (op
->shadow_info_dirty
|| op
->shadow_extra_info_dirty
)
365 /* returns true if an extra_info field is currently being updated */
366 static bool extra_info_update_ongoing(void)
368 const int num_mgrs
= dss_feat_get_num_mgrs();
371 for (i
= 0; i
< num_mgrs
; ++i
) {
372 struct omap_overlay_manager
*mgr
;
373 struct omap_overlay
*ovl
;
374 struct mgr_priv_data
*mp
;
376 mgr
= omap_dss_get_overlay_manager(i
);
377 mp
= get_mgr_priv(mgr
);
385 if (mp
->extra_info_dirty
|| mp
->shadow_extra_info_dirty
)
388 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
389 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
391 if (op
->extra_info_dirty
|| op
->shadow_extra_info_dirty
)
399 /* wait until no extra_info updates are pending */
400 static void wait_pending_extra_info_updates(void)
407 spin_lock_irqsave(&data_lock
, flags
);
409 updating
= extra_info_update_ongoing();
412 spin_unlock_irqrestore(&data_lock
, flags
);
416 init_completion(&extra_updated_completion
);
418 spin_unlock_irqrestore(&data_lock
, flags
);
420 t
= msecs_to_jiffies(500);
421 r
= wait_for_completion_timeout(&extra_updated_completion
, t
);
423 DSSWARN("timeout in wait_pending_extra_info_updates\n");
426 static struct omap_dss_device
*dss_mgr_get_device(struct omap_overlay_manager
*mgr
)
428 struct omap_dss_device
*dssdev
;
430 dssdev
= mgr
->output
;
435 dssdev
= dssdev
->dst
;
443 static struct omap_dss_device
*dss_ovl_get_device(struct omap_overlay
*ovl
)
445 return ovl
->manager
? dss_mgr_get_device(ovl
->manager
) : NULL
;
448 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager
*mgr
)
450 unsigned long timeout
= msecs_to_jiffies(500);
454 if (mgr
->output
== NULL
)
457 r
= dispc_runtime_get();
461 switch (mgr
->output
->id
) {
462 case OMAP_DSS_OUTPUT_VENC
:
463 irq
= DISPC_IRQ_EVSYNC_ODD
;
465 case OMAP_DSS_OUTPUT_HDMI
:
466 irq
= DISPC_IRQ_EVSYNC_EVEN
;
469 irq
= dispc_mgr_get_vsync_irq(mgr
->id
);
473 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
480 static int dss_mgr_wait_for_go(struct omap_overlay_manager
*mgr
)
482 unsigned long timeout
= msecs_to_jiffies(500);
483 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
489 spin_lock_irqsave(&data_lock
, flags
);
491 if (mgr_manual_update(mgr
)) {
492 spin_unlock_irqrestore(&data_lock
, flags
);
497 spin_unlock_irqrestore(&data_lock
, flags
);
501 spin_unlock_irqrestore(&data_lock
, flags
);
503 r
= dispc_runtime_get();
507 irq
= dispc_mgr_get_vsync_irq(mgr
->id
);
511 bool shadow_dirty
, dirty
;
513 spin_lock_irqsave(&data_lock
, flags
);
514 dirty
= mp
->info_dirty
;
515 shadow_dirty
= mp
->shadow_info_dirty
;
516 spin_unlock_irqrestore(&data_lock
, flags
);
518 if (!dirty
&& !shadow_dirty
) {
523 /* 4 iterations is the worst case:
524 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
525 * 2 - first VSYNC, dirty = true
526 * 3 - dirty = false, shadow_dirty = true
527 * 4 - shadow_dirty = false */
529 DSSERR("mgr(%d)->wait_for_go() not finishing\n",
535 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
536 if (r
== -ERESTARTSYS
)
540 DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr
->id
);
550 static int dss_mgr_wait_for_go_ovl(struct omap_overlay
*ovl
)
552 unsigned long timeout
= msecs_to_jiffies(500);
553 struct ovl_priv_data
*op
;
554 struct mgr_priv_data
*mp
;
563 mp
= get_mgr_priv(ovl
->manager
);
565 spin_lock_irqsave(&data_lock
, flags
);
567 if (ovl_manual_update(ovl
)) {
568 spin_unlock_irqrestore(&data_lock
, flags
);
573 spin_unlock_irqrestore(&data_lock
, flags
);
577 spin_unlock_irqrestore(&data_lock
, flags
);
579 r
= dispc_runtime_get();
583 irq
= dispc_mgr_get_vsync_irq(ovl
->manager
->id
);
585 op
= get_ovl_priv(ovl
);
588 bool shadow_dirty
, dirty
;
590 spin_lock_irqsave(&data_lock
, flags
);
591 dirty
= op
->info_dirty
;
592 shadow_dirty
= op
->shadow_info_dirty
;
593 spin_unlock_irqrestore(&data_lock
, flags
);
595 if (!dirty
&& !shadow_dirty
) {
600 /* 4 iterations is the worst case:
601 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
602 * 2 - first VSYNC, dirty = true
603 * 3 - dirty = false, shadow_dirty = true
604 * 4 - shadow_dirty = false */
606 DSSERR("ovl(%d)->wait_for_go() not finishing\n",
612 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
613 if (r
== -ERESTARTSYS
)
617 DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl
->id
);
627 static void dss_ovl_write_regs(struct omap_overlay
*ovl
)
629 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
630 struct omap_overlay_info
*oi
;
632 struct mgr_priv_data
*mp
;
635 DSSDBG("writing ovl %d regs\n", ovl
->id
);
637 if (!op
->enabled
|| !op
->info_dirty
)
642 mp
= get_mgr_priv(ovl
->manager
);
644 replication
= dss_ovl_use_replication(mp
->lcd_config
, oi
->color_mode
);
646 r
= dispc_ovl_setup(ovl
->id
, oi
, replication
, &mp
->timings
, false);
649 * We can't do much here, as this function can be called from
652 DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl
->id
);
654 /* This will leave fifo configurations in a nonoptimal state */
656 dispc_ovl_enable(ovl
->id
, false);
660 op
->info_dirty
= false;
662 op
->shadow_info_dirty
= true;
665 static void dss_ovl_write_regs_extra(struct omap_overlay
*ovl
)
667 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
668 struct mgr_priv_data
*mp
;
670 DSSDBG("writing ovl %d regs extra\n", ovl
->id
);
672 if (!op
->extra_info_dirty
)
675 /* note: write also when op->enabled == false, so that the ovl gets
678 dispc_ovl_enable(ovl
->id
, op
->enabled
);
679 dispc_ovl_set_fifo_threshold(ovl
->id
, op
->fifo_low
, op
->fifo_high
);
681 mp
= get_mgr_priv(ovl
->manager
);
683 op
->extra_info_dirty
= false;
685 op
->shadow_extra_info_dirty
= true;
688 static void dss_mgr_write_regs(struct omap_overlay_manager
*mgr
)
690 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
691 struct omap_overlay
*ovl
;
693 DSSDBG("writing mgr %d regs\n", mgr
->id
);
700 /* Commit overlay settings */
701 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
702 dss_ovl_write_regs(ovl
);
703 dss_ovl_write_regs_extra(ovl
);
706 if (mp
->info_dirty
) {
707 dispc_mgr_setup(mgr
->id
, &mp
->info
);
709 mp
->info_dirty
= false;
711 mp
->shadow_info_dirty
= true;
715 static void dss_mgr_write_regs_extra(struct omap_overlay_manager
*mgr
)
717 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
719 DSSDBG("writing mgr %d regs extra\n", mgr
->id
);
721 if (!mp
->extra_info_dirty
)
724 dispc_mgr_set_timings(mgr
->id
, &mp
->timings
);
726 /* lcd_config parameters */
727 if (dss_mgr_is_lcd(mgr
->id
))
728 dispc_mgr_set_lcd_config(mgr
->id
, &mp
->lcd_config
);
730 mp
->extra_info_dirty
= false;
732 mp
->shadow_extra_info_dirty
= true;
735 static void dss_write_regs(void)
737 const int num_mgrs
= omap_dss_get_num_overlay_managers();
740 for (i
= 0; i
< num_mgrs
; ++i
) {
741 struct omap_overlay_manager
*mgr
;
742 struct mgr_priv_data
*mp
;
745 mgr
= omap_dss_get_overlay_manager(i
);
746 mp
= get_mgr_priv(mgr
);
748 if (!mp
->enabled
|| mgr_manual_update(mgr
) || mp
->busy
)
751 r
= dss_check_settings(mgr
);
753 DSSERR("cannot write registers for manager %s: "
754 "illegal configuration\n", mgr
->name
);
758 dss_mgr_write_regs(mgr
);
759 dss_mgr_write_regs_extra(mgr
);
763 static void dss_set_go_bits(void)
765 const int num_mgrs
= omap_dss_get_num_overlay_managers();
768 for (i
= 0; i
< num_mgrs
; ++i
) {
769 struct omap_overlay_manager
*mgr
;
770 struct mgr_priv_data
*mp
;
772 mgr
= omap_dss_get_overlay_manager(i
);
773 mp
= get_mgr_priv(mgr
);
775 if (!mp
->enabled
|| mgr_manual_update(mgr
) || mp
->busy
)
783 if (!dss_data
.irq_enabled
&& need_isr())
784 dss_register_vsync_isr();
786 dispc_mgr_go(mgr
->id
);
791 static void mgr_clear_shadow_dirty(struct omap_overlay_manager
*mgr
)
793 struct omap_overlay
*ovl
;
794 struct mgr_priv_data
*mp
;
795 struct ovl_priv_data
*op
;
797 mp
= get_mgr_priv(mgr
);
798 mp
->shadow_info_dirty
= false;
799 mp
->shadow_extra_info_dirty
= false;
801 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
802 op
= get_ovl_priv(ovl
);
803 op
->shadow_info_dirty
= false;
804 op
->shadow_extra_info_dirty
= false;
808 static int dss_mgr_connect_compat(struct omap_overlay_manager
*mgr
,
809 struct omap_dss_device
*dst
)
811 return mgr
->set_output(mgr
, dst
);
814 static void dss_mgr_disconnect_compat(struct omap_overlay_manager
*mgr
,
815 struct omap_dss_device
*dst
)
817 mgr
->unset_output(mgr
);
820 static void dss_mgr_start_update_compat(struct omap_overlay_manager
*mgr
)
822 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
826 spin_lock_irqsave(&data_lock
, flags
);
828 WARN_ON(mp
->updating
);
830 r
= dss_check_settings(mgr
);
832 DSSERR("cannot start manual update: illegal configuration\n");
833 spin_unlock_irqrestore(&data_lock
, flags
);
837 dss_mgr_write_regs(mgr
);
838 dss_mgr_write_regs_extra(mgr
);
842 if (!dss_data
.irq_enabled
&& need_isr())
843 dss_register_vsync_isr();
845 dispc_mgr_enable_sync(mgr
->id
);
847 spin_unlock_irqrestore(&data_lock
, flags
);
850 static void dss_apply_irq_handler(void *data
, u32 mask
);
852 static void dss_register_vsync_isr(void)
854 const int num_mgrs
= dss_feat_get_num_mgrs();
859 for (i
= 0; i
< num_mgrs
; ++i
)
860 mask
|= dispc_mgr_get_vsync_irq(i
);
862 for (i
= 0; i
< num_mgrs
; ++i
)
863 mask
|= dispc_mgr_get_framedone_irq(i
);
865 r
= omap_dispc_register_isr(dss_apply_irq_handler
, NULL
, mask
);
868 dss_data
.irq_enabled
= true;
871 static void dss_unregister_vsync_isr(void)
873 const int num_mgrs
= dss_feat_get_num_mgrs();
878 for (i
= 0; i
< num_mgrs
; ++i
)
879 mask
|= dispc_mgr_get_vsync_irq(i
);
881 for (i
= 0; i
< num_mgrs
; ++i
)
882 mask
|= dispc_mgr_get_framedone_irq(i
);
884 r
= omap_dispc_unregister_isr(dss_apply_irq_handler
, NULL
, mask
);
887 dss_data
.irq_enabled
= false;
890 static void dss_apply_irq_handler(void *data
, u32 mask
)
892 const int num_mgrs
= dss_feat_get_num_mgrs();
896 spin_lock(&data_lock
);
898 /* clear busy, updating flags, shadow_dirty flags */
899 for (i
= 0; i
< num_mgrs
; i
++) {
900 struct omap_overlay_manager
*mgr
;
901 struct mgr_priv_data
*mp
;
903 mgr
= omap_dss_get_overlay_manager(i
);
904 mp
= get_mgr_priv(mgr
);
909 mp
->updating
= dispc_mgr_is_enabled(i
);
911 if (!mgr_manual_update(mgr
)) {
912 bool was_busy
= mp
->busy
;
913 mp
->busy
= dispc_mgr_go_busy(i
);
915 if (was_busy
&& !mp
->busy
)
916 mgr_clear_shadow_dirty(mgr
);
923 extra_updating
= extra_info_update_ongoing();
925 complete_all(&extra_updated_completion
);
927 /* call framedone handlers for manual update displays */
928 for (i
= 0; i
< num_mgrs
; i
++) {
929 struct omap_overlay_manager
*mgr
;
930 struct mgr_priv_data
*mp
;
932 mgr
= omap_dss_get_overlay_manager(i
);
933 mp
= get_mgr_priv(mgr
);
935 if (!mgr_manual_update(mgr
) || !mp
->framedone_handler
)
938 if (mask
& dispc_mgr_get_framedone_irq(i
))
939 mp
->framedone_handler(mp
->framedone_handler_data
);
943 dss_unregister_vsync_isr();
945 spin_unlock(&data_lock
);
948 static void omap_dss_mgr_apply_ovl(struct omap_overlay
*ovl
)
950 struct ovl_priv_data
*op
;
952 op
= get_ovl_priv(ovl
);
954 if (!op
->user_info_dirty
)
957 op
->user_info_dirty
= false;
958 op
->info_dirty
= true;
959 op
->info
= op
->user_info
;
962 static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager
*mgr
)
964 struct mgr_priv_data
*mp
;
966 mp
= get_mgr_priv(mgr
);
968 if (!mp
->user_info_dirty
)
971 mp
->user_info_dirty
= false;
972 mp
->info_dirty
= true;
973 mp
->info
= mp
->user_info
;
976 static int omap_dss_mgr_apply(struct omap_overlay_manager
*mgr
)
979 struct omap_overlay
*ovl
;
982 DSSDBG("omap_dss_mgr_apply(%s)\n", mgr
->name
);
984 spin_lock_irqsave(&data_lock
, flags
);
986 r
= dss_check_settings_apply(mgr
);
988 spin_unlock_irqrestore(&data_lock
, flags
);
989 DSSERR("failed to apply settings: illegal configuration.\n");
993 /* Configure overlays */
994 list_for_each_entry(ovl
, &mgr
->overlays
, list
)
995 omap_dss_mgr_apply_ovl(ovl
);
997 /* Configure manager */
998 omap_dss_mgr_apply_mgr(mgr
);
1003 spin_unlock_irqrestore(&data_lock
, flags
);
1008 static void dss_apply_ovl_enable(struct omap_overlay
*ovl
, bool enable
)
1010 struct ovl_priv_data
*op
;
1012 op
= get_ovl_priv(ovl
);
1014 if (op
->enabled
== enable
)
1017 op
->enabled
= enable
;
1018 op
->extra_info_dirty
= true;
1021 static void dss_apply_ovl_fifo_thresholds(struct omap_overlay
*ovl
,
1022 u32 fifo_low
, u32 fifo_high
)
1024 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1026 if (op
->fifo_low
== fifo_low
&& op
->fifo_high
== fifo_high
)
1029 op
->fifo_low
= fifo_low
;
1030 op
->fifo_high
= fifo_high
;
1031 op
->extra_info_dirty
= true;
1034 static void dss_ovl_setup_fifo(struct omap_overlay
*ovl
)
1036 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1037 u32 fifo_low
, fifo_high
;
1038 bool use_fifo_merge
= false;
1040 if (!op
->enabled
&& !op
->enabling
)
1043 dispc_ovl_compute_fifo_thresholds(ovl
->id
, &fifo_low
, &fifo_high
,
1044 use_fifo_merge
, ovl_manual_update(ovl
));
1046 dss_apply_ovl_fifo_thresholds(ovl
, fifo_low
, fifo_high
);
1049 static void dss_mgr_setup_fifos(struct omap_overlay_manager
*mgr
)
1051 struct omap_overlay
*ovl
;
1052 struct mgr_priv_data
*mp
;
1054 mp
= get_mgr_priv(mgr
);
1059 list_for_each_entry(ovl
, &mgr
->overlays
, list
)
1060 dss_ovl_setup_fifo(ovl
);
1063 static void dss_setup_fifos(void)
1065 const int num_mgrs
= omap_dss_get_num_overlay_managers();
1066 struct omap_overlay_manager
*mgr
;
1069 for (i
= 0; i
< num_mgrs
; ++i
) {
1070 mgr
= omap_dss_get_overlay_manager(i
);
1071 dss_mgr_setup_fifos(mgr
);
1075 static int dss_mgr_enable_compat(struct omap_overlay_manager
*mgr
)
1077 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1078 unsigned long flags
;
1081 mutex_lock(&apply_lock
);
1086 spin_lock_irqsave(&data_lock
, flags
);
1090 r
= dss_check_settings(mgr
);
1092 DSSERR("failed to enable manager %d: check_settings failed\n",
1102 if (!mgr_manual_update(mgr
))
1103 mp
->updating
= true;
1105 if (!dss_data
.irq_enabled
&& need_isr())
1106 dss_register_vsync_isr();
1108 spin_unlock_irqrestore(&data_lock
, flags
);
1110 if (!mgr_manual_update(mgr
))
1111 dispc_mgr_enable_sync(mgr
->id
);
1114 mutex_unlock(&apply_lock
);
1119 mp
->enabled
= false;
1120 spin_unlock_irqrestore(&data_lock
, flags
);
1121 mutex_unlock(&apply_lock
);
1125 static void dss_mgr_disable_compat(struct omap_overlay_manager
*mgr
)
1127 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1128 unsigned long flags
;
1130 mutex_lock(&apply_lock
);
1135 wait_pending_extra_info_updates();
1137 if (!mgr_manual_update(mgr
))
1138 dispc_mgr_disable_sync(mgr
->id
);
1140 spin_lock_irqsave(&data_lock
, flags
);
1142 mp
->updating
= false;
1143 mp
->enabled
= false;
1145 spin_unlock_irqrestore(&data_lock
, flags
);
1148 mutex_unlock(&apply_lock
);
1151 static int dss_mgr_set_info(struct omap_overlay_manager
*mgr
,
1152 struct omap_overlay_manager_info
*info
)
1154 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1155 unsigned long flags
;
1158 r
= dss_mgr_simple_check(mgr
, info
);
1162 spin_lock_irqsave(&data_lock
, flags
);
1164 mp
->user_info
= *info
;
1165 mp
->user_info_dirty
= true;
1167 spin_unlock_irqrestore(&data_lock
, flags
);
1172 static void dss_mgr_get_info(struct omap_overlay_manager
*mgr
,
1173 struct omap_overlay_manager_info
*info
)
1175 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1176 unsigned long flags
;
1178 spin_lock_irqsave(&data_lock
, flags
);
1180 *info
= mp
->user_info
;
1182 spin_unlock_irqrestore(&data_lock
, flags
);
1185 static int dss_mgr_set_output(struct omap_overlay_manager
*mgr
,
1186 struct omap_dss_device
*output
)
1190 mutex_lock(&apply_lock
);
1193 DSSERR("manager %s is already connected to an output\n",
1199 if ((mgr
->supported_outputs
& output
->id
) == 0) {
1200 DSSERR("output does not support manager %s\n",
1206 output
->manager
= mgr
;
1207 mgr
->output
= output
;
1209 mutex_unlock(&apply_lock
);
1213 mutex_unlock(&apply_lock
);
1217 static int dss_mgr_unset_output(struct omap_overlay_manager
*mgr
)
1220 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1221 unsigned long flags
;
1223 mutex_lock(&apply_lock
);
1226 DSSERR("failed to unset output, output not set\n");
1231 spin_lock_irqsave(&data_lock
, flags
);
1234 DSSERR("output can't be unset when manager is enabled\n");
1239 spin_unlock_irqrestore(&data_lock
, flags
);
1241 mgr
->output
->manager
= NULL
;
1244 mutex_unlock(&apply_lock
);
1248 spin_unlock_irqrestore(&data_lock
, flags
);
1250 mutex_unlock(&apply_lock
);
1255 static void dss_apply_mgr_timings(struct omap_overlay_manager
*mgr
,
1256 const struct omap_video_timings
*timings
)
1258 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1260 mp
->timings
= *timings
;
1261 mp
->extra_info_dirty
= true;
1264 static void dss_mgr_set_timings_compat(struct omap_overlay_manager
*mgr
,
1265 const struct omap_video_timings
*timings
)
1267 unsigned long flags
;
1268 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1270 spin_lock_irqsave(&data_lock
, flags
);
1273 DSSERR("cannot set timings for %s: manager needs to be disabled\n",
1278 dss_apply_mgr_timings(mgr
, timings
);
1280 spin_unlock_irqrestore(&data_lock
, flags
);
1283 static void dss_apply_mgr_lcd_config(struct omap_overlay_manager
*mgr
,
1284 const struct dss_lcd_mgr_config
*config
)
1286 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1288 mp
->lcd_config
= *config
;
1289 mp
->extra_info_dirty
= true;
1292 static void dss_mgr_set_lcd_config_compat(struct omap_overlay_manager
*mgr
,
1293 const struct dss_lcd_mgr_config
*config
)
1295 unsigned long flags
;
1296 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1298 spin_lock_irqsave(&data_lock
, flags
);
1301 DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
1306 dss_apply_mgr_lcd_config(mgr
, config
);
1308 spin_unlock_irqrestore(&data_lock
, flags
);
1311 static int dss_ovl_set_info(struct omap_overlay
*ovl
,
1312 struct omap_overlay_info
*info
)
1314 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1315 unsigned long flags
;
1318 r
= dss_ovl_simple_check(ovl
, info
);
1322 spin_lock_irqsave(&data_lock
, flags
);
1324 op
->user_info
= *info
;
1325 op
->user_info_dirty
= true;
1327 spin_unlock_irqrestore(&data_lock
, flags
);
1332 static void dss_ovl_get_info(struct omap_overlay
*ovl
,
1333 struct omap_overlay_info
*info
)
1335 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1336 unsigned long flags
;
1338 spin_lock_irqsave(&data_lock
, flags
);
1340 *info
= op
->user_info
;
1342 spin_unlock_irqrestore(&data_lock
, flags
);
1345 static int dss_ovl_set_manager(struct omap_overlay
*ovl
,
1346 struct omap_overlay_manager
*mgr
)
1348 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1349 unsigned long flags
;
1355 mutex_lock(&apply_lock
);
1358 DSSERR("overlay '%s' already has a manager '%s'\n",
1359 ovl
->name
, ovl
->manager
->name
);
1364 r
= dispc_runtime_get();
1368 spin_lock_irqsave(&data_lock
, flags
);
1371 spin_unlock_irqrestore(&data_lock
, flags
);
1372 DSSERR("overlay has to be disabled to change the manager\n");
1377 dispc_ovl_set_channel_out(ovl
->id
, mgr
->id
);
1380 list_add_tail(&ovl
->list
, &mgr
->overlays
);
1382 spin_unlock_irqrestore(&data_lock
, flags
);
1384 dispc_runtime_put();
1386 mutex_unlock(&apply_lock
);
1391 dispc_runtime_put();
1393 mutex_unlock(&apply_lock
);
1397 static int dss_ovl_unset_manager(struct omap_overlay
*ovl
)
1399 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1400 unsigned long flags
;
1403 mutex_lock(&apply_lock
);
1405 if (!ovl
->manager
) {
1406 DSSERR("failed to detach overlay: manager not set\n");
1411 spin_lock_irqsave(&data_lock
, flags
);
1414 spin_unlock_irqrestore(&data_lock
, flags
);
1415 DSSERR("overlay has to be disabled to unset the manager\n");
1420 spin_unlock_irqrestore(&data_lock
, flags
);
1422 /* wait for pending extra_info updates to ensure the ovl is disabled */
1423 wait_pending_extra_info_updates();
1426 * For a manual update display, there is no guarantee that the overlay
1427 * is really disabled in HW, we may need an extra update from this
1428 * manager before the configurations can go in. Return an error if the
1429 * overlay needed an update from the manager.
1431 * TODO: Instead of returning an error, try to do a dummy manager update
1432 * here to disable the overlay in hardware. Use the *GATED fields in
1433 * the DISPC_CONFIG registers to do a dummy update.
1435 spin_lock_irqsave(&data_lock
, flags
);
1437 if (ovl_manual_update(ovl
) && op
->extra_info_dirty
) {
1438 spin_unlock_irqrestore(&data_lock
, flags
);
1439 DSSERR("need an update to change the manager\n");
1444 ovl
->manager
= NULL
;
1445 list_del(&ovl
->list
);
1447 spin_unlock_irqrestore(&data_lock
, flags
);
1449 mutex_unlock(&apply_lock
);
1453 mutex_unlock(&apply_lock
);
1457 static bool dss_ovl_is_enabled(struct omap_overlay
*ovl
)
1459 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1460 unsigned long flags
;
1463 spin_lock_irqsave(&data_lock
, flags
);
1467 spin_unlock_irqrestore(&data_lock
, flags
);
1472 static int dss_ovl_enable(struct omap_overlay
*ovl
)
1474 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1475 unsigned long flags
;
1478 mutex_lock(&apply_lock
);
1485 if (ovl
->manager
== NULL
|| ovl
->manager
->output
== NULL
) {
1490 spin_lock_irqsave(&data_lock
, flags
);
1492 op
->enabling
= true;
1494 r
= dss_check_settings(ovl
->manager
);
1496 DSSERR("failed to enable overlay %d: check_settings failed\n",
1503 op
->enabling
= false;
1504 dss_apply_ovl_enable(ovl
, true);
1509 spin_unlock_irqrestore(&data_lock
, flags
);
1511 mutex_unlock(&apply_lock
);
1515 op
->enabling
= false;
1516 spin_unlock_irqrestore(&data_lock
, flags
);
1518 mutex_unlock(&apply_lock
);
1522 static int dss_ovl_disable(struct omap_overlay
*ovl
)
1524 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1525 unsigned long flags
;
1528 mutex_lock(&apply_lock
);
1535 if (ovl
->manager
== NULL
|| ovl
->manager
->output
== NULL
) {
1540 spin_lock_irqsave(&data_lock
, flags
);
1542 dss_apply_ovl_enable(ovl
, false);
1546 spin_unlock_irqrestore(&data_lock
, flags
);
1548 mutex_unlock(&apply_lock
);
1553 mutex_unlock(&apply_lock
);
1557 static int dss_mgr_register_framedone_handler_compat(struct omap_overlay_manager
*mgr
,
1558 void (*handler
)(void *), void *data
)
1560 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1562 if (mp
->framedone_handler
)
1565 mp
->framedone_handler
= handler
;
1566 mp
->framedone_handler_data
= data
;
1571 static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_manager
*mgr
,
1572 void (*handler
)(void *), void *data
)
1574 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1576 WARN_ON(mp
->framedone_handler
!= handler
||
1577 mp
->framedone_handler_data
!= data
);
1579 mp
->framedone_handler
= NULL
;
1580 mp
->framedone_handler_data
= NULL
;
1583 static const struct dss_mgr_ops apply_mgr_ops
= {
1584 .connect
= dss_mgr_connect_compat
,
1585 .disconnect
= dss_mgr_disconnect_compat
,
1586 .start_update
= dss_mgr_start_update_compat
,
1587 .enable
= dss_mgr_enable_compat
,
1588 .disable
= dss_mgr_disable_compat
,
1589 .set_timings
= dss_mgr_set_timings_compat
,
1590 .set_lcd_config
= dss_mgr_set_lcd_config_compat
,
1591 .register_framedone_handler
= dss_mgr_register_framedone_handler_compat
,
1592 .unregister_framedone_handler
= dss_mgr_unregister_framedone_handler_compat
,
1595 static int compat_refcnt
;
1596 static DEFINE_MUTEX(compat_init_lock
);
1598 int omapdss_compat_init(void)
1600 struct platform_device
*pdev
= dss_get_core_pdev();
1603 mutex_lock(&compat_init_lock
);
1605 if (compat_refcnt
++ > 0)
1610 dss_init_overlay_managers_sysfs(pdev
);
1611 dss_init_overlays(pdev
);
1613 for (i
= 0; i
< omap_dss_get_num_overlay_managers(); i
++) {
1614 struct omap_overlay_manager
*mgr
;
1616 mgr
= omap_dss_get_overlay_manager(i
);
1618 mgr
->set_output
= &dss_mgr_set_output
;
1619 mgr
->unset_output
= &dss_mgr_unset_output
;
1620 mgr
->apply
= &omap_dss_mgr_apply
;
1621 mgr
->set_manager_info
= &dss_mgr_set_info
;
1622 mgr
->get_manager_info
= &dss_mgr_get_info
;
1623 mgr
->wait_for_go
= &dss_mgr_wait_for_go
;
1624 mgr
->wait_for_vsync
= &dss_mgr_wait_for_vsync
;
1625 mgr
->get_device
= &dss_mgr_get_device
;
1628 for (i
= 0; i
< omap_dss_get_num_overlays(); i
++) {
1629 struct omap_overlay
*ovl
= omap_dss_get_overlay(i
);
1631 ovl
->is_enabled
= &dss_ovl_is_enabled
;
1632 ovl
->enable
= &dss_ovl_enable
;
1633 ovl
->disable
= &dss_ovl_disable
;
1634 ovl
->set_manager
= &dss_ovl_set_manager
;
1635 ovl
->unset_manager
= &dss_ovl_unset_manager
;
1636 ovl
->set_overlay_info
= &dss_ovl_set_info
;
1637 ovl
->get_overlay_info
= &dss_ovl_get_info
;
1638 ovl
->wait_for_go
= &dss_mgr_wait_for_go_ovl
;
1639 ovl
->get_device
= &dss_ovl_get_device
;
1642 r
= dss_install_mgr_ops(&apply_mgr_ops
);
1646 r
= display_init_sysfs(pdev
);
1648 goto err_disp_sysfs
;
1650 dispc_runtime_get();
1652 r
= dss_dispc_initialize_irq();
1656 dispc_runtime_put();
1659 mutex_unlock(&compat_init_lock
);
1664 dispc_runtime_put();
1665 display_uninit_sysfs(pdev
);
1668 dss_uninstall_mgr_ops();
1671 dss_uninit_overlay_managers_sysfs(pdev
);
1672 dss_uninit_overlays(pdev
);
1676 mutex_unlock(&compat_init_lock
);
1680 EXPORT_SYMBOL(omapdss_compat_init
);
1682 void omapdss_compat_uninit(void)
1684 struct platform_device
*pdev
= dss_get_core_pdev();
1686 mutex_lock(&compat_init_lock
);
1688 if (--compat_refcnt
> 0)
1691 dss_dispc_uninitialize_irq();
1693 display_uninit_sysfs(pdev
);
1695 dss_uninstall_mgr_ops();
1697 dss_uninit_overlay_managers_sysfs(pdev
);
1698 dss_uninit_overlays(pdev
);
1700 mutex_unlock(&compat_init_lock
);
1702 EXPORT_SYMBOL(omapdss_compat_uninit
);