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 spinlock_t 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 spin_lock_init(&data_lock
);
136 for (i
= 0; i
< num_ovls
; ++i
) {
137 struct ovl_priv_data
*op
;
139 op
= &dss_data
.ovl_priv_data_array
[i
];
141 op
->info
.color_mode
= OMAP_DSS_COLOR_RGB16
;
142 op
->info
.rotation_type
= OMAP_DSS_ROT_DMA
;
144 op
->info
.global_alpha
= 255;
152 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 3 : 0;
156 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 2 : 0;
160 dss_has_feature(FEAT_ALPHA_FREE_ZORDER
) ? 1 : 0;
164 op
->user_info
= op
->info
;
168 * Initialize some of the lcd_config fields for TV manager, this lets
169 * us prevent checking if the manager is LCD or TV at some places
171 mp
= &dss_data
.mgr_priv_data_array
[OMAP_DSS_CHANNEL_DIGIT
];
173 mp
->lcd_config
.video_port_width
= 24;
174 mp
->lcd_config
.clock_info
.lck_div
= 1;
175 mp
->lcd_config
.clock_info
.pck_div
= 1;
179 * A LCD manager's stallmode decides whether it is in manual or auto update. TV
180 * manager is always auto update, stallmode field for TV manager is false by
183 static bool ovl_manual_update(struct omap_overlay
*ovl
)
185 struct mgr_priv_data
*mp
= get_mgr_priv(ovl
->manager
);
187 return mp
->lcd_config
.stallmode
;
190 static bool mgr_manual_update(struct omap_overlay_manager
*mgr
)
192 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
194 return mp
->lcd_config
.stallmode
;
197 static int dss_check_settings_low(struct omap_overlay_manager
*mgr
,
200 struct omap_overlay_info
*oi
;
201 struct omap_overlay_manager_info
*mi
;
202 struct omap_overlay
*ovl
;
203 struct omap_overlay_info
*ois
[MAX_DSS_OVERLAYS
];
204 struct ovl_priv_data
*op
;
205 struct mgr_priv_data
*mp
;
207 mp
= get_mgr_priv(mgr
);
212 if (applying
&& mp
->user_info_dirty
)
217 /* collect the infos to be tested into the array */
218 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
219 op
= get_ovl_priv(ovl
);
221 if (!op
->enabled
&& !op
->enabling
)
223 else if (applying
&& op
->user_info_dirty
)
231 return dss_mgr_check(mgr
, mi
, &mp
->timings
, &mp
->lcd_config
, ois
);
235 * check manager and overlay settings using overlay_info from data->info
237 static int dss_check_settings(struct omap_overlay_manager
*mgr
)
239 return dss_check_settings_low(mgr
, false);
243 * check manager and overlay settings using overlay_info from ovl->info if
244 * dirty and from data->info otherwise
246 static int dss_check_settings_apply(struct omap_overlay_manager
*mgr
)
248 return dss_check_settings_low(mgr
, true);
251 static bool need_isr(void)
253 const int num_mgrs
= dss_feat_get_num_mgrs();
256 for (i
= 0; i
< num_mgrs
; ++i
) {
257 struct omap_overlay_manager
*mgr
;
258 struct mgr_priv_data
*mp
;
259 struct omap_overlay
*ovl
;
261 mgr
= omap_dss_get_overlay_manager(i
);
262 mp
= get_mgr_priv(mgr
);
267 if (mgr_manual_update(mgr
)) {
268 /* to catch FRAMEDONE */
272 /* to catch GO bit going down */
276 /* to write new values to registers */
281 if (mp
->shadow_info_dirty
)
285 * NOTE: we don't check extra_info flags for disabled
286 * managers, once the manager is enabled, the extra_info
287 * related manager changes will be taken in by HW.
290 /* to write new values to registers */
291 if (mp
->extra_info_dirty
)
295 if (mp
->shadow_extra_info_dirty
)
298 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
299 struct ovl_priv_data
*op
;
301 op
= get_ovl_priv(ovl
);
304 * NOTE: we check extra_info flags even for
305 * disabled overlays, as extra_infos need to be
309 /* to write new values to registers */
310 if (op
->extra_info_dirty
)
314 if (op
->shadow_extra_info_dirty
)
320 /* to write new values to registers */
325 if (op
->shadow_info_dirty
)
334 static bool need_go(struct omap_overlay_manager
*mgr
)
336 struct omap_overlay
*ovl
;
337 struct mgr_priv_data
*mp
;
338 struct ovl_priv_data
*op
;
340 mp
= get_mgr_priv(mgr
);
342 if (mp
->shadow_info_dirty
|| mp
->shadow_extra_info_dirty
)
345 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
346 op
= get_ovl_priv(ovl
);
347 if (op
->shadow_info_dirty
|| op
->shadow_extra_info_dirty
)
354 /* returns true if an extra_info field is currently being updated */
355 static bool extra_info_update_ongoing(void)
357 const int num_mgrs
= dss_feat_get_num_mgrs();
360 for (i
= 0; i
< num_mgrs
; ++i
) {
361 struct omap_overlay_manager
*mgr
;
362 struct omap_overlay
*ovl
;
363 struct mgr_priv_data
*mp
;
365 mgr
= omap_dss_get_overlay_manager(i
);
366 mp
= get_mgr_priv(mgr
);
374 if (mp
->extra_info_dirty
|| mp
->shadow_extra_info_dirty
)
377 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
378 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
380 if (op
->extra_info_dirty
|| op
->shadow_extra_info_dirty
)
388 /* wait until no extra_info updates are pending */
389 static void wait_pending_extra_info_updates(void)
396 spin_lock_irqsave(&data_lock
, flags
);
398 updating
= extra_info_update_ongoing();
401 spin_unlock_irqrestore(&data_lock
, flags
);
405 init_completion(&extra_updated_completion
);
407 spin_unlock_irqrestore(&data_lock
, flags
);
409 t
= msecs_to_jiffies(500);
410 r
= wait_for_completion_timeout(&extra_updated_completion
, t
);
412 DSSWARN("timeout in wait_pending_extra_info_updates\n");
415 static struct omap_dss_device
*dss_mgr_get_device(struct omap_overlay_manager
*mgr
)
417 struct omap_dss_device
*dssdev
;
419 dssdev
= mgr
->output
;
424 dssdev
= dssdev
->dst
;
432 static struct omap_dss_device
*dss_ovl_get_device(struct omap_overlay
*ovl
)
434 return ovl
->manager
? dss_mgr_get_device(ovl
->manager
) : NULL
;
437 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager
*mgr
)
439 unsigned long timeout
= msecs_to_jiffies(500);
443 if (mgr
->output
== NULL
)
446 r
= dispc_runtime_get();
450 switch (mgr
->output
->id
) {
451 case OMAP_DSS_OUTPUT_VENC
:
452 irq
= DISPC_IRQ_EVSYNC_ODD
;
454 case OMAP_DSS_OUTPUT_HDMI
:
455 irq
= DISPC_IRQ_EVSYNC_EVEN
;
458 irq
= dispc_mgr_get_vsync_irq(mgr
->id
);
462 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
469 static int dss_mgr_wait_for_go(struct omap_overlay_manager
*mgr
)
471 unsigned long timeout
= msecs_to_jiffies(500);
472 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
478 spin_lock_irqsave(&data_lock
, flags
);
480 if (mgr_manual_update(mgr
)) {
481 spin_unlock_irqrestore(&data_lock
, flags
);
486 spin_unlock_irqrestore(&data_lock
, flags
);
490 spin_unlock_irqrestore(&data_lock
, flags
);
492 r
= dispc_runtime_get();
496 irq
= dispc_mgr_get_vsync_irq(mgr
->id
);
500 bool shadow_dirty
, dirty
;
502 spin_lock_irqsave(&data_lock
, flags
);
503 dirty
= mp
->info_dirty
;
504 shadow_dirty
= mp
->shadow_info_dirty
;
505 spin_unlock_irqrestore(&data_lock
, flags
);
507 if (!dirty
&& !shadow_dirty
) {
512 /* 4 iterations is the worst case:
513 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
514 * 2 - first VSYNC, dirty = true
515 * 3 - dirty = false, shadow_dirty = true
516 * 4 - shadow_dirty = false */
518 DSSERR("mgr(%d)->wait_for_go() not finishing\n",
524 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
525 if (r
== -ERESTARTSYS
)
529 DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr
->id
);
539 static int dss_mgr_wait_for_go_ovl(struct omap_overlay
*ovl
)
541 unsigned long timeout
= msecs_to_jiffies(500);
542 struct ovl_priv_data
*op
;
543 struct mgr_priv_data
*mp
;
552 mp
= get_mgr_priv(ovl
->manager
);
554 spin_lock_irqsave(&data_lock
, flags
);
556 if (ovl_manual_update(ovl
)) {
557 spin_unlock_irqrestore(&data_lock
, flags
);
562 spin_unlock_irqrestore(&data_lock
, flags
);
566 spin_unlock_irqrestore(&data_lock
, flags
);
568 r
= dispc_runtime_get();
572 irq
= dispc_mgr_get_vsync_irq(ovl
->manager
->id
);
574 op
= get_ovl_priv(ovl
);
577 bool shadow_dirty
, dirty
;
579 spin_lock_irqsave(&data_lock
, flags
);
580 dirty
= op
->info_dirty
;
581 shadow_dirty
= op
->shadow_info_dirty
;
582 spin_unlock_irqrestore(&data_lock
, flags
);
584 if (!dirty
&& !shadow_dirty
) {
589 /* 4 iterations is the worst case:
590 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
591 * 2 - first VSYNC, dirty = true
592 * 3 - dirty = false, shadow_dirty = true
593 * 4 - shadow_dirty = false */
595 DSSERR("ovl(%d)->wait_for_go() not finishing\n",
601 r
= omap_dispc_wait_for_irq_interruptible_timeout(irq
, timeout
);
602 if (r
== -ERESTARTSYS
)
606 DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl
->id
);
616 static void dss_ovl_write_regs(struct omap_overlay
*ovl
)
618 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
619 struct omap_overlay_info
*oi
;
621 struct mgr_priv_data
*mp
;
624 DSSDBG("writing ovl %d regs\n", ovl
->id
);
626 if (!op
->enabled
|| !op
->info_dirty
)
631 mp
= get_mgr_priv(ovl
->manager
);
633 replication
= dss_ovl_use_replication(mp
->lcd_config
, oi
->color_mode
);
635 r
= dispc_ovl_setup(ovl
->id
, oi
, replication
, &mp
->timings
, false);
638 * We can't do much here, as this function can be called from
641 DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl
->id
);
643 /* This will leave fifo configurations in a nonoptimal state */
645 dispc_ovl_enable(ovl
->id
, false);
649 op
->info_dirty
= false;
651 op
->shadow_info_dirty
= true;
654 static void dss_ovl_write_regs_extra(struct omap_overlay
*ovl
)
656 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
657 struct mgr_priv_data
*mp
;
659 DSSDBG("writing ovl %d regs extra\n", ovl
->id
);
661 if (!op
->extra_info_dirty
)
664 /* note: write also when op->enabled == false, so that the ovl gets
667 dispc_ovl_enable(ovl
->id
, op
->enabled
);
668 dispc_ovl_set_fifo_threshold(ovl
->id
, op
->fifo_low
, op
->fifo_high
);
670 mp
= get_mgr_priv(ovl
->manager
);
672 op
->extra_info_dirty
= false;
674 op
->shadow_extra_info_dirty
= true;
677 static void dss_mgr_write_regs(struct omap_overlay_manager
*mgr
)
679 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
680 struct omap_overlay
*ovl
;
682 DSSDBG("writing mgr %d regs\n", mgr
->id
);
689 /* Commit overlay settings */
690 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
691 dss_ovl_write_regs(ovl
);
692 dss_ovl_write_regs_extra(ovl
);
695 if (mp
->info_dirty
) {
696 dispc_mgr_setup(mgr
->id
, &mp
->info
);
698 mp
->info_dirty
= false;
700 mp
->shadow_info_dirty
= true;
704 static void dss_mgr_write_regs_extra(struct omap_overlay_manager
*mgr
)
706 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
708 DSSDBG("writing mgr %d regs extra\n", mgr
->id
);
710 if (!mp
->extra_info_dirty
)
713 dispc_mgr_set_timings(mgr
->id
, &mp
->timings
);
715 /* lcd_config parameters */
716 if (dss_mgr_is_lcd(mgr
->id
))
717 dispc_mgr_set_lcd_config(mgr
->id
, &mp
->lcd_config
);
719 mp
->extra_info_dirty
= false;
721 mp
->shadow_extra_info_dirty
= true;
724 static void dss_write_regs(void)
726 const int num_mgrs
= omap_dss_get_num_overlay_managers();
729 for (i
= 0; i
< num_mgrs
; ++i
) {
730 struct omap_overlay_manager
*mgr
;
731 struct mgr_priv_data
*mp
;
734 mgr
= omap_dss_get_overlay_manager(i
);
735 mp
= get_mgr_priv(mgr
);
737 if (!mp
->enabled
|| mgr_manual_update(mgr
) || mp
->busy
)
740 r
= dss_check_settings(mgr
);
742 DSSERR("cannot write registers for manager %s: "
743 "illegal configuration\n", mgr
->name
);
747 dss_mgr_write_regs(mgr
);
748 dss_mgr_write_regs_extra(mgr
);
752 static void dss_set_go_bits(void)
754 const int num_mgrs
= omap_dss_get_num_overlay_managers();
757 for (i
= 0; i
< num_mgrs
; ++i
) {
758 struct omap_overlay_manager
*mgr
;
759 struct mgr_priv_data
*mp
;
761 mgr
= omap_dss_get_overlay_manager(i
);
762 mp
= get_mgr_priv(mgr
);
764 if (!mp
->enabled
|| mgr_manual_update(mgr
) || mp
->busy
)
772 if (!dss_data
.irq_enabled
&& need_isr())
773 dss_register_vsync_isr();
775 dispc_mgr_go(mgr
->id
);
780 static void mgr_clear_shadow_dirty(struct omap_overlay_manager
*mgr
)
782 struct omap_overlay
*ovl
;
783 struct mgr_priv_data
*mp
;
784 struct ovl_priv_data
*op
;
786 mp
= get_mgr_priv(mgr
);
787 mp
->shadow_info_dirty
= false;
788 mp
->shadow_extra_info_dirty
= false;
790 list_for_each_entry(ovl
, &mgr
->overlays
, list
) {
791 op
= get_ovl_priv(ovl
);
792 op
->shadow_info_dirty
= false;
793 op
->shadow_extra_info_dirty
= false;
797 static int dss_mgr_connect_compat(struct omap_overlay_manager
*mgr
,
798 struct omap_dss_device
*dst
)
800 return mgr
->set_output(mgr
, dst
);
803 static void dss_mgr_disconnect_compat(struct omap_overlay_manager
*mgr
,
804 struct omap_dss_device
*dst
)
806 mgr
->unset_output(mgr
);
809 static void dss_mgr_start_update_compat(struct omap_overlay_manager
*mgr
)
811 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
815 spin_lock_irqsave(&data_lock
, flags
);
817 WARN_ON(mp
->updating
);
819 r
= dss_check_settings(mgr
);
821 DSSERR("cannot start manual update: illegal configuration\n");
822 spin_unlock_irqrestore(&data_lock
, flags
);
826 dss_mgr_write_regs(mgr
);
827 dss_mgr_write_regs_extra(mgr
);
831 if (!dss_data
.irq_enabled
&& need_isr())
832 dss_register_vsync_isr();
834 dispc_mgr_enable_sync(mgr
->id
);
836 spin_unlock_irqrestore(&data_lock
, flags
);
839 static void dss_apply_irq_handler(void *data
, u32 mask
);
841 static void dss_register_vsync_isr(void)
843 const int num_mgrs
= dss_feat_get_num_mgrs();
848 for (i
= 0; i
< num_mgrs
; ++i
)
849 mask
|= dispc_mgr_get_vsync_irq(i
);
851 for (i
= 0; i
< num_mgrs
; ++i
)
852 mask
|= dispc_mgr_get_framedone_irq(i
);
854 r
= omap_dispc_register_isr(dss_apply_irq_handler
, NULL
, mask
);
857 dss_data
.irq_enabled
= true;
860 static void dss_unregister_vsync_isr(void)
862 const int num_mgrs
= dss_feat_get_num_mgrs();
867 for (i
= 0; i
< num_mgrs
; ++i
)
868 mask
|= dispc_mgr_get_vsync_irq(i
);
870 for (i
= 0; i
< num_mgrs
; ++i
)
871 mask
|= dispc_mgr_get_framedone_irq(i
);
873 r
= omap_dispc_unregister_isr(dss_apply_irq_handler
, NULL
, mask
);
876 dss_data
.irq_enabled
= false;
879 static void dss_apply_irq_handler(void *data
, u32 mask
)
881 const int num_mgrs
= dss_feat_get_num_mgrs();
885 spin_lock(&data_lock
);
887 /* clear busy, updating flags, shadow_dirty flags */
888 for (i
= 0; i
< num_mgrs
; i
++) {
889 struct omap_overlay_manager
*mgr
;
890 struct mgr_priv_data
*mp
;
892 mgr
= omap_dss_get_overlay_manager(i
);
893 mp
= get_mgr_priv(mgr
);
898 mp
->updating
= dispc_mgr_is_enabled(i
);
900 if (!mgr_manual_update(mgr
)) {
901 bool was_busy
= mp
->busy
;
902 mp
->busy
= dispc_mgr_go_busy(i
);
904 if (was_busy
&& !mp
->busy
)
905 mgr_clear_shadow_dirty(mgr
);
912 extra_updating
= extra_info_update_ongoing();
914 complete_all(&extra_updated_completion
);
916 /* call framedone handlers for manual update displays */
917 for (i
= 0; i
< num_mgrs
; i
++) {
918 struct omap_overlay_manager
*mgr
;
919 struct mgr_priv_data
*mp
;
921 mgr
= omap_dss_get_overlay_manager(i
);
922 mp
= get_mgr_priv(mgr
);
924 if (!mgr_manual_update(mgr
) || !mp
->framedone_handler
)
927 if (mask
& dispc_mgr_get_framedone_irq(i
))
928 mp
->framedone_handler(mp
->framedone_handler_data
);
932 dss_unregister_vsync_isr();
934 spin_unlock(&data_lock
);
937 static void omap_dss_mgr_apply_ovl(struct omap_overlay
*ovl
)
939 struct ovl_priv_data
*op
;
941 op
= get_ovl_priv(ovl
);
943 if (!op
->user_info_dirty
)
946 op
->user_info_dirty
= false;
947 op
->info_dirty
= true;
948 op
->info
= op
->user_info
;
951 static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager
*mgr
)
953 struct mgr_priv_data
*mp
;
955 mp
= get_mgr_priv(mgr
);
957 if (!mp
->user_info_dirty
)
960 mp
->user_info_dirty
= false;
961 mp
->info_dirty
= true;
962 mp
->info
= mp
->user_info
;
965 static int omap_dss_mgr_apply(struct omap_overlay_manager
*mgr
)
968 struct omap_overlay
*ovl
;
971 DSSDBG("omap_dss_mgr_apply(%s)\n", mgr
->name
);
973 spin_lock_irqsave(&data_lock
, flags
);
975 r
= dss_check_settings_apply(mgr
);
977 spin_unlock_irqrestore(&data_lock
, flags
);
978 DSSERR("failed to apply settings: illegal configuration.\n");
982 /* Configure overlays */
983 list_for_each_entry(ovl
, &mgr
->overlays
, list
)
984 omap_dss_mgr_apply_ovl(ovl
);
986 /* Configure manager */
987 omap_dss_mgr_apply_mgr(mgr
);
992 spin_unlock_irqrestore(&data_lock
, flags
);
997 static void dss_apply_ovl_enable(struct omap_overlay
*ovl
, bool enable
)
999 struct ovl_priv_data
*op
;
1001 op
= get_ovl_priv(ovl
);
1003 if (op
->enabled
== enable
)
1006 op
->enabled
= enable
;
1007 op
->extra_info_dirty
= true;
1010 static void dss_apply_ovl_fifo_thresholds(struct omap_overlay
*ovl
,
1011 u32 fifo_low
, u32 fifo_high
)
1013 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1015 if (op
->fifo_low
== fifo_low
&& op
->fifo_high
== fifo_high
)
1018 op
->fifo_low
= fifo_low
;
1019 op
->fifo_high
= fifo_high
;
1020 op
->extra_info_dirty
= true;
1023 static void dss_ovl_setup_fifo(struct omap_overlay
*ovl
)
1025 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1026 u32 fifo_low
, fifo_high
;
1027 bool use_fifo_merge
= false;
1029 if (!op
->enabled
&& !op
->enabling
)
1032 dispc_ovl_compute_fifo_thresholds(ovl
->id
, &fifo_low
, &fifo_high
,
1033 use_fifo_merge
, ovl_manual_update(ovl
));
1035 dss_apply_ovl_fifo_thresholds(ovl
, fifo_low
, fifo_high
);
1038 static void dss_mgr_setup_fifos(struct omap_overlay_manager
*mgr
)
1040 struct omap_overlay
*ovl
;
1041 struct mgr_priv_data
*mp
;
1043 mp
= get_mgr_priv(mgr
);
1048 list_for_each_entry(ovl
, &mgr
->overlays
, list
)
1049 dss_ovl_setup_fifo(ovl
);
1052 static void dss_setup_fifos(void)
1054 const int num_mgrs
= omap_dss_get_num_overlay_managers();
1055 struct omap_overlay_manager
*mgr
;
1058 for (i
= 0; i
< num_mgrs
; ++i
) {
1059 mgr
= omap_dss_get_overlay_manager(i
);
1060 dss_mgr_setup_fifos(mgr
);
1064 static int dss_mgr_enable_compat(struct omap_overlay_manager
*mgr
)
1066 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1067 unsigned long flags
;
1070 mutex_lock(&apply_lock
);
1075 spin_lock_irqsave(&data_lock
, flags
);
1079 r
= dss_check_settings(mgr
);
1081 DSSERR("failed to enable manager %d: check_settings failed\n",
1091 if (!mgr_manual_update(mgr
))
1092 mp
->updating
= true;
1094 if (!dss_data
.irq_enabled
&& need_isr())
1095 dss_register_vsync_isr();
1097 spin_unlock_irqrestore(&data_lock
, flags
);
1099 if (!mgr_manual_update(mgr
))
1100 dispc_mgr_enable_sync(mgr
->id
);
1103 mutex_unlock(&apply_lock
);
1108 mp
->enabled
= false;
1109 spin_unlock_irqrestore(&data_lock
, flags
);
1110 mutex_unlock(&apply_lock
);
1114 static void dss_mgr_disable_compat(struct omap_overlay_manager
*mgr
)
1116 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1117 unsigned long flags
;
1119 mutex_lock(&apply_lock
);
1124 wait_pending_extra_info_updates();
1126 if (!mgr_manual_update(mgr
))
1127 dispc_mgr_disable_sync(mgr
->id
);
1129 spin_lock_irqsave(&data_lock
, flags
);
1131 mp
->updating
= false;
1132 mp
->enabled
= false;
1134 spin_unlock_irqrestore(&data_lock
, flags
);
1137 mutex_unlock(&apply_lock
);
1140 static int dss_mgr_set_info(struct omap_overlay_manager
*mgr
,
1141 struct omap_overlay_manager_info
*info
)
1143 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1144 unsigned long flags
;
1147 r
= dss_mgr_simple_check(mgr
, info
);
1151 spin_lock_irqsave(&data_lock
, flags
);
1153 mp
->user_info
= *info
;
1154 mp
->user_info_dirty
= true;
1156 spin_unlock_irqrestore(&data_lock
, flags
);
1161 static void dss_mgr_get_info(struct omap_overlay_manager
*mgr
,
1162 struct omap_overlay_manager_info
*info
)
1164 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1165 unsigned long flags
;
1167 spin_lock_irqsave(&data_lock
, flags
);
1169 *info
= mp
->user_info
;
1171 spin_unlock_irqrestore(&data_lock
, flags
);
1174 static int dss_mgr_set_output(struct omap_overlay_manager
*mgr
,
1175 struct omap_dss_device
*output
)
1179 mutex_lock(&apply_lock
);
1182 DSSERR("manager %s is already connected to an output\n",
1188 if ((mgr
->supported_outputs
& output
->id
) == 0) {
1189 DSSERR("output does not support manager %s\n",
1195 output
->manager
= mgr
;
1196 mgr
->output
= output
;
1198 mutex_unlock(&apply_lock
);
1202 mutex_unlock(&apply_lock
);
1206 static int dss_mgr_unset_output(struct omap_overlay_manager
*mgr
)
1209 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1210 unsigned long flags
;
1212 mutex_lock(&apply_lock
);
1215 DSSERR("failed to unset output, output not set\n");
1220 spin_lock_irqsave(&data_lock
, flags
);
1223 DSSERR("output can't be unset when manager is enabled\n");
1228 spin_unlock_irqrestore(&data_lock
, flags
);
1230 mgr
->output
->manager
= NULL
;
1233 mutex_unlock(&apply_lock
);
1237 spin_unlock_irqrestore(&data_lock
, flags
);
1239 mutex_unlock(&apply_lock
);
1244 static void dss_apply_mgr_timings(struct omap_overlay_manager
*mgr
,
1245 const struct omap_video_timings
*timings
)
1247 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1249 mp
->timings
= *timings
;
1250 mp
->extra_info_dirty
= true;
1253 static void dss_mgr_set_timings_compat(struct omap_overlay_manager
*mgr
,
1254 const struct omap_video_timings
*timings
)
1256 unsigned long flags
;
1257 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1259 spin_lock_irqsave(&data_lock
, flags
);
1262 DSSERR("cannot set timings for %s: manager needs to be disabled\n",
1267 dss_apply_mgr_timings(mgr
, timings
);
1269 spin_unlock_irqrestore(&data_lock
, flags
);
1272 static void dss_apply_mgr_lcd_config(struct omap_overlay_manager
*mgr
,
1273 const struct dss_lcd_mgr_config
*config
)
1275 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1277 mp
->lcd_config
= *config
;
1278 mp
->extra_info_dirty
= true;
1281 static void dss_mgr_set_lcd_config_compat(struct omap_overlay_manager
*mgr
,
1282 const struct dss_lcd_mgr_config
*config
)
1284 unsigned long flags
;
1285 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1287 spin_lock_irqsave(&data_lock
, flags
);
1290 DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
1295 dss_apply_mgr_lcd_config(mgr
, config
);
1297 spin_unlock_irqrestore(&data_lock
, flags
);
1300 static int dss_ovl_set_info(struct omap_overlay
*ovl
,
1301 struct omap_overlay_info
*info
)
1303 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1304 unsigned long flags
;
1307 r
= dss_ovl_simple_check(ovl
, info
);
1311 spin_lock_irqsave(&data_lock
, flags
);
1313 op
->user_info
= *info
;
1314 op
->user_info_dirty
= true;
1316 spin_unlock_irqrestore(&data_lock
, flags
);
1321 static void dss_ovl_get_info(struct omap_overlay
*ovl
,
1322 struct omap_overlay_info
*info
)
1324 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1325 unsigned long flags
;
1327 spin_lock_irqsave(&data_lock
, flags
);
1329 *info
= op
->user_info
;
1331 spin_unlock_irqrestore(&data_lock
, flags
);
1334 static int dss_ovl_set_manager(struct omap_overlay
*ovl
,
1335 struct omap_overlay_manager
*mgr
)
1337 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1338 unsigned long flags
;
1344 mutex_lock(&apply_lock
);
1347 DSSERR("overlay '%s' already has a manager '%s'\n",
1348 ovl
->name
, ovl
->manager
->name
);
1353 r
= dispc_runtime_get();
1357 spin_lock_irqsave(&data_lock
, flags
);
1360 spin_unlock_irqrestore(&data_lock
, flags
);
1361 DSSERR("overlay has to be disabled to change the manager\n");
1366 dispc_ovl_set_channel_out(ovl
->id
, mgr
->id
);
1369 list_add_tail(&ovl
->list
, &mgr
->overlays
);
1371 spin_unlock_irqrestore(&data_lock
, flags
);
1373 dispc_runtime_put();
1375 mutex_unlock(&apply_lock
);
1380 dispc_runtime_put();
1382 mutex_unlock(&apply_lock
);
1386 static int dss_ovl_unset_manager(struct omap_overlay
*ovl
)
1388 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1389 unsigned long flags
;
1392 mutex_lock(&apply_lock
);
1394 if (!ovl
->manager
) {
1395 DSSERR("failed to detach overlay: manager not set\n");
1400 spin_lock_irqsave(&data_lock
, flags
);
1403 spin_unlock_irqrestore(&data_lock
, flags
);
1404 DSSERR("overlay has to be disabled to unset the manager\n");
1409 spin_unlock_irqrestore(&data_lock
, flags
);
1411 /* wait for pending extra_info updates to ensure the ovl is disabled */
1412 wait_pending_extra_info_updates();
1415 * For a manual update display, there is no guarantee that the overlay
1416 * is really disabled in HW, we may need an extra update from this
1417 * manager before the configurations can go in. Return an error if the
1418 * overlay needed an update from the manager.
1420 * TODO: Instead of returning an error, try to do a dummy manager update
1421 * here to disable the overlay in hardware. Use the *GATED fields in
1422 * the DISPC_CONFIG registers to do a dummy update.
1424 spin_lock_irqsave(&data_lock
, flags
);
1426 if (ovl_manual_update(ovl
) && op
->extra_info_dirty
) {
1427 spin_unlock_irqrestore(&data_lock
, flags
);
1428 DSSERR("need an update to change the manager\n");
1433 ovl
->manager
= NULL
;
1434 list_del(&ovl
->list
);
1436 spin_unlock_irqrestore(&data_lock
, flags
);
1438 mutex_unlock(&apply_lock
);
1442 mutex_unlock(&apply_lock
);
1446 static bool dss_ovl_is_enabled(struct omap_overlay
*ovl
)
1448 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1449 unsigned long flags
;
1452 spin_lock_irqsave(&data_lock
, flags
);
1456 spin_unlock_irqrestore(&data_lock
, flags
);
1461 static int dss_ovl_enable(struct omap_overlay
*ovl
)
1463 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1464 unsigned long flags
;
1467 mutex_lock(&apply_lock
);
1474 if (ovl
->manager
== NULL
|| ovl
->manager
->output
== NULL
) {
1479 spin_lock_irqsave(&data_lock
, flags
);
1481 op
->enabling
= true;
1483 r
= dss_check_settings(ovl
->manager
);
1485 DSSERR("failed to enable overlay %d: check_settings failed\n",
1492 op
->enabling
= false;
1493 dss_apply_ovl_enable(ovl
, true);
1498 spin_unlock_irqrestore(&data_lock
, flags
);
1500 mutex_unlock(&apply_lock
);
1504 op
->enabling
= false;
1505 spin_unlock_irqrestore(&data_lock
, flags
);
1507 mutex_unlock(&apply_lock
);
1511 static int dss_ovl_disable(struct omap_overlay
*ovl
)
1513 struct ovl_priv_data
*op
= get_ovl_priv(ovl
);
1514 unsigned long flags
;
1517 mutex_lock(&apply_lock
);
1524 if (ovl
->manager
== NULL
|| ovl
->manager
->output
== NULL
) {
1529 spin_lock_irqsave(&data_lock
, flags
);
1531 dss_apply_ovl_enable(ovl
, false);
1535 spin_unlock_irqrestore(&data_lock
, flags
);
1537 mutex_unlock(&apply_lock
);
1542 mutex_unlock(&apply_lock
);
1546 static int dss_mgr_register_framedone_handler_compat(struct omap_overlay_manager
*mgr
,
1547 void (*handler
)(void *), void *data
)
1549 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1551 if (mp
->framedone_handler
)
1554 mp
->framedone_handler
= handler
;
1555 mp
->framedone_handler_data
= data
;
1560 static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_manager
*mgr
,
1561 void (*handler
)(void *), void *data
)
1563 struct mgr_priv_data
*mp
= get_mgr_priv(mgr
);
1565 WARN_ON(mp
->framedone_handler
!= handler
||
1566 mp
->framedone_handler_data
!= data
);
1568 mp
->framedone_handler
= NULL
;
1569 mp
->framedone_handler_data
= NULL
;
1572 static const struct dss_mgr_ops apply_mgr_ops
= {
1573 .connect
= dss_mgr_connect_compat
,
1574 .disconnect
= dss_mgr_disconnect_compat
,
1575 .start_update
= dss_mgr_start_update_compat
,
1576 .enable
= dss_mgr_enable_compat
,
1577 .disable
= dss_mgr_disable_compat
,
1578 .set_timings
= dss_mgr_set_timings_compat
,
1579 .set_lcd_config
= dss_mgr_set_lcd_config_compat
,
1580 .register_framedone_handler
= dss_mgr_register_framedone_handler_compat
,
1581 .unregister_framedone_handler
= dss_mgr_unregister_framedone_handler_compat
,
1584 static int compat_refcnt
;
1585 static DEFINE_MUTEX(compat_init_lock
);
1587 int omapdss_compat_init(void)
1589 struct platform_device
*pdev
= dss_get_core_pdev();
1592 mutex_lock(&compat_init_lock
);
1594 if (compat_refcnt
++ > 0)
1599 dss_init_overlay_managers_sysfs(pdev
);
1600 dss_init_overlays(pdev
);
1602 for (i
= 0; i
< omap_dss_get_num_overlay_managers(); i
++) {
1603 struct omap_overlay_manager
*mgr
;
1605 mgr
= omap_dss_get_overlay_manager(i
);
1607 mgr
->set_output
= &dss_mgr_set_output
;
1608 mgr
->unset_output
= &dss_mgr_unset_output
;
1609 mgr
->apply
= &omap_dss_mgr_apply
;
1610 mgr
->set_manager_info
= &dss_mgr_set_info
;
1611 mgr
->get_manager_info
= &dss_mgr_get_info
;
1612 mgr
->wait_for_go
= &dss_mgr_wait_for_go
;
1613 mgr
->wait_for_vsync
= &dss_mgr_wait_for_vsync
;
1614 mgr
->get_device
= &dss_mgr_get_device
;
1617 for (i
= 0; i
< omap_dss_get_num_overlays(); i
++) {
1618 struct omap_overlay
*ovl
= omap_dss_get_overlay(i
);
1620 ovl
->is_enabled
= &dss_ovl_is_enabled
;
1621 ovl
->enable
= &dss_ovl_enable
;
1622 ovl
->disable
= &dss_ovl_disable
;
1623 ovl
->set_manager
= &dss_ovl_set_manager
;
1624 ovl
->unset_manager
= &dss_ovl_unset_manager
;
1625 ovl
->set_overlay_info
= &dss_ovl_set_info
;
1626 ovl
->get_overlay_info
= &dss_ovl_get_info
;
1627 ovl
->wait_for_go
= &dss_mgr_wait_for_go_ovl
;
1628 ovl
->get_device
= &dss_ovl_get_device
;
1631 r
= dss_install_mgr_ops(&apply_mgr_ops
);
1635 r
= display_init_sysfs(pdev
);
1637 goto err_disp_sysfs
;
1639 dispc_runtime_get();
1641 r
= dss_dispc_initialize_irq();
1645 dispc_runtime_put();
1648 mutex_unlock(&compat_init_lock
);
1653 dispc_runtime_put();
1654 display_uninit_sysfs(pdev
);
1657 dss_uninstall_mgr_ops();
1660 dss_uninit_overlay_managers_sysfs(pdev
);
1661 dss_uninit_overlays(pdev
);
1665 mutex_unlock(&compat_init_lock
);
1669 EXPORT_SYMBOL(omapdss_compat_init
);
1671 void omapdss_compat_uninit(void)
1673 struct platform_device
*pdev
= dss_get_core_pdev();
1675 mutex_lock(&compat_init_lock
);
1677 if (--compat_refcnt
> 0)
1680 dss_dispc_uninitialize_irq();
1682 display_uninit_sysfs(pdev
);
1684 dss_uninstall_mgr_ops();
1686 dss_uninit_overlay_managers_sysfs(pdev
);
1687 dss_uninit_overlays(pdev
);
1689 mutex_unlock(&compat_init_lock
);
1691 EXPORT_SYMBOL(omapdss_compat_uninit
);