Merge branch 'for-linus' of git://gitorious.org/linux-omap-dss2/linux
* 'for-linus' of git://gitorious.org/linux-omap-dss2/linux: OMAP: DSS2: OMAPFB: fix crash when panel driver was not loaded OMAP: DSS2: Reject scaling settings when they cannot be supported OMAP: DSS2: Make check-delay-loops consistent OMAP: DSS2: OMAPFB: fix omapfb_free_fbmem() video/omap: add __init/__exit macros to drivers/video/omap/lcd_htcherald.c OMAP: DSS2: Fix compile warning MAINTAINERS: Combine DSS2 and OMAPFB2 into one entry MAINTAINERS: change omapfb maintainer OMAP: OMAPFB: add dummy release function for omapdss OMAP: OMAPFB: fix clk_get for RFBI OMAP: DSS2: RFBI: convert to new kfifo API OMAP: DSS2: Fix crash when panel doesn't define enable_te() OMAP: DSS2: Collect interrupt statistics OMAP: DSS2: DSI: print debug DCS cmd in hex OMAP: DSS2: DSI: fix VC channels in send_short and send_null
This commit is contained in:
commit
90aeb7c01c
17
MAINTAINERS
17
MAINTAINERS
|
@ -3940,29 +3940,20 @@ S: Maintained
|
||||||
F: sound/soc/omap/
|
F: sound/soc/omap/
|
||||||
|
|
||||||
OMAP FRAMEBUFFER SUPPORT
|
OMAP FRAMEBUFFER SUPPORT
|
||||||
M: Imre Deak <imre.deak@nokia.com>
|
M: Tomi Valkeinen <tomi.valkeinen@nokia.com>
|
||||||
L: linux-fbdev@vger.kernel.org
|
L: linux-fbdev@vger.kernel.org
|
||||||
L: linux-omap@vger.kernel.org
|
L: linux-omap@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/video/omap/
|
F: drivers/video/omap/
|
||||||
|
|
||||||
OMAP DISPLAY SUBSYSTEM SUPPORT (DSS2)
|
OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2)
|
||||||
M: Tomi Valkeinen <tomi.valkeinen@nokia.com>
|
M: Tomi Valkeinen <tomi.valkeinen@nokia.com>
|
||||||
L: linux-omap@vger.kernel.org
|
L: linux-omap@vger.kernel.org
|
||||||
L: linux-fbdev@vger.kernel.org (moderated for non-subscribers)
|
L: linux-fbdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/video/omap2/dss/
|
F: drivers/video/omap2/
|
||||||
F: drivers/video/omap2/vrfb.c
|
|
||||||
F: drivers/video/omap2/vram.c
|
|
||||||
F: Documentation/arm/OMAP/DSS
|
F: Documentation/arm/OMAP/DSS
|
||||||
|
|
||||||
OMAP FRAMEBUFFER SUPPORT (FOR DSS2)
|
|
||||||
M: Tomi Valkeinen <tomi.valkeinen@nokia.com>
|
|
||||||
L: linux-omap@vger.kernel.org
|
|
||||||
L: linux-fbdev@vger.kernel.org (moderated for non-subscribers)
|
|
||||||
S: Maintained
|
|
||||||
F: drivers/video/omap2/omapfb/
|
|
||||||
|
|
||||||
OMAP MMC SUPPORT
|
OMAP MMC SUPPORT
|
||||||
M: Jarkko Lavinen <jarkko.lavinen@nokia.com>
|
M: Jarkko Lavinen <jarkko.lavinen@nokia.com>
|
||||||
L: linux-omap@vger.kernel.org
|
L: linux-omap@vger.kernel.org
|
||||||
|
|
|
@ -189,11 +189,6 @@ static struct {
|
||||||
struct omapfb_color_key color_key;
|
struct omapfb_color_key color_key;
|
||||||
} dispc;
|
} dispc;
|
||||||
|
|
||||||
static struct platform_device omapdss_device = {
|
|
||||||
.name = "omapdss",
|
|
||||||
.id = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void enable_lcd_clocks(int enable);
|
static void enable_lcd_clocks(int enable);
|
||||||
|
|
||||||
static void inline dispc_write_reg(int idx, u32 val)
|
static void inline dispc_write_reg(int idx, u32 val)
|
||||||
|
@ -920,20 +915,20 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev)
|
||||||
|
|
||||||
static int get_dss_clocks(void)
|
static int get_dss_clocks(void)
|
||||||
{
|
{
|
||||||
dispc.dss_ick = clk_get(&omapdss_device.dev, "ick");
|
dispc.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick");
|
||||||
if (IS_ERR(dispc.dss_ick)) {
|
if (IS_ERR(dispc.dss_ick)) {
|
||||||
dev_err(dispc.fbdev->dev, "can't get ick\n");
|
dev_err(dispc.fbdev->dev, "can't get ick\n");
|
||||||
return PTR_ERR(dispc.dss_ick);
|
return PTR_ERR(dispc.dss_ick);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispc.dss1_fck = clk_get(&omapdss_device.dev, "dss1_fck");
|
dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck");
|
||||||
if (IS_ERR(dispc.dss1_fck)) {
|
if (IS_ERR(dispc.dss1_fck)) {
|
||||||
dev_err(dispc.fbdev->dev, "can't get dss1_fck\n");
|
dev_err(dispc.fbdev->dev, "can't get dss1_fck\n");
|
||||||
clk_put(dispc.dss_ick);
|
clk_put(dispc.dss_ick);
|
||||||
return PTR_ERR(dispc.dss1_fck);
|
return PTR_ERR(dispc.dss1_fck);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispc.dss_54m_fck = clk_get(&omapdss_device.dev, "tv_fck");
|
dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_fck");
|
||||||
if (IS_ERR(dispc.dss_54m_fck)) {
|
if (IS_ERR(dispc.dss_54m_fck)) {
|
||||||
dev_err(dispc.fbdev->dev, "can't get tv_fck\n");
|
dev_err(dispc.fbdev->dev, "can't get tv_fck\n");
|
||||||
clk_put(dispc.dss_ick);
|
clk_put(dispc.dss_ick);
|
||||||
|
@ -1385,12 +1380,6 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
|
||||||
int skip_init = 0;
|
int skip_init = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
r = platform_device_register(&omapdss_device);
|
|
||||||
if (r) {
|
|
||||||
dev_err(fbdev->dev, "can't register omapdss device\n");
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&dispc, 0, sizeof(dispc));
|
memset(&dispc, 0, sizeof(dispc));
|
||||||
|
|
||||||
dispc.base = ioremap(DISPC_BASE, SZ_1K);
|
dispc.base = ioremap(DISPC_BASE, SZ_1K);
|
||||||
|
@ -1534,7 +1523,6 @@ static void omap_dispc_cleanup(void)
|
||||||
free_irq(INT_24XX_DSS_IRQ, dispc.fbdev);
|
free_irq(INT_24XX_DSS_IRQ, dispc.fbdev);
|
||||||
put_dss_clocks();
|
put_dss_clocks();
|
||||||
iounmap(dispc.base);
|
iounmap(dispc.base);
|
||||||
platform_device_unregister(&omapdss_device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct lcd_ctrl omap2_int_ctrl = {
|
const struct lcd_ctrl omap2_int_ctrl = {
|
||||||
|
|
|
@ -115,12 +115,12 @@ struct platform_driver htcherald_panel_driver = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int htcherald_panel_drv_init(void)
|
static int __init htcherald_panel_drv_init(void)
|
||||||
{
|
{
|
||||||
return platform_driver_register(&htcherald_panel_driver);
|
return platform_driver_register(&htcherald_panel_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void htcherald_panel_drv_cleanup(void)
|
static void __exit htcherald_panel_drv_cleanup(void)
|
||||||
{
|
{
|
||||||
platform_driver_unregister(&htcherald_panel_driver);
|
platform_driver_unregister(&htcherald_panel_driver);
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,6 +203,8 @@ struct omapfb_device {
|
||||||
|
|
||||||
struct omapfb_mem_desc mem_desc;
|
struct omapfb_mem_desc mem_desc;
|
||||||
struct fb_info *fb_info[OMAPFB_PLANE_NUM];
|
struct fb_info *fb_info[OMAPFB_PLANE_NUM];
|
||||||
|
|
||||||
|
struct platform_device *dssdev; /* dummy dev for clocks */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_OMAP1
|
#ifdef CONFIG_ARCH_OMAP1
|
||||||
|
|
|
@ -83,6 +83,19 @@ static struct caps_table_struct color_caps[] = {
|
||||||
{ 1 << OMAPFB_COLOR_YUY422, "YUY422", },
|
{ 1 << OMAPFB_COLOR_YUY422, "YUY422", },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void omapdss_release(struct device *dev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dummy device for clocks */
|
||||||
|
static struct platform_device omapdss_device = {
|
||||||
|
.name = "omapdss",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.release = omapdss_release,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ---------------------------------------------------------------------------
|
* ---------------------------------------------------------------------------
|
||||||
* LCD panel
|
* LCD panel
|
||||||
|
@ -1700,6 +1713,7 @@ static int omapfb_do_probe(struct platform_device *pdev,
|
||||||
|
|
||||||
fbdev->dev = &pdev->dev;
|
fbdev->dev = &pdev->dev;
|
||||||
fbdev->panel = panel;
|
fbdev->panel = panel;
|
||||||
|
fbdev->dssdev = &omapdss_device;
|
||||||
platform_set_drvdata(pdev, fbdev);
|
platform_set_drvdata(pdev, fbdev);
|
||||||
|
|
||||||
mutex_init(&fbdev->rqueue_mutex);
|
mutex_init(&fbdev->rqueue_mutex);
|
||||||
|
@ -1814,8 +1828,16 @@ cleanup:
|
||||||
|
|
||||||
static int omapfb_probe(struct platform_device *pdev)
|
static int omapfb_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
BUG_ON(fbdev_pdev != NULL);
|
BUG_ON(fbdev_pdev != NULL);
|
||||||
|
|
||||||
|
r = platform_device_register(&omapdss_device);
|
||||||
|
if (r) {
|
||||||
|
dev_err(&pdev->dev, "can't register omapdss device\n");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/* Delay actual initialization until the LCD is registered */
|
/* Delay actual initialization until the LCD is registered */
|
||||||
fbdev_pdev = pdev;
|
fbdev_pdev = pdev;
|
||||||
if (fbdev_panel != NULL)
|
if (fbdev_panel != NULL)
|
||||||
|
@ -1843,6 +1865,9 @@ static int omapfb_remove(struct platform_device *pdev)
|
||||||
fbdev->state = OMAPFB_DISABLED;
|
fbdev->state = OMAPFB_DISABLED;
|
||||||
omapfb_free_resources(fbdev, saved_state);
|
omapfb_free_resources(fbdev, saved_state);
|
||||||
|
|
||||||
|
platform_device_unregister(&omapdss_device);
|
||||||
|
fbdev->dssdev = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,13 +83,13 @@ static inline u32 rfbi_read_reg(int idx)
|
||||||
|
|
||||||
static int rfbi_get_clocks(void)
|
static int rfbi_get_clocks(void)
|
||||||
{
|
{
|
||||||
rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "ick");
|
rfbi.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick");
|
||||||
if (IS_ERR(rfbi.dss_ick)) {
|
if (IS_ERR(rfbi.dss_ick)) {
|
||||||
dev_err(rfbi.fbdev->dev, "can't get ick\n");
|
dev_err(rfbi.fbdev->dev, "can't get ick\n");
|
||||||
return PTR_ERR(rfbi.dss_ick);
|
return PTR_ERR(rfbi.dss_ick);
|
||||||
}
|
}
|
||||||
|
|
||||||
rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck");
|
rfbi.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck");
|
||||||
if (IS_ERR(rfbi.dss1_fck)) {
|
if (IS_ERR(rfbi.dss1_fck)) {
|
||||||
dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
|
dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
|
||||||
clk_put(rfbi.dss_ick);
|
clk_put(rfbi.dss_ick);
|
||||||
|
|
|
@ -25,6 +25,13 @@ config OMAP2_DSS_DEBUG_SUPPORT
|
||||||
This enables debug messages. You need to enable printing
|
This enables debug messages. You need to enable printing
|
||||||
with 'debug' module parameter.
|
with 'debug' module parameter.
|
||||||
|
|
||||||
|
config OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
bool "Collect DSS IRQ statistics"
|
||||||
|
depends on OMAP2_DSS_DEBUG_SUPPORT
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Collect DSS IRQ statistics, printable via debugfs
|
||||||
|
|
||||||
config OMAP2_DSS_RFBI
|
config OMAP2_DSS_RFBI
|
||||||
bool "RFBI support"
|
bool "RFBI support"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -124,6 +124,7 @@ static void restore_all_ctx(void)
|
||||||
dss_clk_disable_all_no_ctx();
|
dss_clk_disable_all_no_ctx();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
|
||||||
/* CLOCKS */
|
/* CLOCKS */
|
||||||
static void core_dump_clocks(struct seq_file *s)
|
static void core_dump_clocks(struct seq_file *s)
|
||||||
{
|
{
|
||||||
|
@ -149,6 +150,7 @@ static void core_dump_clocks(struct seq_file *s)
|
||||||
clocks[i]->usecount);
|
clocks[i]->usecount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
|
||||||
|
|
||||||
static int dss_get_clock(struct clk **clock, const char *clk_name)
|
static int dss_get_clock(struct clk **clock, const char *clk_name)
|
||||||
{
|
{
|
||||||
|
@ -395,6 +397,14 @@ static int dss_initialize_debugfs(void)
|
||||||
debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
|
debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
|
||||||
&dss_debug_dump_clocks, &dss_debug_fops);
|
&dss_debug_dump_clocks, &dss_debug_fops);
|
||||||
|
|
||||||
|
debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir,
|
||||||
|
&dispc_dump_irqs, &dss_debug_fops);
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_DSI
|
||||||
|
debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir,
|
||||||
|
&dsi_dump_irqs, &dss_debug_fops);
|
||||||
|
#endif
|
||||||
|
|
||||||
debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir,
|
debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir,
|
||||||
&dss_dump_regs, &dss_debug_fops);
|
&dss_dump_regs, &dss_debug_fops);
|
||||||
debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir,
|
debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir,
|
||||||
|
|
|
@ -148,6 +148,12 @@ static const struct dispc_reg dispc_reg_att[] = { DISPC_GFX_ATTRIBUTES,
|
||||||
DISPC_VID_ATTRIBUTES(0),
|
DISPC_VID_ATTRIBUTES(0),
|
||||||
DISPC_VID_ATTRIBUTES(1) };
|
DISPC_VID_ATTRIBUTES(1) };
|
||||||
|
|
||||||
|
struct dispc_irq_stats {
|
||||||
|
unsigned long last_reset;
|
||||||
|
unsigned irq_count;
|
||||||
|
unsigned irqs[32];
|
||||||
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
|
|
||||||
|
@ -160,6 +166,11 @@ static struct {
|
||||||
struct work_struct error_work;
|
struct work_struct error_work;
|
||||||
|
|
||||||
u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
|
u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
spinlock_t irq_stats_lock;
|
||||||
|
struct dispc_irq_stats irq_stats;
|
||||||
|
#endif
|
||||||
} dispc;
|
} dispc;
|
||||||
|
|
||||||
static void _omap_dispc_set_irqs(void);
|
static void _omap_dispc_set_irqs(void);
|
||||||
|
@ -1443,7 +1454,10 @@ static unsigned long calc_fclk_five_taps(u16 width, u16 height,
|
||||||
do_div(tmp, 2 * out_height * ppl);
|
do_div(tmp, 2 * out_height * ppl);
|
||||||
fclk = tmp;
|
fclk = tmp;
|
||||||
|
|
||||||
if (height > 2 * out_height && ppl != out_width) {
|
if (height > 2 * out_height) {
|
||||||
|
if (ppl == out_width)
|
||||||
|
return 0;
|
||||||
|
|
||||||
tmp = pclk * (height - 2 * out_height) * out_width;
|
tmp = pclk * (height - 2 * out_height) * out_width;
|
||||||
do_div(tmp, 2 * out_height * (ppl - out_width));
|
do_div(tmp, 2 * out_height * (ppl - out_width));
|
||||||
fclk = max(fclk, (u32) tmp);
|
fclk = max(fclk, (u32) tmp);
|
||||||
|
@ -1623,7 +1637,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
|
||||||
DSSDBG("required fclk rate = %lu Hz\n", fclk);
|
DSSDBG("required fclk rate = %lu Hz\n", fclk);
|
||||||
DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
|
DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
|
||||||
|
|
||||||
if (fclk > dispc_fclk_rate()) {
|
if (!fclk || fclk > dispc_fclk_rate()) {
|
||||||
DSSERR("failed to set up scaling, "
|
DSSERR("failed to set up scaling, "
|
||||||
"required fclk rate = %lu Hz, "
|
"required fclk rate = %lu Hz, "
|
||||||
"current fclk rate = %lu Hz\n",
|
"current fclk rate = %lu Hz\n",
|
||||||
|
@ -2247,6 +2261,50 @@ void dispc_dump_clocks(struct seq_file *s)
|
||||||
enable_clocks(0);
|
enable_clocks(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
void dispc_dump_irqs(struct seq_file *s)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
struct dispc_irq_stats stats;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dispc.irq_stats_lock, flags);
|
||||||
|
|
||||||
|
stats = dispc.irq_stats;
|
||||||
|
memset(&dispc.irq_stats, 0, sizeof(dispc.irq_stats));
|
||||||
|
dispc.irq_stats.last_reset = jiffies;
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dispc.irq_stats_lock, flags);
|
||||||
|
|
||||||
|
seq_printf(s, "period %u ms\n",
|
||||||
|
jiffies_to_msecs(jiffies - stats.last_reset));
|
||||||
|
|
||||||
|
seq_printf(s, "irqs %d\n", stats.irq_count);
|
||||||
|
#define PIS(x) \
|
||||||
|
seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]);
|
||||||
|
|
||||||
|
PIS(FRAMEDONE);
|
||||||
|
PIS(VSYNC);
|
||||||
|
PIS(EVSYNC_EVEN);
|
||||||
|
PIS(EVSYNC_ODD);
|
||||||
|
PIS(ACBIAS_COUNT_STAT);
|
||||||
|
PIS(PROG_LINE_NUM);
|
||||||
|
PIS(GFX_FIFO_UNDERFLOW);
|
||||||
|
PIS(GFX_END_WIN);
|
||||||
|
PIS(PAL_GAMMA_MASK);
|
||||||
|
PIS(OCP_ERR);
|
||||||
|
PIS(VID1_FIFO_UNDERFLOW);
|
||||||
|
PIS(VID1_END_WIN);
|
||||||
|
PIS(VID2_FIFO_UNDERFLOW);
|
||||||
|
PIS(VID2_END_WIN);
|
||||||
|
PIS(SYNC_LOST);
|
||||||
|
PIS(SYNC_LOST_DIGIT);
|
||||||
|
PIS(WAKEUP);
|
||||||
|
#undef PIS
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void dispc_dump_irqs(struct seq_file *s) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
void dispc_dump_regs(struct seq_file *s)
|
void dispc_dump_regs(struct seq_file *s)
|
||||||
{
|
{
|
||||||
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
|
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
|
||||||
|
@ -2665,6 +2723,13 @@ void dispc_irq_handler(void)
|
||||||
|
|
||||||
irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
|
irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
spin_lock(&dispc.irq_stats_lock);
|
||||||
|
dispc.irq_stats.irq_count++;
|
||||||
|
dss_collect_irq_stats(irqstatus, dispc.irq_stats.irqs);
|
||||||
|
spin_unlock(&dispc.irq_stats_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (dss_debug)
|
if (dss_debug)
|
||||||
print_irq_status(irqstatus);
|
print_irq_status(irqstatus);
|
||||||
|
@ -3012,6 +3077,11 @@ int dispc_init(void)
|
||||||
|
|
||||||
spin_lock_init(&dispc.irq_lock);
|
spin_lock_init(&dispc.irq_lock);
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
spin_lock_init(&dispc.irq_stats_lock);
|
||||||
|
dispc.irq_stats.last_reset = jiffies;
|
||||||
|
#endif
|
||||||
|
|
||||||
INIT_WORK(&dispc.error_work, dispc_error_worker);
|
INIT_WORK(&dispc.error_work, dispc_error_worker);
|
||||||
|
|
||||||
dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);
|
dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);
|
||||||
|
|
|
@ -204,6 +204,14 @@ struct dsi_update_region {
|
||||||
struct omap_dss_device *device;
|
struct omap_dss_device *device;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dsi_irq_stats {
|
||||||
|
unsigned long last_reset;
|
||||||
|
unsigned irq_count;
|
||||||
|
unsigned dsi_irqs[32];
|
||||||
|
unsigned vc_irqs[4][32];
|
||||||
|
unsigned cio_irqs[32];
|
||||||
|
};
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
|
@ -258,6 +266,11 @@ static struct
|
||||||
#endif
|
#endif
|
||||||
int debug_read;
|
int debug_read;
|
||||||
int debug_write;
|
int debug_write;
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
spinlock_t irq_stats_lock;
|
||||||
|
struct dsi_irq_stats irq_stats;
|
||||||
|
#endif
|
||||||
} dsi;
|
} dsi;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -528,6 +541,12 @@ void dsi_irq_handler(void)
|
||||||
|
|
||||||
irqstatus = dsi_read_reg(DSI_IRQSTATUS);
|
irqstatus = dsi_read_reg(DSI_IRQSTATUS);
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
spin_lock(&dsi.irq_stats_lock);
|
||||||
|
dsi.irq_stats.irq_count++;
|
||||||
|
dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (irqstatus & DSI_IRQ_ERROR_MASK) {
|
if (irqstatus & DSI_IRQ_ERROR_MASK) {
|
||||||
DSSERR("DSI error, irqstatus %x\n", irqstatus);
|
DSSERR("DSI error, irqstatus %x\n", irqstatus);
|
||||||
print_irq_status(irqstatus);
|
print_irq_status(irqstatus);
|
||||||
|
@ -549,6 +568,10 @@ void dsi_irq_handler(void)
|
||||||
|
|
||||||
vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i));
|
vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i));
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (vcstatus & DSI_VC_IRQ_BTA)
|
if (vcstatus & DSI_VC_IRQ_BTA)
|
||||||
complete(&dsi.bta_completion);
|
complete(&dsi.bta_completion);
|
||||||
|
|
||||||
|
@ -568,6 +591,10 @@ void dsi_irq_handler(void)
|
||||||
if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) {
|
if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) {
|
||||||
ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
|
ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs);
|
||||||
|
#endif
|
||||||
|
|
||||||
dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
|
dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
|
||||||
/* flush posted write */
|
/* flush posted write */
|
||||||
dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
|
dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
|
||||||
|
@ -579,6 +606,10 @@ void dsi_irq_handler(void)
|
||||||
dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
|
dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
|
||||||
/* flush posted write */
|
/* flush posted write */
|
||||||
dsi_read_reg(DSI_IRQSTATUS);
|
dsi_read_reg(DSI_IRQSTATUS);
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
spin_unlock(&dsi.irq_stats_lock);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -797,12 +828,12 @@ static int dsi_pll_power(enum dsi_pll_power_state state)
|
||||||
|
|
||||||
/* PLL_PWR_STATUS */
|
/* PLL_PWR_STATUS */
|
||||||
while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) {
|
while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) {
|
||||||
udelay(1);
|
if (++t > 1000) {
|
||||||
if (t++ > 1000) {
|
|
||||||
DSSERR("Failed to set DSI PLL power mode to %d\n",
|
DSSERR("Failed to set DSI PLL power mode to %d\n",
|
||||||
state);
|
state);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
udelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1226,6 +1257,95 @@ void dsi_dump_clocks(struct seq_file *s)
|
||||||
enable_clocks(0);
|
enable_clocks(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
void dsi_dump_irqs(struct seq_file *s)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
struct dsi_irq_stats stats;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dsi.irq_stats_lock, flags);
|
||||||
|
|
||||||
|
stats = dsi.irq_stats;
|
||||||
|
memset(&dsi.irq_stats, 0, sizeof(dsi.irq_stats));
|
||||||
|
dsi.irq_stats.last_reset = jiffies;
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dsi.irq_stats_lock, flags);
|
||||||
|
|
||||||
|
seq_printf(s, "period %u ms\n",
|
||||||
|
jiffies_to_msecs(jiffies - stats.last_reset));
|
||||||
|
|
||||||
|
seq_printf(s, "irqs %d\n", stats.irq_count);
|
||||||
|
#define PIS(x) \
|
||||||
|
seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]);
|
||||||
|
|
||||||
|
seq_printf(s, "-- DSI interrupts --\n");
|
||||||
|
PIS(VC0);
|
||||||
|
PIS(VC1);
|
||||||
|
PIS(VC2);
|
||||||
|
PIS(VC3);
|
||||||
|
PIS(WAKEUP);
|
||||||
|
PIS(RESYNC);
|
||||||
|
PIS(PLL_LOCK);
|
||||||
|
PIS(PLL_UNLOCK);
|
||||||
|
PIS(PLL_RECALL);
|
||||||
|
PIS(COMPLEXIO_ERR);
|
||||||
|
PIS(HS_TX_TIMEOUT);
|
||||||
|
PIS(LP_RX_TIMEOUT);
|
||||||
|
PIS(TE_TRIGGER);
|
||||||
|
PIS(ACK_TRIGGER);
|
||||||
|
PIS(SYNC_LOST);
|
||||||
|
PIS(LDO_POWER_GOOD);
|
||||||
|
PIS(TA_TIMEOUT);
|
||||||
|
#undef PIS
|
||||||
|
|
||||||
|
#define PIS(x) \
|
||||||
|
seq_printf(s, "%-20s %10d %10d %10d %10d\n", #x, \
|
||||||
|
stats.vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \
|
||||||
|
stats.vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \
|
||||||
|
stats.vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \
|
||||||
|
stats.vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]);
|
||||||
|
|
||||||
|
seq_printf(s, "-- VC interrupts --\n");
|
||||||
|
PIS(CS);
|
||||||
|
PIS(ECC_CORR);
|
||||||
|
PIS(PACKET_SENT);
|
||||||
|
PIS(FIFO_TX_OVF);
|
||||||
|
PIS(FIFO_RX_OVF);
|
||||||
|
PIS(BTA);
|
||||||
|
PIS(ECC_NO_CORR);
|
||||||
|
PIS(FIFO_TX_UDF);
|
||||||
|
PIS(PP_BUSY_CHANGE);
|
||||||
|
#undef PIS
|
||||||
|
|
||||||
|
#define PIS(x) \
|
||||||
|
seq_printf(s, "%-20s %10d\n", #x, \
|
||||||
|
stats.cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]);
|
||||||
|
|
||||||
|
seq_printf(s, "-- CIO interrupts --\n");
|
||||||
|
PIS(ERRSYNCESC1);
|
||||||
|
PIS(ERRSYNCESC2);
|
||||||
|
PIS(ERRSYNCESC3);
|
||||||
|
PIS(ERRESC1);
|
||||||
|
PIS(ERRESC2);
|
||||||
|
PIS(ERRESC3);
|
||||||
|
PIS(ERRCONTROL1);
|
||||||
|
PIS(ERRCONTROL2);
|
||||||
|
PIS(ERRCONTROL3);
|
||||||
|
PIS(STATEULPS1);
|
||||||
|
PIS(STATEULPS2);
|
||||||
|
PIS(STATEULPS3);
|
||||||
|
PIS(ERRCONTENTIONLP0_1);
|
||||||
|
PIS(ERRCONTENTIONLP1_1);
|
||||||
|
PIS(ERRCONTENTIONLP0_2);
|
||||||
|
PIS(ERRCONTENTIONLP1_2);
|
||||||
|
PIS(ERRCONTENTIONLP0_3);
|
||||||
|
PIS(ERRCONTENTIONLP1_3);
|
||||||
|
PIS(ULPSACTIVENOT_ALL0);
|
||||||
|
PIS(ULPSACTIVENOT_ALL1);
|
||||||
|
#undef PIS
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void dsi_dump_regs(struct seq_file *s)
|
void dsi_dump_regs(struct seq_file *s)
|
||||||
{
|
{
|
||||||
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r))
|
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r))
|
||||||
|
@ -1321,12 +1441,12 @@ static int dsi_complexio_power(enum dsi_complexio_power_state state)
|
||||||
|
|
||||||
/* PWR_STATUS */
|
/* PWR_STATUS */
|
||||||
while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) {
|
while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) {
|
||||||
udelay(1);
|
if (++t > 1000) {
|
||||||
if (t++ > 1000) {
|
|
||||||
DSSERR("failed to set complexio power state to "
|
DSSERR("failed to set complexio power state to "
|
||||||
"%d\n", state);
|
"%d\n", state);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
udelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1526,10 +1646,10 @@ static void dsi_complexio_uninit(void)
|
||||||
|
|
||||||
static int _dsi_wait_reset(void)
|
static int _dsi_wait_reset(void)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int t = 0;
|
||||||
|
|
||||||
while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) {
|
while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) {
|
||||||
if (i++ > 5) {
|
if (++t > 5) {
|
||||||
DSSERR("soft reset failed\n");
|
DSSERR("soft reset failed\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
@ -1999,7 +2119,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_id = data_type | channel << 6;
|
data_id = data_type | dsi.vc[channel].dest_per << 6;
|
||||||
|
|
||||||
r = (data_id << 0) | (data << 8) | (ecc << 24);
|
r = (data_id << 0) | (data << 8) | (ecc << 24);
|
||||||
|
|
||||||
|
@ -2011,7 +2131,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
|
||||||
int dsi_vc_send_null(int channel)
|
int dsi_vc_send_null(int channel)
|
||||||
{
|
{
|
||||||
u8 nullpkg[] = {0, 0, 0, 0};
|
u8 nullpkg[] = {0, 0, 0, 0};
|
||||||
return dsi_vc_send_long(0, DSI_DT_NULL_PACKET, nullpkg, 4, 0);
|
return dsi_vc_send_long(channel, DSI_DT_NULL_PACKET, nullpkg, 4, 0);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dsi_vc_send_null);
|
EXPORT_SYMBOL(dsi_vc_send_null);
|
||||||
|
|
||||||
|
@ -2058,7 +2178,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (dsi.debug_read)
|
if (dsi.debug_read)
|
||||||
DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %u)\n", channel, dcs_cmd);
|
DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd);
|
||||||
|
|
||||||
r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0);
|
r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0);
|
||||||
if (r)
|
if (r)
|
||||||
|
@ -2586,7 +2706,6 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
|
||||||
/* using fifo not empty */
|
/* using fifo not empty */
|
||||||
/* TX_FIFO_NOT_EMPTY */
|
/* TX_FIFO_NOT_EMPTY */
|
||||||
while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) {
|
while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) {
|
||||||
udelay(1);
|
|
||||||
fifo_stalls++;
|
fifo_stalls++;
|
||||||
if (fifo_stalls > 0xfffff) {
|
if (fifo_stalls > 0xfffff) {
|
||||||
DSSERR("fifo stalls overflow, pixels left %d\n",
|
DSSERR("fifo stalls overflow, pixels left %d\n",
|
||||||
|
@ -2594,6 +2713,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
|
||||||
dsi_if_enable(0);
|
dsi_if_enable(0);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
udelay(1);
|
||||||
}
|
}
|
||||||
#elif 1
|
#elif 1
|
||||||
/* using fifo emptiness */
|
/* using fifo emptiness */
|
||||||
|
@ -2812,11 +2932,15 @@ static int dsi_set_update_mode(struct omap_dss_device *dssdev,
|
||||||
|
|
||||||
static int dsi_set_te(struct omap_dss_device *dssdev, bool enable)
|
static int dsi_set_te(struct omap_dss_device *dssdev, bool enable)
|
||||||
{
|
{
|
||||||
int r;
|
int r = 0;
|
||||||
r = dssdev->driver->enable_te(dssdev, enable);
|
|
||||||
/* XXX for some reason, DSI TE breaks if we don't wait here.
|
if (dssdev->driver->enable_te) {
|
||||||
* Panel bug? Needs more studying */
|
r = dssdev->driver->enable_te(dssdev, enable);
|
||||||
msleep(100);
|
/* XXX for some reason, DSI TE breaks if we don't wait here.
|
||||||
|
* Panel bug? Needs more studying */
|
||||||
|
msleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3637,6 +3761,11 @@ int dsi_init(struct platform_device *pdev)
|
||||||
spin_lock_init(&dsi.errors_lock);
|
spin_lock_init(&dsi.errors_lock);
|
||||||
dsi.errors = 0;
|
dsi.errors = 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
spin_lock_init(&dsi.irq_stats_lock);
|
||||||
|
dsi.irq_stats.last_reset = jiffies;
|
||||||
|
#endif
|
||||||
|
|
||||||
init_completion(&dsi.bta_completion);
|
init_completion(&dsi.bta_completion);
|
||||||
init_completion(&dsi.update_completion);
|
init_completion(&dsi.update_completion);
|
||||||
|
|
||||||
|
|
|
@ -467,14 +467,14 @@ static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
|
||||||
|
|
||||||
static int _omap_dss_wait_reset(void)
|
static int _omap_dss_wait_reset(void)
|
||||||
{
|
{
|
||||||
unsigned timeout = 1000;
|
int t = 0;
|
||||||
|
|
||||||
while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) {
|
while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) {
|
||||||
udelay(1);
|
if (++t > 1000) {
|
||||||
if (!--timeout) {
|
|
||||||
DSSERR("soft reset failed\n");
|
DSSERR("soft reset failed\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
udelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -240,6 +240,7 @@ int dsi_init(struct platform_device *pdev);
|
||||||
void dsi_exit(void);
|
void dsi_exit(void);
|
||||||
|
|
||||||
void dsi_dump_clocks(struct seq_file *s);
|
void dsi_dump_clocks(struct seq_file *s);
|
||||||
|
void dsi_dump_irqs(struct seq_file *s);
|
||||||
void dsi_dump_regs(struct seq_file *s);
|
void dsi_dump_regs(struct seq_file *s);
|
||||||
|
|
||||||
void dsi_save_context(void);
|
void dsi_save_context(void);
|
||||||
|
@ -268,6 +269,7 @@ int dpi_init_display(struct omap_dss_device *dssdev);
|
||||||
int dispc_init(void);
|
int dispc_init(void);
|
||||||
void dispc_exit(void);
|
void dispc_exit(void);
|
||||||
void dispc_dump_clocks(struct seq_file *s);
|
void dispc_dump_clocks(struct seq_file *s);
|
||||||
|
void dispc_dump_irqs(struct seq_file *s);
|
||||||
void dispc_dump_regs(struct seq_file *s);
|
void dispc_dump_regs(struct seq_file *s);
|
||||||
void dispc_irq_handler(void);
|
void dispc_irq_handler(void);
|
||||||
void dispc_fake_vsync_irq(void);
|
void dispc_fake_vsync_irq(void);
|
||||||
|
@ -367,4 +369,16 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
|
||||||
unsigned long rfbi_get_max_tx_rate(void);
|
unsigned long rfbi_get_max_tx_rate(void);
|
||||||
int rfbi_init_display(struct omap_dss_device *display);
|
int rfbi_init_display(struct omap_dss_device *display);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
|
||||||
|
static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr)
|
||||||
|
{
|
||||||
|
int b;
|
||||||
|
for (b = 0; b < 32; ++b) {
|
||||||
|
if (irqstatus & (1 << b))
|
||||||
|
irq_arr[b]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -120,7 +120,7 @@ static struct {
|
||||||
|
|
||||||
struct omap_dss_device *dssdev[2];
|
struct omap_dss_device *dssdev[2];
|
||||||
|
|
||||||
struct kfifo *cmd_fifo;
|
struct kfifo cmd_fifo;
|
||||||
spinlock_t cmd_lock;
|
spinlock_t cmd_lock;
|
||||||
struct completion cmd_done;
|
struct completion cmd_done;
|
||||||
atomic_t cmd_fifo_full;
|
atomic_t cmd_fifo_full;
|
||||||
|
@ -1011,20 +1011,20 @@ static void process_cmd_fifo(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
spin_lock_irqsave(rfbi.cmd_fifo->lock, flags);
|
spin_lock_irqsave(&rfbi.cmd_lock, flags);
|
||||||
|
|
||||||
len = __kfifo_get(rfbi.cmd_fifo, (unsigned char *)&p,
|
len = kfifo_out(&rfbi.cmd_fifo, (unsigned char *)&p,
|
||||||
sizeof(struct update_param));
|
sizeof(struct update_param));
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
DSSDBG("nothing more in fifo\n");
|
DSSDBG("nothing more in fifo\n");
|
||||||
atomic_set(&rfbi.cmd_pending, 0);
|
atomic_set(&rfbi.cmd_pending, 0);
|
||||||
spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
|
spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/
|
/* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/
|
||||||
|
|
||||||
spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
|
spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
|
||||||
|
|
||||||
BUG_ON(len != sizeof(struct update_param));
|
BUG_ON(len != sizeof(struct update_param));
|
||||||
BUG_ON(p.rfbi_module > 1);
|
BUG_ON(p.rfbi_module > 1);
|
||||||
|
@ -1052,25 +1052,25 @@ static void rfbi_push_cmd(struct update_param *p)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int available;
|
int available;
|
||||||
|
|
||||||
spin_lock_irqsave(rfbi.cmd_fifo->lock, flags);
|
spin_lock_irqsave(&rfbi.cmd_lock, flags);
|
||||||
available = RFBI_CMD_FIFO_LEN_BYTES -
|
available = RFBI_CMD_FIFO_LEN_BYTES -
|
||||||
__kfifo_len(rfbi.cmd_fifo);
|
kfifo_len(&rfbi.cmd_fifo);
|
||||||
|
|
||||||
/* DSSDBG("%d bytes left in fifo\n", available); */
|
/* DSSDBG("%d bytes left in fifo\n", available); */
|
||||||
if (available < sizeof(struct update_param)) {
|
if (available < sizeof(struct update_param)) {
|
||||||
DSSDBG("Going to wait because FIFO FULL..\n");
|
DSSDBG("Going to wait because FIFO FULL..\n");
|
||||||
spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
|
spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
|
||||||
atomic_inc(&rfbi.cmd_fifo_full);
|
atomic_inc(&rfbi.cmd_fifo_full);
|
||||||
wait_for_completion(&rfbi.cmd_done);
|
wait_for_completion(&rfbi.cmd_done);
|
||||||
/*DSSDBG("Woke up because fifo not full anymore\n");*/
|
/*DSSDBG("Woke up because fifo not full anymore\n");*/
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = __kfifo_put(rfbi.cmd_fifo, (unsigned char *)p,
|
ret = kfifo_in(&rfbi.cmd_fifo, (unsigned char *)p,
|
||||||
sizeof(struct update_param));
|
sizeof(struct update_param));
|
||||||
/* DSSDBG("pushed %d bytes\n", ret);*/
|
/* DSSDBG("pushed %d bytes\n", ret);*/
|
||||||
|
|
||||||
spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
|
spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
|
||||||
|
|
||||||
BUG_ON(ret != sizeof(struct update_param));
|
BUG_ON(ret != sizeof(struct update_param));
|
||||||
|
|
||||||
|
@ -1155,12 +1155,12 @@ int rfbi_init(void)
|
||||||
{
|
{
|
||||||
u32 rev;
|
u32 rev;
|
||||||
u32 l;
|
u32 l;
|
||||||
|
int r;
|
||||||
|
|
||||||
spin_lock_init(&rfbi.cmd_lock);
|
spin_lock_init(&rfbi.cmd_lock);
|
||||||
rfbi.cmd_fifo = kfifo_alloc(RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL,
|
r = kfifo_alloc(&rfbi.cmd_fifo, RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL);
|
||||||
&rfbi.cmd_lock);
|
if (r)
|
||||||
if (IS_ERR(rfbi.cmd_fifo))
|
return r;
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
init_completion(&rfbi.cmd_done);
|
init_completion(&rfbi.cmd_done);
|
||||||
atomic_set(&rfbi.cmd_fifo_full, 0);
|
atomic_set(&rfbi.cmd_fifo_full, 0);
|
||||||
|
@ -1196,7 +1196,7 @@ void rfbi_exit(void)
|
||||||
{
|
{
|
||||||
DSSDBG("rfbi_exit\n");
|
DSSDBG("rfbi_exit\n");
|
||||||
|
|
||||||
kfifo_free(rfbi.cmd_fifo);
|
kfifo_free(&rfbi.cmd_fifo);
|
||||||
|
|
||||||
iounmap(rfbi.base);
|
iounmap(rfbi.base);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1311,6 +1311,7 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
|
||||||
if (rg->vrfb.vaddr[0]) {
|
if (rg->vrfb.vaddr[0]) {
|
||||||
iounmap(rg->vrfb.vaddr[0]);
|
iounmap(rg->vrfb.vaddr[0]);
|
||||||
omap_vrfb_release_ctx(&rg->vrfb);
|
omap_vrfb_release_ctx(&rg->vrfb);
|
||||||
|
rg->vrfb.vaddr[0] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2114,6 +2115,11 @@ static int omapfb_probe(struct platform_device *pdev)
|
||||||
dssdev = NULL;
|
dssdev = NULL;
|
||||||
for_each_dss_dev(dssdev) {
|
for_each_dss_dev(dssdev) {
|
||||||
omap_dss_get_device(dssdev);
|
omap_dss_get_device(dssdev);
|
||||||
|
if (!dssdev->driver) {
|
||||||
|
dev_err(&pdev->dev, "no driver for display\n");
|
||||||
|
r = -EINVAL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
fbdev->displays[fbdev->num_displays++] = dssdev;
|
fbdev->displays[fbdev->num_displays++] = dssdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue