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>
This commit is contained in:
Родитель
1550202d4a
Коммит
bb39813413
|
@ -1,7 +1,7 @@
|
|||
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
|
||||
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
|
||||
manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o \
|
||||
display-sysfs.o
|
||||
display-sysfs.o dispc-compat.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
|
||||
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
#include "dispc-compat.h"
|
||||
|
||||
/*
|
||||
* We have 4 levels of cache for the dispc settings. First two are in SW and
|
||||
|
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Texas Instruments
|
||||
* Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "APPLY"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "dss.h"
|
||||
#include "dss_features.h"
|
||||
#include "dispc-compat.h"
|
||||
|
||||
static void dispc_mgr_disable_isr(void *data, u32 mask)
|
||||
{
|
||||
struct completion *compl = data;
|
||||
complete(compl);
|
||||
}
|
||||
|
||||
static void dispc_mgr_enable_lcd_out(enum omap_channel channel)
|
||||
{
|
||||
dispc_mgr_enable(channel, true);
|
||||
}
|
||||
|
||||
static void dispc_mgr_disable_lcd_out(enum omap_channel channel)
|
||||
{
|
||||
DECLARE_COMPLETION_ONSTACK(framedone_compl);
|
||||
int r;
|
||||
u32 irq;
|
||||
|
||||
if (dispc_mgr_is_enabled(channel) == false)
|
||||
return;
|
||||
|
||||
/*
|
||||
* When we disable LCD output, we need to wait for FRAMEDONE to know
|
||||
* that DISPC has finished with the LCD output.
|
||||
*/
|
||||
|
||||
irq = dispc_mgr_get_framedone_irq(channel);
|
||||
|
||||
r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
|
||||
irq);
|
||||
if (r)
|
||||
DSSERR("failed to register FRAMEDONE isr\n");
|
||||
|
||||
dispc_mgr_enable(channel, false);
|
||||
|
||||
/* if we couldn't register for framedone, just sleep and exit */
|
||||
if (r) {
|
||||
msleep(100);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wait_for_completion_timeout(&framedone_compl,
|
||||
msecs_to_jiffies(100)))
|
||||
DSSERR("timeout waiting for FRAME DONE\n");
|
||||
|
||||
r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
|
||||
irq);
|
||||
if (r)
|
||||
DSSERR("failed to unregister FRAMEDONE isr\n");
|
||||
}
|
||||
|
||||
static void dispc_digit_out_enable_isr(void *data, u32 mask)
|
||||
{
|
||||
struct completion *compl = data;
|
||||
|
||||
/* ignore any sync lost interrupts */
|
||||
if (mask & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD))
|
||||
complete(compl);
|
||||
}
|
||||
|
||||
static void dispc_mgr_enable_digit_out(void)
|
||||
{
|
||||
DECLARE_COMPLETION_ONSTACK(vsync_compl);
|
||||
int r;
|
||||
u32 irq_mask;
|
||||
|
||||
if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == true)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Digit output produces some sync lost interrupts during the first
|
||||
* frame when enabling. Those need to be ignored, so we register for the
|
||||
* sync lost irq to prevent the error handler from triggering.
|
||||
*/
|
||||
|
||||
irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT) |
|
||||
dispc_mgr_get_sync_lost_irq(OMAP_DSS_CHANNEL_DIGIT);
|
||||
|
||||
r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl,
|
||||
irq_mask);
|
||||
if (r) {
|
||||
DSSERR("failed to register %x isr\n", irq_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, true);
|
||||
|
||||
/* wait for the first evsync */
|
||||
if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100)))
|
||||
DSSERR("timeout waiting for digit out to start\n");
|
||||
|
||||
r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl,
|
||||
irq_mask);
|
||||
if (r)
|
||||
DSSERR("failed to unregister %x isr\n", irq_mask);
|
||||
}
|
||||
|
||||
static void dispc_mgr_disable_digit_out(void)
|
||||
{
|
||||
DECLARE_COMPLETION_ONSTACK(framedone_compl);
|
||||
int r, i;
|
||||
u32 irq_mask;
|
||||
int num_irqs;
|
||||
|
||||
if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == false)
|
||||
return;
|
||||
|
||||
/*
|
||||
* When we disable the digit output, we need to wait for FRAMEDONE to
|
||||
* know that DISPC has finished with the output.
|
||||
*/
|
||||
|
||||
irq_mask = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_DIGIT);
|
||||
num_irqs = 1;
|
||||
|
||||
if (!irq_mask) {
|
||||
/*
|
||||
* omap 2/3 don't have framedone irq for TV, so we need to use
|
||||
* vsyncs for this.
|
||||
*/
|
||||
|
||||
irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT);
|
||||
/*
|
||||
* We need to wait for both even and odd vsyncs. Note that this
|
||||
* is not totally reliable, as we could get a vsync interrupt
|
||||
* before we disable the output, which leads to timeout in the
|
||||
* wait_for_completion.
|
||||
*/
|
||||
num_irqs = 2;
|
||||
}
|
||||
|
||||
r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
|
||||
irq_mask);
|
||||
if (r)
|
||||
DSSERR("failed to register %x isr\n", irq_mask);
|
||||
|
||||
dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, false);
|
||||
|
||||
/* if we couldn't register the irq, just sleep and exit */
|
||||
if (r) {
|
||||
msleep(100);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_irqs; ++i) {
|
||||
if (!wait_for_completion_timeout(&framedone_compl,
|
||||
msecs_to_jiffies(100)))
|
||||
DSSERR("timeout waiting for digit out to stop\n");
|
||||
}
|
||||
|
||||
r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
|
||||
irq_mask);
|
||||
if (r)
|
||||
DSSERR("failed to unregister %x isr\n", irq_mask);
|
||||
}
|
||||
|
||||
void dispc_mgr_enable_sync(enum omap_channel channel)
|
||||
{
|
||||
if (dss_mgr_is_lcd(channel))
|
||||
dispc_mgr_enable_lcd_out(channel);
|
||||
else if (channel == OMAP_DSS_CHANNEL_DIGIT)
|
||||
dispc_mgr_enable_digit_out();
|
||||
else
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
void dispc_mgr_disable_sync(enum omap_channel channel)
|
||||
{
|
||||
if (dss_mgr_is_lcd(channel))
|
||||
dispc_mgr_disable_lcd_out(channel);
|
||||
else if (channel == OMAP_DSS_CHANNEL_DIGIT)
|
||||
dispc_mgr_disable_digit_out();
|
||||
else
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Texas Instruments
|
||||
* Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __OMAP2_DSS_DISPC_COMPAT_H
|
||||
#define __OMAP2_DSS_DISPC_COMPAT_H
|
||||
|
||||
void dispc_mgr_enable_sync(enum omap_channel channel);
|
||||
void dispc_mgr_disable_sync(enum omap_channel channel);
|
||||
|
||||
#endif
|
|
@ -2599,12 +2599,6 @@ bool dispc_ovl_enabled(enum omap_plane plane)
|
|||
return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
|
||||
}
|
||||
|
||||
static void dispc_mgr_disable_isr(void *data, u32 mask)
|
||||
{
|
||||
struct completion *compl = data;
|
||||
complete(compl);
|
||||
}
|
||||
|
||||
void dispc_mgr_enable(enum omap_channel channel, bool enable)
|
||||
{
|
||||
mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable);
|
||||
|
@ -2617,175 +2611,6 @@ bool dispc_mgr_is_enabled(enum omap_channel channel)
|
|||
return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
|
||||
}
|
||||
|
||||
static void dispc_mgr_enable_lcd_out(enum omap_channel channel)
|
||||
{
|
||||
dispc_mgr_enable(channel, true);
|
||||
}
|
||||
|
||||
static void dispc_mgr_disable_lcd_out(enum omap_channel channel)
|
||||
{
|
||||
DECLARE_COMPLETION_ONSTACK(framedone_compl);
|
||||
int r;
|
||||
u32 irq;
|
||||
|
||||
if (dispc_mgr_is_enabled(channel) == false)
|
||||
return;
|
||||
|
||||
/*
|
||||
* When we disable LCD output, we need to wait for FRAMEDONE to know
|
||||
* that DISPC has finished with the LCD output.
|
||||
*/
|
||||
|
||||
irq = dispc_mgr_get_framedone_irq(channel);
|
||||
|
||||
r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
|
||||
irq);
|
||||
if (r)
|
||||
DSSERR("failed to register FRAMEDONE isr\n");
|
||||
|
||||
dispc_mgr_enable(channel, false);
|
||||
|
||||
/* if we couldn't register for framedone, just sleep and exit */
|
||||
if (r) {
|
||||
msleep(100);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wait_for_completion_timeout(&framedone_compl,
|
||||
msecs_to_jiffies(100)))
|
||||
DSSERR("timeout waiting for FRAME DONE\n");
|
||||
|
||||
r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
|
||||
irq);
|
||||
if (r)
|
||||
DSSERR("failed to unregister FRAMEDONE isr\n");
|
||||
}
|
||||
|
||||
static void dispc_digit_out_enable_isr(void *data, u32 mask)
|
||||
{
|
||||
struct completion *compl = data;
|
||||
|
||||
/* ignore any sync lost interrupts */
|
||||
if (mask & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD))
|
||||
complete(compl);
|
||||
}
|
||||
|
||||
static void dispc_mgr_enable_digit_out(void)
|
||||
{
|
||||
DECLARE_COMPLETION_ONSTACK(vsync_compl);
|
||||
int r;
|
||||
u32 irq_mask;
|
||||
|
||||
if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == true)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Digit output produces some sync lost interrupts during the first
|
||||
* frame when enabling. Those need to be ignored, so we register for the
|
||||
* sync lost irq to prevent the error handler from triggering.
|
||||
*/
|
||||
|
||||
irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT) |
|
||||
dispc_mgr_get_sync_lost_irq(OMAP_DSS_CHANNEL_DIGIT);
|
||||
|
||||
r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl,
|
||||
irq_mask);
|
||||
if (r) {
|
||||
DSSERR("failed to register %x isr\n", irq_mask);
|
||||
return;
|
||||
}
|
||||
|
||||
dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, true);
|
||||
|
||||
/* wait for the first evsync */
|
||||
if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100)))
|
||||
DSSERR("timeout waiting for digit out to start\n");
|
||||
|
||||
r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl,
|
||||
irq_mask);
|
||||
if (r)
|
||||
DSSERR("failed to unregister %x isr\n", irq_mask);
|
||||
}
|
||||
|
||||
static void dispc_mgr_disable_digit_out(void)
|
||||
{
|
||||
DECLARE_COMPLETION_ONSTACK(framedone_compl);
|
||||
int r, i;
|
||||
u32 irq_mask;
|
||||
int num_irqs;
|
||||
|
||||
if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT) == false)
|
||||
return;
|
||||
|
||||
/*
|
||||
* When we disable the digit output, we need to wait for FRAMEDONE to
|
||||
* know that DISPC has finished with the output.
|
||||
*/
|
||||
|
||||
irq_mask = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_DIGIT);
|
||||
num_irqs = 1;
|
||||
|
||||
if (!irq_mask) {
|
||||
/*
|
||||
* omap 2/3 don't have framedone irq for TV, so we need to use
|
||||
* vsyncs for this.
|
||||
*/
|
||||
|
||||
irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT);
|
||||
/*
|
||||
* We need to wait for both even and odd vsyncs. Note that this
|
||||
* is not totally reliable, as we could get a vsync interrupt
|
||||
* before we disable the output, which leads to timeout in the
|
||||
* wait_for_completion.
|
||||
*/
|
||||
num_irqs = 2;
|
||||
}
|
||||
|
||||
r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
|
||||
irq_mask);
|
||||
if (r)
|
||||
DSSERR("failed to register %x isr\n", irq_mask);
|
||||
|
||||
dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, false);
|
||||
|
||||
/* if we couldn't register the irq, just sleep and exit */
|
||||
if (r) {
|
||||
msleep(100);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_irqs; ++i) {
|
||||
if (!wait_for_completion_timeout(&framedone_compl,
|
||||
msecs_to_jiffies(100)))
|
||||
DSSERR("timeout waiting for digit out to stop\n");
|
||||
}
|
||||
|
||||
r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
|
||||
irq_mask);
|
||||
if (r)
|
||||
DSSERR("failed to unregister %x isr\n", irq_mask);
|
||||
}
|
||||
|
||||
void dispc_mgr_enable_sync(enum omap_channel channel)
|
||||
{
|
||||
if (dss_mgr_is_lcd(channel))
|
||||
dispc_mgr_enable_lcd_out(channel);
|
||||
else if (channel == OMAP_DSS_CHANNEL_DIGIT)
|
||||
dispc_mgr_enable_digit_out();
|
||||
else
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
void dispc_mgr_disable_sync(enum omap_channel channel)
|
||||
{
|
||||
if (dss_mgr_is_lcd(channel))
|
||||
dispc_mgr_disable_lcd_out(channel);
|
||||
else if (channel == OMAP_DSS_CHANNEL_DIGIT)
|
||||
dispc_mgr_disable_digit_out();
|
||||
else
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
void dispc_wb_enable(bool enable)
|
||||
{
|
||||
dispc_ovl_enable(OMAP_DSS_WB, enable);
|
||||
|
|
|
@ -426,8 +426,6 @@ bool dispc_mgr_go_busy(enum omap_channel channel);
|
|||
void dispc_mgr_go(enum omap_channel channel);
|
||||
void dispc_mgr_enable(enum omap_channel channel, bool enable);
|
||||
bool dispc_mgr_is_enabled(enum omap_channel channel);
|
||||
void dispc_mgr_enable_sync(enum omap_channel channel);
|
||||
void dispc_mgr_disable_sync(enum omap_channel channel);
|
||||
void dispc_mgr_set_lcd_config(enum omap_channel channel,
|
||||
const struct dss_lcd_mgr_config *config);
|
||||
void dispc_mgr_set_timings(enum omap_channel channel,
|
||||
|
|
Загрузка…
Ссылка в новой задаче