1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2011 Texas Instruments
4 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
7 #define DSS_SUBSYS_NAME "APPLY"
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/slab.h>
12 #include <linux/spinlock.h>
13 #include <linux/jiffies.h>
15 #include <video/omapfb_dss.h>
18 #include "dss_features.h"
19 #include "dispc-compat.h"
22 * We have 4 levels of cache for the dispc settings. First two are in SW and
23 * the latter two in HW.
27 * +--------------------+
29 * +--------------------+
33 * +--------------------+
35 * +--------------------+
39 * +--------------------+
40 * | shadow registers |
41 * +--------------------+
43 * VFP or lcd/digit_enable
45 * +--------------------+
47 * +--------------------+
50 struct ovl_priv_data
{
53 struct omap_overlay_info user_info
;
56 struct omap_overlay_info info
;
58 bool shadow_info_dirty
;
60 bool extra_info_dirty
;
61 bool shadow_extra_info_dirty
;
64 u32 fifo_low
, fifo_high
;
67 * True if overlay is to be enabled. Used to check and calculate configs
68 * for the overlay before it is enabled in the HW.
73 struct mgr_priv_data
{
76 struct omap_overlay_manager_info user_info
;
79 struct omap_overlay_manager_info info
;
81 bool shadow_info_dirty
;
83 /* If true, GO bit is up and shadow registers cannot be written.
84 * Never true for manual update displays */
87 /* If true, dispc output is enabled */
90 /* If true, a display is enabled using this manager */
93 bool extra_info_dirty
;
94 bool shadow_extra_info_dirty
;
96 struct omap_video_timings timings
;
97 struct dss_lcd_mgr_config lcd_config
;
99 void (*framedone_handler
)(void *);
100 void *framedone_handler_data
;
104 struct ovl_priv_data ovl_priv_data_array
[MAX_DSS_OVERLAYS
];
105 struct mgr_priv_data mgr_priv_data_array
[MAX_DSS_MANAGERS
];
110 /* protects dss_data */
111 static DEFINE_SPINLOCK(data_lock
);
112 /* lock for blocking functions */
113 static DEFINE_MUTEX(apply_lock
);
114 static DECLARE_COMPLETION(extra_updated_completion
);
116 static void dss_register_vsync_isr(void);
118 static struct ovl_priv_data
*get_ovl_priv(struct omap_overlay
*ovl
)
120 return &dss_data
.ovl_priv_data_array
[ovl
->id
];
123 static struct mgr_priv_data
*get_mgr_priv(struct omap_overlay_manager
*mgr
)
125 return &dss_data
.mgr_priv_data_array
[mgr
->id
];
128 static void apply_init_priv(void)
130 const int num_ovls
= dss_feat_get_num_ovls();
131 struct mgr_priv_data
*mp
;
134 for (i
= 0; i
< num_ovls
; ++i
) {
135 struct ovl_priv_data
*op
;
137 op
= &dss_data
.ovl_priv_data_array
[i
];
139 op
->info
.color_mode
= OMAP_DSS_COLOR_RGB16
;
140 op
->info
.rotation_type
= OMAP_DSS_ROT_DMA
;
142 op
->info
.global_alpha
= 255;
150 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 3 : 0;
154 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 2 : 0;
158 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 1 : 0;
162 op
->user_info
= op
->info
;
166 * Initialize some of the lcd_config fields for TV manager, this lets
167 * us prevent checking if the manager is LCD or TV at some places
169 mp
= &dss_data
.mgr_priv_data_array
[OMAP_DSS_CHANNEL_DIGIT
];
171 mp
->lcd_config
.video_port_width
= 24;
172 mp
->lcd_config
.clock_info
.lck_div
= 1;
173 mp
->lcd_config
.clock_info
.pck_div
= 1;
177 * A LCD manager's stallmode decides whether it is in manual or auto update. TV
178 * manager is always auto update, stallmode field for TV manager is false by
181 static bool ovl_manual_update(struct omap_overlay
*ovl
)
183 struct mgr_priv_data
*mp
= get_mgr_priv(ovl
->manager
);
185 return mp
->lcd_config
.stallmode
;
188 static bool mgr_manual_update(struct omap_overlay_manager
*mgr
)
190 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
192 return mp
->lcd_config
.stallmode
;
195 static int dss_check_settings_low(struct omap_overlay_manager
*mgr
,
198 struct omap_overlay_info
*oi
;
199 struct omap_overlay_manager_info
*mi
;
200 struct omap_overlay
*ovl
;
201 struct omap_overlay_info
*ois
[MAX_DSS_OVERLAYS
];
202 struct ovl_priv_data
*op
;
203 struct mgr_priv_data
*mp
;
205 mp
= get_mgr_priv(mgr
);
210 if (applying
&& mp
->user_info_dirty
)
215 /* collect the infos to be tested into the array */
216 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
217 op
= get_ovl_priv(ovl
);
219 if (!op
->enabled
&& !op
->enabling
)
221 else if (applying
&& op
->user_info_dirty
)
229 return dss_mgr_check(mgr
, mi
, &mp
->timings
, &mp
->lcd_config
, ois
);
233 * check manager and overlay settings using overlay_info from data->info
235 static int dss_check_settings(struct omap_overlay_manager
*mgr
)
237 return dss_check_settings_low(mgr
, false);
241 * check manager and overlay settings using overlay_info from ovl->info if
242 * dirty and from data->info otherwise
244 static int dss_check_settings_apply(struct omap_overlay_manager
*mgr
)
246 return dss_check_settings_low(mgr
, true);
249 static bool need_isr(void)
251 const int num_mgrs
= dss_feat_get_num_mgrs();
254 for (i
= 0; i
< num_mgrs
; ++i
) {
255 struct omap_overlay_manager
*mgr
;
256 struct mgr_priv_data
*mp
;
257 struct omap_overlay
*ovl
;
259 mgr
= omap_dss_get_overlay_manager(i
);
260 mp
= get_mgr_priv(mgr
);
265 if (mgr_manual_update(mgr
)) {
266 /* to catch FRAMEDONE */
270 /* to catch GO bit going down */
274 /* to write new values to registers */
279 if (mp
->shadow_info_dirty
)
283 * NOTE: we don't check extra_info flags for disabled
284 * managers, once the manager is enabled, the extra_info
285 * related manager changes will be taken in by HW.
288 /* to write new values to registers */
289 if (mp
->extra_info_dirty
)
293 if (mp
->shadow_extra_info_dirty
)
296 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
297 struct ovl_priv_data
*op
;
299 op
= get_ovl_priv(ovl
);
302 * NOTE: we check extra_info flags even for
303 * disabled overlays, as extra_infos need to be
307 /* to write new values to registers */
308 if (op
->extra_info_dirty
)
312 if (op
->shadow_extra_info_dirty
)
318 /* to write new values to registers */
323 if (op
->shadow_info_dirty
)
332 static bool need_go(struct omap_overlay_manager
*mgr
)
334 struct omap_overlay
*ovl
;
335 struct mgr_priv_data
*mp
;
336 struct ovl_priv_data
*op
;
338 mp
= get_mgr_priv(mgr
);
340 if (mp
->shadow_info_dirty
|| mp
->shadow_extra_info_dirty
)
343 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
344 op
= get_ovl_priv(ovl
);
345 if (op
->shadow_info_dirty
|| op
->shadow_extra_info_dirty
)
352 /* returns true if an extra_info field is currently being updated */
353 static bool extra_info_update_ongoing(void)
355 const int num_mgrs
= dss_feat_get_num_mgrs();
358 for (i
= 0; i
< num_mgrs
; ++i
) {
359 struct omap_overlay_manager
*mgr
;
360 struct omap_overlay
*ovl
;
361 struct mgr_priv_data
*mp
;
363 mgr
= omap_dss_get_overlay_manager(i
);
364 mp
= get_mgr_priv(mgr
);
372 if (mp
->extra_info_dirty
|| mp
->shadow_extra_info_dirty
)
375 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
376 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
378 if (op
->extra_info_dirty
|| op
->shadow_extra_info_dirty
)
386 /* wait until no extra_info updates are pending */
387 static void wait_pending_extra_info_updates(void)
394 spin_lock_irqsave(&data_lock
, flags
);
396 updating
= extra_info_update_ongoing();
399 spin_unlock_irqrestore(&data_lock
, flags
);
403 init_completion(&extra_updated_completion
);
405 spin_unlock_irqrestore(&data_lock
, flags
);
407 t
= msecs_to_jiffies(500);
408 r
= wait_for_completion_timeout(&extra_updated_completion
, t
);
410 DSSWARN("timeout in wait_pending_extra_info_updates\n");
413 static struct omap_dss_device
*dss_mgr_get_device(struct omap_overlay_manager
*mgr
)
415 struct omap_dss_device
*dssdev
;
417 dssdev
= mgr
->output
;
422 dssdev
= dssdev
->dst
;
430 static struct omap_dss_device
*dss_ovl_get_device(struct omap_overlay
*ovl
)
432 return ovl
->manager
? dss_mgr_get_device(ovl
->manager
) : NULL
;
435 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager
*mgr
)
437 unsigned long timeout
= msecs_to_jiffies(500);
441 if (mgr
->output
== NULL
)
444 r
= dispc_runtime_get();
448 switch (mgr
->output
->id
) {
449 case OMAP_DSS_OUTPUT_VENC
:
450 irq
= DISPC_IRQ_EVSYNC_ODD
;
452 case OMAP_DSS_OUTPUT_HDMI
:
453 irq
= DISPC_IRQ_EVSYNC_EVEN
;
456 irq
= dispc_mgr_get_vsync_irq(mgr
->id
);
460 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
467 static int dss_mgr_wait_for_go(struct omap_overlay_manager
*mgr
)
469 unsigned long timeout
= msecs_to_jiffies(500);
470 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
476 spin_lock_irqsave(&data_lock
, flags
);
478 if (mgr_manual_update(mgr
)) {
479 spin_unlock_irqrestore(&data_lock
, flags
);
484 spin_unlock_irqrestore(&data_lock
, flags
);
488 spin_unlock_irqrestore(&data_lock
, flags
);
490 r
= dispc_runtime_get();
494 irq
= dispc_mgr_get_vsync_irq(mgr
->id
);
498 bool shadow_dirty
, dirty
;
500 spin_lock_irqsave(&data_lock
, flags
);
501 dirty
= mp
->info_dirty
;
502 shadow_dirty
= mp
->shadow_info_dirty
;
503 spin_unlock_irqrestore(&data_lock
, flags
);
505 if (!dirty
&& !shadow_dirty
) {
510 /* 4 iterations is the worst case:
511 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
512 * 2 - first VSYNC, dirty = true
513 * 3 - dirty = false, shadow_dirty = true
514 * 4 - shadow_dirty = false */
516 DSSERR("mgr(%d)->wait_for_go() not finishing\n",
522 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
523 if (r
== -ERESTARTSYS
)
527 DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr
->id
);
537 static int dss_mgr_wait_for_go_ovl(struct omap_overlay
*ovl
)
539 unsigned long timeout
= msecs_to_jiffies(500);
540 struct ovl_priv_data
*op
;
541 struct mgr_priv_data
*mp
;
550 mp
= get_mgr_priv(ovl
->manager
);
552 spin_lock_irqsave(&data_lock
, flags
);
554 if (ovl_manual_update(ovl
)) {
555 spin_unlock_irqrestore(&data_lock
, flags
);
560 spin_unlock_irqrestore(&data_lock
, flags
);
564 spin_unlock_irqrestore(&data_lock
, flags
);
566 r
= dispc_runtime_get();
570 irq
= dispc_mgr_get_vsync_irq(ovl
->manager
->id
);
572 op
= get_ovl_priv(ovl
);
575 bool shadow_dirty
, dirty
;
577 spin_lock_irqsave(&data_lock
, flags
);
578 dirty
= op
->info_dirty
;
579 shadow_dirty
= op
->shadow_info_dirty
;
580 spin_unlock_irqrestore(&data_lock
, flags
);
582 if (!dirty
&& !shadow_dirty
) {
587 /* 4 iterations is the worst case:
588 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
589 * 2 - first VSYNC, dirty = true
590 * 3 - dirty = false, shadow_dirty = true
591 * 4 - shadow_dirty = false */
593 DSSERR("ovl(%d)->wait_for_go() not finishing\n",
599 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
600 if (r
== -ERESTARTSYS
)
604 DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl
->id
);
614 static void dss_ovl_write_regs(struct omap_overlay
*ovl
)
616 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
617 struct omap_overlay_info
*oi
;
619 struct mgr_priv_data
*mp
;
622 DSSDBG("writing ovl %d regs\n", ovl
->id
);
624 if (!op
->enabled
|| !op
->info_dirty
)
629 mp
= get_mgr_priv(ovl
->manager
);
631 replication
= dss_ovl_use_replication(mp
->lcd_config
, oi
->color_mode
);
633 r
= dispc_ovl_setup(ovl
->id
, oi
, replication
, &mp
->timings
, false);
636 * We can't do much here, as this function can be called from
639 DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl
->id
);
641 /* This will leave fifo configurations in a nonoptimal state */
643 dispc_ovl_enable(ovl
->id
, false);
647 op
->info_dirty
= false;
649 op
->shadow_info_dirty
= true;
652 static void dss_ovl_write_regs_extra(struct omap_overlay
*ovl
)
654 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
655 struct mgr_priv_data
*mp
;
657 DSSDBG("writing ovl %d regs extra\n", ovl
->id
);
659 if (!op
->extra_info_dirty
)
662 /* note: write also when op->enabled == false, so that the ovl gets
665 dispc_ovl_enable(ovl
->id
, op
->enabled
);
666 dispc_ovl_set_fifo_threshold(ovl
->id
, op
->fifo_low
, op
->fifo_high
);
668 mp
= get_mgr_priv(ovl
->manager
);
670 op
->extra_info_dirty
= false;
672 op
->shadow_extra_info_dirty
= true;
675 static void dss_mgr_write_regs(struct omap_overlay_manager
*mgr
)
677 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
678 struct omap_overlay
*ovl
;
680 DSSDBG("writing mgr %d regs\n", mgr
->id
);
687 /* Commit overlay settings */
688 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
689 dss_ovl_write_regs(ovl
);
690 dss_ovl_write_regs_extra(ovl
);
693 if (mp
->info_dirty
) {
694 dispc_mgr_setup(mgr
->id
, &mp
->info
);
696 mp
->info_dirty
= false;
698 mp
->shadow_info_dirty
= true;
702 static void dss_mgr_write_regs_extra(struct omap_overlay_manager
*mgr
)
704 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
706 DSSDBG("writing mgr %d regs extra\n", mgr
->id
);
708 if (!mp
->extra_info_dirty
)
711 dispc_mgr_set_timings(mgr
->id
, &mp
->timings
);
713 /* lcd_config parameters */
714 if (dss_mgr_is_lcd(mgr
->id
))
715 dispc_mgr_set_lcd_config(mgr
->id
, &mp
->lcd_config
);
717 mp
->extra_info_dirty
= false;
719 mp
->shadow_extra_info_dirty
= true;
722 static void dss_write_regs(void)
724 const int num_mgrs
= omap_dss_get_num_overlay_managers();
727 for (i
= 0; i
< num_mgrs
; ++i
) {
728 struct omap_overlay_manager
*mgr
;
729 struct mgr_priv_data
*mp
;
732 mgr
= omap_dss_get_overlay_manager(i
);
733 mp
= get_mgr_priv(mgr
);
735 if (!mp
->enabled
|| mgr_manual_update(mgr
) || mp
->busy
)
738 r
= dss_check_settings(mgr
);
740 DSSERR("cannot write registers for manager %s: "
741 "illegal configuration\n", mgr
->name
);
745 dss_mgr_write_regs(mgr
);
746 dss_mgr_write_regs_extra(mgr
);
750 static void dss_set_go_bits(void)
752 const int num_mgrs
= omap_dss_get_num_overlay_managers();
755 for (i
= 0; i
< num_mgrs
; ++i
) {
756 struct omap_overlay_manager
*mgr
;
757 struct mgr_priv_data
*mp
;
759 mgr
= omap_dss_get_overlay_manager(i
);
760 mp
= get_mgr_priv(mgr
);
762 if (!mp
->enabled
|| mgr_manual_update(mgr
) || mp
->busy
)
770 if (!dss_data
.irq_enabled
&& need_isr())
771 dss_register_vsync_isr();
773 dispc_mgr_go(mgr
->id
);
778 static void mgr_clear_shadow_dirty(struct omap_overlay_manager
*mgr
)
780 struct omap_overlay
*ovl
;
781 struct mgr_priv_data
*mp
;
782 struct ovl_priv_data
*op
;
784 mp
= get_mgr_priv(mgr
);
785 mp
->shadow_info_dirty
= false;
786 mp
->shadow_extra_info_dirty
= false;
788 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
789 op
= get_ovl_priv(ovl
);
790 op
->shadow_info_dirty
= false;
791 op
->shadow_extra_info_dirty
= false;
795 static int dss_mgr_connect_compat(struct omap_overlay_manager
*mgr
,
796 struct omap_dss_device
*dst
)
798 return mgr
->set_output(mgr
, dst
);
801 static void dss_mgr_disconnect_compat(struct omap_overlay_manager
*mgr
,
802 struct omap_dss_device
*dst
)
804 mgr
->unset_output(mgr
);
807 static void dss_mgr_start_update_compat(struct omap_overlay_manager
*mgr
)
809 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
813 spin_lock_irqsave(&data_lock
, flags
);
815 WARN_ON(mp
->updating
);
817 r
= dss_check_settings(mgr
);
819 DSSERR("cannot start manual update: illegal configuration\n");
820 spin_unlock_irqrestore(&data_lock
, flags
);
824 dss_mgr_write_regs(mgr
);
825 dss_mgr_write_regs_extra(mgr
);
829 if (!dss_data
.irq_enabled
&& need_isr())
830 dss_register_vsync_isr();
832 dispc_mgr_enable_sync(mgr
->id
);
834 spin_unlock_irqrestore(&data_lock
, flags
);
837 static void dss_apply_irq_handler(void *data
, u32 mask
);
839 static void dss_register_vsync_isr(void)
841 const int num_mgrs
= dss_feat_get_num_mgrs();
846 for (i
= 0; i
< num_mgrs
; ++i
)
847 mask
|= dispc_mgr_get_vsync_irq(i
);
849 for (i
= 0; i
< num_mgrs
; ++i
)
850 mask
|= dispc_mgr_get_framedone_irq(i
);
852 r
= omap_dispc_register_isr(dss_apply_irq_handler
, NULL
, mask
);
855 dss_data
.irq_enabled
= true;
858 static void dss_unregister_vsync_isr(void)
860 const int num_mgrs
= dss_feat_get_num_mgrs();
865 for (i
= 0; i
< num_mgrs
; ++i
)
866 mask
|= dispc_mgr_get_vsync_irq(i
);
868 for (i
= 0; i
< num_mgrs
; ++i
)
869 mask
|= dispc_mgr_get_framedone_irq(i
);
871 r
= omap_dispc_unregister_isr(dss_apply_irq_handler
, NULL
, mask
);
874 dss_data
.irq_enabled
= false;
877 static void dss_apply_irq_handler(void *data
, u32 mask
)
879 const int num_mgrs
= dss_feat_get_num_mgrs();
883 spin_lock(&data_lock
);
885 /* clear busy, updating flags, shadow_dirty flags */
886 for (i
= 0; i
< num_mgrs
; i
++) {
887 struct omap_overlay_manager
*mgr
;
888 struct mgr_priv_data
*mp
;
890 mgr
= omap_dss_get_overlay_manager(i
);
891 mp
= get_mgr_priv(mgr
);
896 mp
->updating
= dispc_mgr_is_enabled(i
);
898 if (!mgr_manual_update(mgr
)) {
899 bool was_busy
= mp
->busy
;
900 mp
->busy
= dispc_mgr_go_busy(i
);
902 if (was_busy
&& !mp
->busy
)
903 mgr_clear_shadow_dirty(mgr
);
910 extra_updating
= extra_info_update_ongoing();
912 complete_all(&extra_updated_completion
);
914 /* call framedone handlers for manual update displays */
915 for (i
= 0; i
< num_mgrs
; i
++) {
916 struct omap_overlay_manager
*mgr
;
917 struct mgr_priv_data
*mp
;
919 mgr
= omap_dss_get_overlay_manager(i
);
920 mp
= get_mgr_priv(mgr
);
922 if (!mgr_manual_update(mgr
) || !mp
->framedone_handler
)
925 if (mask
& dispc_mgr_get_framedone_irq(i
))
926 mp
->framedone_handler(mp
->framedone_handler_data
);
930 dss_unregister_vsync_isr();
932 spin_unlock(&data_lock
);
935 static void omap_dss_mgr_apply_ovl(struct omap_overlay
*ovl
)
937 struct ovl_priv_data
*op
;
939 op
= get_ovl_priv(ovl
);
941 if (!op
->user_info_dirty
)
944 op
->user_info_dirty
= false;
945 op
->info_dirty
= true;
946 op
->info
= op
->user_info
;
949 static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager
*mgr
)
951 struct mgr_priv_data
*mp
;
953 mp
= get_mgr_priv(mgr
);
955 if (!mp
->user_info_dirty
)
958 mp
->user_info_dirty
= false;
959 mp
->info_dirty
= true;
960 mp
->info
= mp
->user_info
;
963 static int omap_dss_mgr_apply(struct omap_overlay_manager
*mgr
)
966 struct omap_overlay
*ovl
;
969 DSSDBG("omap_dss_mgr_apply(%s)\n", mgr
->name
);
971 spin_lock_irqsave(&data_lock
, flags
);
973 r
= dss_check_settings_apply(mgr
);
975 spin_unlock_irqrestore(&data_lock
, flags
);
976 DSSERR("failed to apply settings: illegal configuration.\n");
980 /* Configure overlays */
981 list_for_each_entry(ovl
, &mgr
->overlays
, list
)
982 omap_dss_mgr_apply_ovl(ovl
);
984 /* Configure manager */
985 omap_dss_mgr_apply_mgr(mgr
);
990 spin_unlock_irqrestore(&data_lock
, flags
);
995 static void dss_apply_ovl_enable(struct omap_overlay
*ovl
, bool enable
)
997 struct ovl_priv_data
*op
;
999 op
= get_ovl_priv(ovl
);
1001 if (op
->enabled
== enable
)
1004 op
->enabled
= enable
;
1005 op
->extra_info_dirty
= true;
1008 static void dss_apply_ovl_fifo_thresholds(struct omap_overlay
*ovl
,
1009 u32 fifo_low
, u32 fifo_high
)
1011 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1013 if (op
->fifo_low
== fifo_low
&& op
->fifo_high
== fifo_high
)
1016 op
->fifo_low
= fifo_low
;
1017 op
->fifo_high
= fifo_high
;
1018 op
->extra_info_dirty
= true;
1021 static void dss_ovl_setup_fifo(struct omap_overlay
*ovl
)
1023 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1024 u32 fifo_low
, fifo_high
;
1025 bool use_fifo_merge
= false;
1027 if (!op
->enabled
&& !op
->enabling
)
1030 dispc_ovl_compute_fifo_thresholds(ovl
->id
, &fifo_low
, &fifo_high
,
1031 use_fifo_merge
, ovl_manual_update(ovl
));
1033 dss_apply_ovl_fifo_thresholds(ovl
, fifo_low
, fifo_high
);
1036 static void dss_mgr_setup_fifos(struct omap_overlay_manager
*mgr
)
1038 struct omap_overlay
*ovl
;
1039 struct mgr_priv_data
*mp
;
1041 mp
= get_mgr_priv(mgr
);
1046 list_for_each_entry(ovl
, &mgr
->overlays
, list
)
1047 dss_ovl_setup_fifo(ovl
);
1050 static void dss_setup_fifos(void)
1052 const int num_mgrs
= omap_dss_get_num_overlay_managers();
1053 struct omap_overlay_manager
*mgr
;
1056 for (i
= 0; i
< num_mgrs
; ++i
) {
1057 mgr
= omap_dss_get_overlay_manager(i
);
1058 dss_mgr_setup_fifos(mgr
);
1062 static int dss_mgr_enable_compat(struct omap_overlay_manager
*mgr
)
1064 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1065 unsigned long flags
;
1068 mutex_lock(&apply_lock
);
1073 spin_lock_irqsave(&data_lock
, flags
);
1077 r
= dss_check_settings(mgr
);
1079 DSSERR("failed to enable manager %d: check_settings failed\n",
1089 if (!mgr_manual_update(mgr
))
1090 mp
->updating
= true;
1092 if (!dss_data
.irq_enabled
&& need_isr())
1093 dss_register_vsync_isr();
1095 spin_unlock_irqrestore(&data_lock
, flags
);
1097 if (!mgr_manual_update(mgr
))
1098 dispc_mgr_enable_sync(mgr
->id
);
1101 mutex_unlock(&apply_lock
);
1106 mp
->enabled
= false;
1107 spin_unlock_irqrestore(&data_lock
, flags
);
1108 mutex_unlock(&apply_lock
);
1112 static void dss_mgr_disable_compat(struct omap_overlay_manager
*mgr
)
1114 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1115 unsigned long flags
;
1117 mutex_lock(&apply_lock
);
1122 wait_pending_extra_info_updates();
1124 if (!mgr_manual_update(mgr
))
1125 dispc_mgr_disable_sync(mgr
->id
);
1127 spin_lock_irqsave(&data_lock
, flags
);
1129 mp
->updating
= false;
1130 mp
->enabled
= false;
1132 spin_unlock_irqrestore(&data_lock
, flags
);
1135 mutex_unlock(&apply_lock
);
1138 static int dss_mgr_set_info(struct omap_overlay_manager
*mgr
,
1139 struct omap_overlay_manager_info
*info
)
1141 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1142 unsigned long flags
;
1145 r
= dss_mgr_simple_check(mgr
, info
);
1149 spin_lock_irqsave(&data_lock
, flags
);
1151 mp
->user_info
= *info
;
1152 mp
->user_info_dirty
= true;
1154 spin_unlock_irqrestore(&data_lock
, flags
);
1159 static void dss_mgr_get_info(struct omap_overlay_manager
*mgr
,
1160 struct omap_overlay_manager_info
*info
)
1162 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1163 unsigned long flags
;
1165 spin_lock_irqsave(&data_lock
, flags
);
1167 *info
= mp
->user_info
;
1169 spin_unlock_irqrestore(&data_lock
, flags
);
1172 static int dss_mgr_set_output(struct omap_overlay_manager
*mgr
,
1173 struct omap_dss_device
*output
)
1177 mutex_lock(&apply_lock
);
1180 DSSERR("manager %s is already connected to an output\n",
1186 if ((mgr
->supported_outputs
& output
->id
) == 0) {
1187 DSSERR("output does not support manager %s\n",
1193 output
->manager
= mgr
;
1194 mgr
->output
= output
;
1196 mutex_unlock(&apply_lock
);
1200 mutex_unlock(&apply_lock
);
1204 static int dss_mgr_unset_output(struct omap_overlay_manager
*mgr
)
1207 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1208 unsigned long flags
;
1210 mutex_lock(&apply_lock
);
1213 DSSERR("failed to unset output, output not set\n");
1218 spin_lock_irqsave(&data_lock
, flags
);
1221 DSSERR("output can't be unset when manager is enabled\n");
1226 spin_unlock_irqrestore(&data_lock
, flags
);
1228 mgr
->output
->manager
= NULL
;
1231 mutex_unlock(&apply_lock
);
1235 spin_unlock_irqrestore(&data_lock
, flags
);
1237 mutex_unlock(&apply_lock
);
1242 static void dss_apply_mgr_timings(struct omap_overlay_manager
*mgr
,
1243 const struct omap_video_timings
*timings
)
1245 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1247 mp
->timings
= *timings
;
1248 mp
->extra_info_dirty
= true;
1251 static void dss_mgr_set_timings_compat(struct omap_overlay_manager
*mgr
,
1252 const struct omap_video_timings
*timings
)
1254 unsigned long flags
;
1255 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1257 spin_lock_irqsave(&data_lock
, flags
);
1260 DSSERR("cannot set timings for %s: manager needs to be disabled\n",
1265 dss_apply_mgr_timings(mgr
, timings
);
1267 spin_unlock_irqrestore(&data_lock
, flags
);
1270 static void dss_apply_mgr_lcd_config(struct omap_overlay_manager
*mgr
,
1271 const struct dss_lcd_mgr_config
*config
)
1273 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1275 mp
->lcd_config
= *config
;
1276 mp
->extra_info_dirty
= true;
1279 static void dss_mgr_set_lcd_config_compat(struct omap_overlay_manager
*mgr
,
1280 const struct dss_lcd_mgr_config
*config
)
1282 unsigned long flags
;
1283 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1285 spin_lock_irqsave(&data_lock
, flags
);
1288 DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
1293 dss_apply_mgr_lcd_config(mgr
, config
);
1295 spin_unlock_irqrestore(&data_lock
, flags
);
1298 static int dss_ovl_set_info(struct omap_overlay
*ovl
,
1299 struct omap_overlay_info
*info
)
1301 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1302 unsigned long flags
;
1305 r
= dss_ovl_simple_check(ovl
, info
);
1309 spin_lock_irqsave(&data_lock
, flags
);
1311 op
->user_info
= *info
;
1312 op
->user_info_dirty
= true;
1314 spin_unlock_irqrestore(&data_lock
, flags
);
1319 static void dss_ovl_get_info(struct omap_overlay
*ovl
,
1320 struct omap_overlay_info
*info
)
1322 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1323 unsigned long flags
;
1325 spin_lock_irqsave(&data_lock
, flags
);
1327 *info
= op
->user_info
;
1329 spin_unlock_irqrestore(&data_lock
, flags
);
1332 static int dss_ovl_set_manager(struct omap_overlay
*ovl
,
1333 struct omap_overlay_manager
*mgr
)
1335 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1336 unsigned long flags
;
1342 mutex_lock(&apply_lock
);
1345 DSSERR("overlay '%s' already has a manager '%s'\n",
1346 ovl
->name
, ovl
->manager
->name
);
1351 r
= dispc_runtime_get();
1355 spin_lock_irqsave(&data_lock
, flags
);
1358 spin_unlock_irqrestore(&data_lock
, flags
);
1359 DSSERR("overlay has to be disabled to change the manager\n");
1364 dispc_ovl_set_channel_out(ovl
->id
, mgr
->id
);
1367 list_add_tail(&ovl
->list
, &mgr
->overlays
);
1369 spin_unlock_irqrestore(&data_lock
, flags
);
1371 dispc_runtime_put();
1373 mutex_unlock(&apply_lock
);
1378 dispc_runtime_put();
1380 mutex_unlock(&apply_lock
);
1384 static int dss_ovl_unset_manager(struct omap_overlay
*ovl
)
1386 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1387 unsigned long flags
;
1390 mutex_lock(&apply_lock
);
1392 if (!ovl
->manager
) {
1393 DSSERR("failed to detach overlay: manager not set\n");
1398 spin_lock_irqsave(&data_lock
, flags
);
1401 spin_unlock_irqrestore(&data_lock
, flags
);
1402 DSSERR("overlay has to be disabled to unset the manager\n");
1407 spin_unlock_irqrestore(&data_lock
, flags
);
1409 /* wait for pending extra_info updates to ensure the ovl is disabled */
1410 wait_pending_extra_info_updates();
1413 * For a manual update display, there is no guarantee that the overlay
1414 * is really disabled in HW, we may need an extra update from this
1415 * manager before the configurations can go in. Return an error if the
1416 * overlay needed an update from the manager.
1418 * TODO: Instead of returning an error, try to do a dummy manager update
1419 * here to disable the overlay in hardware. Use the *GATED fields in
1420 * the DISPC_CONFIG registers to do a dummy update.
1422 spin_lock_irqsave(&data_lock
, flags
);
1424 if (ovl_manual_update(ovl
) && op
->extra_info_dirty
) {
1425 spin_unlock_irqrestore(&data_lock
, flags
);
1426 DSSERR("need an update to change the manager\n");
1431 ovl
->manager
= NULL
;
1432 list_del(&ovl
->list
);
1434 spin_unlock_irqrestore(&data_lock
, flags
);
1436 mutex_unlock(&apply_lock
);
1440 mutex_unlock(&apply_lock
);
1444 static bool dss_ovl_is_enabled(struct omap_overlay
*ovl
)
1446 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1447 unsigned long flags
;
1450 spin_lock_irqsave(&data_lock
, flags
);
1454 spin_unlock_irqrestore(&data_lock
, flags
);
1459 static int dss_ovl_enable(struct omap_overlay
*ovl
)
1461 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1462 unsigned long flags
;
1465 mutex_lock(&apply_lock
);
1472 if (ovl
->manager
== NULL
|| ovl
->manager
->output
== NULL
) {
1477 spin_lock_irqsave(&data_lock
, flags
);
1479 op
->enabling
= true;
1481 r
= dss_check_settings(ovl
->manager
);
1483 DSSERR("failed to enable overlay %d: check_settings failed\n",
1490 op
->enabling
= false;
1491 dss_apply_ovl_enable(ovl
, true);
1496 spin_unlock_irqrestore(&data_lock
, flags
);
1498 mutex_unlock(&apply_lock
);
1502 op
->enabling
= false;
1503 spin_unlock_irqrestore(&data_lock
, flags
);
1505 mutex_unlock(&apply_lock
);
1509 static int dss_ovl_disable(struct omap_overlay
*ovl
)
1511 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1512 unsigned long flags
;
1515 mutex_lock(&apply_lock
);
1522 if (ovl
->manager
== NULL
|| ovl
->manager
->output
== NULL
) {
1527 spin_lock_irqsave(&data_lock
, flags
);
1529 dss_apply_ovl_enable(ovl
, false);
1533 spin_unlock_irqrestore(&data_lock
, flags
);
1535 mutex_unlock(&apply_lock
);
1540 mutex_unlock(&apply_lock
);
1544 static int dss_mgr_register_framedone_handler_compat(struct omap_overlay_manager
*mgr
,
1545 void (*handler
)(void *), void *data
)
1547 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1549 if (mp
->framedone_handler
)
1552 mp
->framedone_handler
= handler
;
1553 mp
->framedone_handler_data
= data
;
1558 static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_manager
*mgr
,
1559 void (*handler
)(void *), void *data
)
1561 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1563 WARN_ON(mp
->framedone_handler
!= handler
||
1564 mp
->framedone_handler_data
!= data
);
1566 mp
->framedone_handler
= NULL
;
1567 mp
->framedone_handler_data
= NULL
;
1570 static const struct dss_mgr_ops apply_mgr_ops
= {
1571 .connect
= dss_mgr_connect_compat
,
1572 .disconnect
= dss_mgr_disconnect_compat
,
1573 .start_update
= dss_mgr_start_update_compat
,
1574 .enable
= dss_mgr_enable_compat
,
1575 .disable
= dss_mgr_disable_compat
,
1576 .set_timings
= dss_mgr_set_timings_compat
,
1577 .set_lcd_config
= dss_mgr_set_lcd_config_compat
,
1578 .register_framedone_handler
= dss_mgr_register_framedone_handler_compat
,
1579 .unregister_framedone_handler
= dss_mgr_unregister_framedone_handler_compat
,
1582 static int compat_refcnt
;
1583 static DEFINE_MUTEX(compat_init_lock
);
1585 int omapdss_compat_init(void)
1587 struct platform_device
*pdev
= dss_get_core_pdev();
1590 mutex_lock(&compat_init_lock
);
1592 if (compat_refcnt
++ > 0)
1597 dss_init_overlay_managers_sysfs(pdev
);
1598 dss_init_overlays(pdev
);
1600 for (i
= 0; i
< omap_dss_get_num_overlay_managers(); i
++) {
1601 struct omap_overlay_manager
*mgr
;
1603 mgr
= omap_dss_get_overlay_manager(i
);
1605 mgr
->set_output
= &dss_mgr_set_output
;
1606 mgr
->unset_output
= &dss_mgr_unset_output
;
1607 mgr
->apply
= &omap_dss_mgr_apply
;
1608 mgr
->set_manager_info
= &dss_mgr_set_info
;
1609 mgr
->get_manager_info
= &dss_mgr_get_info
;
1610 mgr
->wait_for_go
= &dss_mgr_wait_for_go
;
1611 mgr
->wait_for_vsync
= &dss_mgr_wait_for_vsync
;
1612 mgr
->get_device
= &dss_mgr_get_device
;
1615 for (i
= 0; i
< omap_dss_get_num_overlays(); i
++) {
1616 struct omap_overlay
*ovl
= omap_dss_get_overlay(i
);
1618 ovl
->is_enabled
= &dss_ovl_is_enabled
;
1619 ovl
->enable
= &dss_ovl_enable
;
1620 ovl
->disable
= &dss_ovl_disable
;
1621 ovl
->set_manager
= &dss_ovl_set_manager
;
1622 ovl
->unset_manager
= &dss_ovl_unset_manager
;
1623 ovl
->set_overlay_info
= &dss_ovl_set_info
;
1624 ovl
->get_overlay_info
= &dss_ovl_get_info
;
1625 ovl
->wait_for_go
= &dss_mgr_wait_for_go_ovl
;
1626 ovl
->get_device
= &dss_ovl_get_device
;
1629 r
= dss_install_mgr_ops(&apply_mgr_ops
);
1633 r
= display_init_sysfs(pdev
);
1635 goto err_disp_sysfs
;
1637 dispc_runtime_get();
1639 r
= dss_dispc_initialize_irq();
1643 dispc_runtime_put();
1646 mutex_unlock(&compat_init_lock
);
1651 dispc_runtime_put();
1652 display_uninit_sysfs(pdev
);
1655 dss_uninstall_mgr_ops();
1658 dss_uninit_overlay_managers_sysfs(pdev
);
1659 dss_uninit_overlays(pdev
);
1663 mutex_unlock(&compat_init_lock
);
1667 EXPORT_SYMBOL(omapdss_compat_init
);
1669 void omapdss_compat_uninit(void)
1671 struct platform_device
*pdev
= dss_get_core_pdev();
1673 mutex_lock(&compat_init_lock
);
1675 if (--compat_refcnt
> 0)
1678 dss_dispc_uninitialize_irq();
1680 display_uninit_sysfs(pdev
);
1682 dss_uninstall_mgr_ops();
1684 dss_uninit_overlay_managers_sysfs(pdev
);
1685 dss_uninit_overlays(pdev
);
1687 mutex_unlock(&compat_init_lock
);
1689 EXPORT_SYMBOL(omapdss_compat_uninit
);