aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-10-24 05:39:53 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-12-07 10:05:56 -0500
commitbb39813413db782cc77b94d55cb5d044f42079df (patch)
tree76cd7a0e4654570506682ea0c533be03e0b73bb9 /drivers/video/omap2/dss
parent1550202d4a7593655a2aca99e39a58751073c92a (diff)
OMAPDSS: move blocking mgr enable/disable to compat layer
dispc_mgr_enable_sync and dispc_mgr_disable_sync are only used with the compat mode. Non-compat will use the simpler enable and disable functions. This patch moves the synchronous enable/disable code to the compat layer. A new file is created, dispc-compat.c, which contains low level dispc compat code (versus apply.c, which contains slightly higher level compat code). Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2/dss')
-rw-r--r--drivers/video/omap2/dss/Makefile2
-rw-r--r--drivers/video/omap2/dss/apply.c1
-rw-r--r--drivers/video/omap2/dss/dispc-compat.c207
-rw-r--r--drivers/video/omap2/dss/dispc-compat.h24
-rw-r--r--drivers/video/omap2/dss/dispc.c175
-rw-r--r--drivers/video/omap2/dss/dss.h2
6 files changed, 233 insertions, 178 deletions
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index af866d0b7942..c834f9c42008 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,7 +1,7 @@
1obj-$(CONFIG_OMAP2_DSS) += omapdss.o 1obj-$(CONFIG_OMAP2_DSS) += omapdss.o
2omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ 2omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
3 manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o \ 3 manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o \
4 display-sysfs.o 4 display-sysfs.o dispc-compat.o
5omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o 5omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
6omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o 6omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
7omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o 7omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 5952f149c91a..0de0d3cf1764 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -27,6 +27,7 @@
27 27
28#include "dss.h" 28#include "dss.h"
29#include "dss_features.h" 29#include "dss_features.h"
30#include "dispc-compat.h"
30 31
31/* 32/*
32 * We have 4 levels of cache for the dispc settings. First two are in SW and 33 * We have 4 levels of cache for the dispc settings. First two are in SW and
diff --git a/drivers/video/omap2/dss/dispc-compat.c b/drivers/video/omap2/dss/dispc-compat.c
new file mode 100644
index 000000000000..cca38488ab27
--- /dev/null
+++ b/drivers/video/omap2/dss/dispc-compat.c
@@ -0,0 +1,207 @@
1/*
2 * Copyright (C) 2012 Texas Instruments
3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 *
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.
8 *
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
12 * more details.
13 *
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/>.
16 */
17
18#define DSS_SUBSYS_NAME "APPLY"
19
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>
25#include <linux/delay.h>
26
27#include <video/omapdss.h>
28
29#include "dss.h"
30#include "dss_features.h"
31#include "dispc-compat.h"
32
33static void dispc_mgr_disable_isr(void *data, u32 mask)
34{
35 struct completion *compl = data;
36 complete(compl);
37}
38
39static void dispc_mgr_enable_lcd_out(enum omap_channel channel)
40{
41 dispc_mgr_enable(channel, true);
42}
43
44static void dispc_mgr_disable_lcd_out(enum omap_channel channel)
45{
46 DECLARE_COMPLETION_ONSTACK(framedone_compl);
47 int r;
48 u32 irq;
49
50 if (dispc_mgr_is_enabled(channel) == false)
51 return;
52
53 /*
54 * When we disable LCD output, we need to wait for FRAMEDONE to know
55 * that DISPC has finished with the LCD output.
56 */
57
58 irq = dispc_mgr_get_framedone_irq(channel);
59
60 r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
61 irq);
62 if (r)
63 DSSERR("failed to register FRAMEDONE isr\n");
64
65 dispc_mgr_enable(channel, false);
66
67 /* if we couldn't register for framedone, just sleep and exit */
68 if (r) {
69 msleep(100);
70 return;
71 }
72
73 if (!wait_for_completion_timeout(&framedone_compl,
74 msecs_to_jiffies(100)))
75 DSSERR("timeout waiting for FRAME DONE\n");
76
77 r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
78 irq);
79 if (r)
80 DSSERR("failed to unregister FRAMEDONE isr\n");
81}
82
83static void dispc_digit_out_enable_isr(void *data, u32 mask)
84{
85 struct completion *compl = data;
86
87 /* ignore any sync lost interrupts */
88 if (mask & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD))
89 complete(compl);
90}
91
92static void dispc_mgr_enable_digit_out(void)
93{
94 DECLARE_COMPLETION_ONSTACK(vsync_compl);
95 int r;
96 u32 irq_mask;
97
98 if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == true)
99 return;
100
101 /*
102 * Digit output produces some sync lost interrupts during the first
103 * frame when enabling. Those need to be ignored, so we register for the
104 * sync lost irq to prevent the error handler from triggering.
105 */
106
107 irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT) |
108 dispc_mgr_get_sync_lost_irq(OMAP_DSS_CHANNEL_DIGIT);
109
110 r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl,
111 irq_mask);
112 if (r) {
113 DSSERR("failed to register %x isr\n", irq_mask);
114 return;
115 }
116
117 dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, true);
118
119 /* wait for the first evsync */
120 if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100)))
121 DSSERR("timeout waiting for digit out to start\n");
122
123 r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl,
124 irq_mask);
125 if (r)
126 DSSERR("failed to unregister %x isr\n", irq_mask);
127}
128
129static void dispc_mgr_disable_digit_out(void)
130{
131 DECLARE_COMPLETION_ONSTACK(framedone_compl);
132 int r, i;
133 u32 irq_mask;
134 int num_irqs;
135
136 if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == false)
137 return;
138
139 /*
140 * When we disable the digit output, we need to wait for FRAMEDONE to
141 * know that DISPC has finished with the output.
142 */
143
144 irq_mask = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_DIGIT);
145 num_irqs = 1;
146
147 if (!irq_mask) {
148 /*
149 * omap 2/3 don't have framedone irq for TV, so we need to use
150 * vsyncs for this.
151 */
152
153 irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT);
154 /*
155 * We need to wait for both even and odd vsyncs. Note that this
156 * is not totally reliable, as we could get a vsync interrupt
157 * before we disable the output, which leads to timeout in the
158 * wait_for_completion.
159 */
160 num_irqs = 2;
161 }
162
163 r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
164 irq_mask);
165 if (r)
166 DSSERR("failed to register %x isr\n", irq_mask);
167
168 dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, false);
169
170 /* if we couldn't register the irq, just sleep and exit */
171 if (r) {
172 msleep(100);
173 return;
174 }
175
176 for (i = 0; i < num_irqs; ++i) {
177 if (!wait_for_completion_timeout(&framedone_compl,
178 msecs_to_jiffies(100)))
179 DSSERR("timeout waiting for digit out to stop\n");
180 }
181
182 r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
183 irq_mask);
184 if (r)
185 DSSERR("failed to unregister %x isr\n", irq_mask);
186}
187
188void dispc_mgr_enable_sync(enum omap_channel channel)
189{
190 if (dss_mgr_is_lcd(channel))
191 dispc_mgr_enable_lcd_out(channel);
192 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
193 dispc_mgr_enable_digit_out();
194 else
195 WARN_ON(1);
196}
197
198void dispc_mgr_disable_sync(enum omap_channel channel)
199{
200 if (dss_mgr_is_lcd(channel))
201 dispc_mgr_disable_lcd_out(channel);
202 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
203 dispc_mgr_disable_digit_out();
204 else
205 WARN_ON(1);
206}
207
diff --git a/drivers/video/omap2/dss/dispc-compat.h b/drivers/video/omap2/dss/dispc-compat.h
new file mode 100644
index 000000000000..2d4f5e77a7bf
--- /dev/null
+++ b/drivers/video/omap2/dss/dispc-compat.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (C) 2012 Texas Instruments
3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4 *
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.
8 *
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
12 * more details.
13 *
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/>.
16 */
17
18#ifndef __OMAP2_DSS_DISPC_COMPAT_H
19#define __OMAP2_DSS_DISPC_COMPAT_H
20
21void dispc_mgr_enable_sync(enum omap_channel channel);
22void dispc_mgr_disable_sync(enum omap_channel channel);
23
24#endif
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index f7df52306788..73972e99ec63 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2599,12 +2599,6 @@ bool dispc_ovl_enabled(enum omap_plane plane)
2599 return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0); 2599 return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
2600} 2600}
2601 2601
2602static void dispc_mgr_disable_isr(void *data, u32 mask)
2603{
2604 struct completion *compl = data;
2605 complete(compl);
2606}
2607
2608void dispc_mgr_enable(enum omap_channel channel, bool enable) 2602void dispc_mgr_enable(enum omap_channel channel, bool enable)
2609{ 2603{
2610 mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable); 2604 mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable);
@@ -2617,175 +2611,6 @@ bool dispc_mgr_is_enabled(enum omap_channel channel)
2617 return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); 2611 return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
2618} 2612}
2619 2613
2620static void dispc_mgr_enable_lcd_out(enum omap_channel channel)
2621{
2622 dispc_mgr_enable(channel, true);
2623}
2624
2625static void dispc_mgr_disable_lcd_out(enum omap_channel channel)
2626{
2627 DECLARE_COMPLETION_ONSTACK(framedone_compl);
2628 int r;
2629 u32 irq;
2630
2631 if (dispc_mgr_is_enabled(channel) == false)
2632 return;
2633
2634 /*
2635 * When we disable LCD output, we need to wait for FRAMEDONE to know
2636 * that DISPC has finished with the LCD output.
2637 */
2638
2639 irq = dispc_mgr_get_framedone_irq(channel);
2640
2641 r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
2642 irq);
2643 if (r)
2644 DSSERR("failed to register FRAMEDONE isr\n");
2645
2646 dispc_mgr_enable(channel, false);
2647
2648 /* if we couldn't register for framedone, just sleep and exit */
2649 if (r) {
2650 msleep(100);
2651 return;
2652 }
2653
2654 if (!wait_for_completion_timeout(&framedone_compl,
2655 msecs_to_jiffies(100)))
2656 DSSERR("timeout waiting for FRAME DONE\n");
2657
2658 r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
2659 irq);
2660 if (r)
2661 DSSERR("failed to unregister FRAMEDONE isr\n");
2662}
2663
2664static void dispc_digit_out_enable_isr(void *data, u32 mask)
2665{
2666 struct completion *compl = data;
2667
2668 /* ignore any sync lost interrupts */
2669 if (mask & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD))
2670 complete(compl);
2671}
2672
2673static void dispc_mgr_enable_digit_out(void)
2674{
2675 DECLARE_COMPLETION_ONSTACK(vsync_compl);
2676 int r;
2677 u32 irq_mask;
2678
2679 if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == true)
2680 return;
2681
2682 /*
2683 * Digit output produces some sync lost interrupts during the first
2684 * frame when enabling. Those need to be ignored, so we register for the
2685 * sync lost irq to prevent the error handler from triggering.
2686 */
2687
2688 irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT) |
2689 dispc_mgr_get_sync_lost_irq(OMAP_DSS_CHANNEL_DIGIT);
2690
2691 r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl,
2692 irq_mask);
2693 if (r) {
2694 DSSERR("failed to register %x isr\n", irq_mask);
2695 return;
2696 }
2697
2698 dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, true);
2699
2700 /* wait for the first evsync */
2701 if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100)))
2702 DSSERR("timeout waiting for digit out to start\n");
2703
2704 r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl,
2705 irq_mask);
2706 if (r)
2707 DSSERR("failed to unregister %x isr\n", irq_mask);
2708}
2709
2710static void dispc_mgr_disable_digit_out(void)
2711{
2712 DECLARE_COMPLETION_ONSTACK(framedone_compl);
2713 int r, i;
2714 u32 irq_mask;
2715 int num_irqs;
2716
2717 if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == false)
2718 return;
2719
2720 /*
2721 * When we disable the digit output, we need to wait for FRAMEDONE to
2722 * know that DISPC has finished with the output.
2723 */
2724
2725 irq_mask = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_DIGIT);
2726 num_irqs = 1;
2727
2728 if (!irq_mask) {
2729 /*
2730 * omap 2/3 don't have framedone irq for TV, so we need to use
2731 * vsyncs for this.
2732 */
2733
2734 irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT);
2735 /*
2736 * We need to wait for both even and odd vsyncs. Note that this
2737 * is not totally reliable, as we could get a vsync interrupt
2738 * before we disable the output, which leads to timeout in the
2739 * wait_for_completion.
2740 */
2741 num_irqs = 2;
2742 }
2743
2744 r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
2745 irq_mask);
2746 if (r)
2747 DSSERR("failed to register %x isr\n", irq_mask);
2748
2749 dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, false);
2750
2751 /* if we couldn't register the irq, just sleep and exit */
2752 if (r) {
2753 msleep(100);
2754 return;
2755 }
2756
2757 for (i = 0; i < num_irqs; ++i) {
2758 if (!wait_for_completion_timeout(&framedone_compl,
2759 msecs_to_jiffies(100)))
2760 DSSERR("timeout waiting for digit out to stop\n");
2761 }
2762
2763 r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
2764 irq_mask);
2765 if (r)
2766 DSSERR("failed to unregister %x isr\n", irq_mask);
2767}
2768
2769void dispc_mgr_enable_sync(enum omap_channel channel)
2770{
2771 if (dss_mgr_is_lcd(channel))
2772 dispc_mgr_enable_lcd_out(channel);
2773 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
2774 dispc_mgr_enable_digit_out();
2775 else
2776 WARN_ON(1);
2777}
2778
2779void dispc_mgr_disable_sync(enum omap_channel channel)
2780{
2781 if (dss_mgr_is_lcd(channel))
2782 dispc_mgr_disable_lcd_out(channel);
2783 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
2784 dispc_mgr_disable_digit_out();
2785 else
2786 WARN_ON(1);
2787}
2788
2789void dispc_wb_enable(bool enable) 2614void dispc_wb_enable(bool enable)
2790{ 2615{
2791 dispc_ovl_enable(OMAP_DSS_WB, enable); 2616 dispc_ovl_enable(OMAP_DSS_WB, enable);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 8ae73670aa37..9faaa63d3089 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -426,8 +426,6 @@ bool dispc_mgr_go_busy(enum omap_channel channel);
426void dispc_mgr_go(enum omap_channel channel); 426void dispc_mgr_go(enum omap_channel channel);
427void dispc_mgr_enable(enum omap_channel channel, bool enable); 427void dispc_mgr_enable(enum omap_channel channel, bool enable);
428bool dispc_mgr_is_enabled(enum omap_channel channel); 428bool dispc_mgr_is_enabled(enum omap_channel channel);
429void dispc_mgr_enable_sync(enum omap_channel channel);
430void dispc_mgr_disable_sync(enum omap_channel channel);
431void dispc_mgr_set_lcd_config(enum omap_channel channel, 429void dispc_mgr_set_lcd_config(enum omap_channel channel,
432 const struct dss_lcd_mgr_config *config); 430 const struct dss_lcd_mgr_config *config);
433void dispc_mgr_set_timings(enum omap_channel channel, 431void dispc_mgr_set_timings(enum omap_channel channel,