From: Tomasz Sterna <tomek@xiaoka.com>
To: linux-arm-msm@vger.kernel.org
Subject: [PATCH] [Streak] Add workaround for TTY kernel OOPS at the cost of performance.
Date: Fri, 01 Oct 2010 00:42:45 +0200 [thread overview]
Message-ID: <1285886565.11486.26.camel@wing> (raw)
The current framebuffer driver oopses when used as a console (kernel
parameter: console=tty ).
Here is a patch that makes it work - at the cost of performance.
Signed-off-by: Bradley Smith <brad@brad-smith.co.uk>
(cherry picked from commit 28d06a6366c851c6e0c5b954353bf82cb641d4e7)
---
drivers/video/msm/Kconfig | 4 ++++
drivers/video/msm/mdp.c | 20 ++++++++++++++++++++
drivers/video/msm/mdp.h | 3 +++
drivers/video/msm/mdp_dma.c | 15 +++++++++++++++
drivers/video/msm/mdp_dma_s.c | 28 ++++++++++++++++++++++++++++
drivers/video/msm/msm_fb.c | 2 ++
drivers/video/msm/msm_fb.h | 14 ++++++++++++++
7 files changed, 86 insertions(+), 0 deletions(-)
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index e887a2d..cff8435 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -14,3 +14,7 @@ config FB_MSM_LCDC
depends on FB_MSM && MSM_MDP31
default y
+config MSM_FB_TTY_WORKAROUND
+ bool "Workaround TTY kernel OOPS at the cost of performance"
+ depends on FB_MSM
+ default n
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index e56dd81..8bc2b13 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -118,6 +118,10 @@ static int mdp_suspend(struct platform_device *pdev, pm_message_t state);
struct timeval mdp_dma2_timeval;
struct timeval mdp_ppp_timeval;
+#ifdef CONFIG_MSM_FB_TTY_WORKAROUND
+LIST_HEAD(msm_fb_dma_task_list);
+#endif
+
#ifdef CONFIG_HAS_EARLYSUSPEND
static struct early_suspend early_suspend;
#endif
@@ -634,10 +638,26 @@ irqreturn_t mdp_isr(int irq, void *ptr)
/* DMA2 LCD-Out Complete */
if (mdp_interrupt & MDP_DMA_S_DONE) {
dma = &dma_s_data;
+#ifdef CONFIG_MSM_FB_TTY_WORKAROUND
+ if(!list_empty(&msm_fb_dma_task_list)) {
+ struct msm_fb_dma_task *tsk = list_first_entry(
+ &msm_fb_dma_task_list, struct msm_fb_dma_task, list);
+ dma->busy = TRUE;
+ mdp_dma_s_update_lcd(tsk->mfd, &tsk->ibuf);
+ list_del(&tsk->list);
+ kfree(tsk);
+ }
+ else {
+ mdp_disable_irq(MDP_DMA_S_TERM);
+ mdp_disable_irq(MDP_DMA_E_TERM);
+ dma->busy = FALSE;
+ }
+#else
dma->busy = FALSE;
mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_OFF,
TRUE);
complete(&dma->comp);
+#endif
}
/* DMA_E LCD-Out Complete */
if (mdp_interrupt & MDP_DMA_E_DONE) {
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index d60ccae..f3d064b 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -680,4 +680,7 @@ int mdp_debugfs_init(void);
#endif
void mdp_dma_s_update(struct msm_fb_data_type *mfd);
+#ifdef CONFIG_MSM_FB_TTY_WORKAROUND
+void mdp_dma_s_update_lcd(struct msm_fb_data_type *mfd, MDPIBUF *iBuf);
+#endif
#endif /* MDP_H */
diff --git a/drivers/video/msm/mdp_dma.c b/drivers/video/msm/mdp_dma.c
index dc8d58d..f62c7e3 100644
--- a/drivers/video/msm/mdp_dma.c
+++ b/drivers/video/msm/mdp_dma.c
@@ -433,7 +433,9 @@ void mdp_dma2_update(struct msm_fb_data_type *mfd)
down(&mfd->dma->mutex);
if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
down(&mfd->sem);
+#if !defined(CONFIG_MSM_FB_TTY_WORKAROUND)
mfd->ibuf_flushed = TRUE;
+#endif
mdp_dma2_update_lcd(mfd);
mdp_enable_irq(MDP_DMA2_TERM);
@@ -448,11 +450,13 @@ void mdp_dma2_update(struct msm_fb_data_type *mfd)
wait_for_completion_killable(&mfd->dma->comp);
mdp_disable_irq(MDP_DMA2_TERM);
+#if !defined(CONFIG_MSM_FB_TTY_WORKAROUND)
/* signal if pan function is waiting for the update completion */
if (mfd->pan_waiting) {
mfd->pan_waiting = FALSE;
complete(&mfd->pan_comp);
}
+#endif
}
up(&mfd->dma->mutex);
}
@@ -484,6 +488,12 @@ void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty,
iBuf->vsync_enable = sync;
+#ifdef CONFIG_MSM_FB_TTY_WORKAROUND
+ iBuf->dma_x = 0;
+ iBuf->dma_y = 0;
+ iBuf->dma_w = info->var.xres;
+ iBuf->dma_h = info->var.yres;
+#else
if (dirty) {
/*
* ToDo: dirty region check inside var.xoffset+xres
@@ -500,6 +510,7 @@ void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty,
iBuf->dma_h = info->var.yres;
}
mfd->ibuf_flushed = FALSE;
+#endif
up(&mfd->sem);
}
@@ -510,6 +521,9 @@ void mdp_dma_pan_update(struct fb_info *info)
iBuf = &mfd->ibuf;
+#ifdef CONFIG_MSM_FB_TTY_WORKAROUND
+ mfd->dma_fnc(mfd);
+#else
if (mfd->sw_currently_refreshing) {
/* we need to wait for the pending update */
mfd->pan_waiting = TRUE;
@@ -521,6 +535,7 @@ void mdp_dma_pan_update(struct fb_info *info)
wait_for_completion_killable(&mfd->pan_comp);
} else
mfd->dma_fnc(mfd);
+#endif
}
void mdp_refresh_screen(unsigned long data)
diff --git a/drivers/video/msm/mdp_dma_s.c b/drivers/video/msm/mdp_dma_s.c
index ee39504..c9b67d5 100644
--- a/drivers/video/msm/mdp_dma_s.c
+++ b/drivers/video/msm/mdp_dma_s.c
@@ -37,9 +37,14 @@
#include "mdp.h"
#include "msm_fb.h"
+#ifdef CONFIG_MSM_FB_TTY_WORKAROUND
+void mdp_dma_s_update_lcd(struct msm_fb_data_type *mfd, MDPIBUF *iBuf)
+{
+#else
static void mdp_dma_s_update_lcd(struct msm_fb_data_type *mfd)
{
MDPIBUF *iBuf = &mfd->ibuf;
+#endif
int mddi_dest = FALSE;
uint32 outBpp = iBuf->bpp;
uint32 dma_s_cfg_reg;
@@ -141,6 +146,28 @@ static void mdp_dma_s_update_lcd(struct msm_fb_data_type *mfd)
void mdp_dma_s_update(struct msm_fb_data_type *mfd)
{
down(&mfd->dma->mutex);
+#ifdef CONFIG_MSM_FB_TTY_WORKAROUND
+ if(mfd && mfd->panel_power_on) {
+ if (!mfd->dma->busy) {
+ down(&mfd->sem);
+ mdp_enable_irq(MDP_DMA_S_TERM);
+ if (mfd->panel_info.type == MDDI_PANEL)
+ mdp_enable_irq(MDP_DMA_S_TERM);
+ else
+ mdp_enable_irq(MDP_DMA_E_TERM);
+ mfd->dma->busy = TRUE;
+ mdp_dma_s_update_lcd(mfd, &mfd->ibuf);
+ up(&mfd->sem);
+ }
+ else {
+ struct msm_fb_dma_task *tsk = kzalloc(sizeof(
+ struct msm_fb_dma_task), GFP_ATOMIC);
+ tsk->mfd = mfd;
+ tsk->ibuf = mfd->ibuf;
+ list_add_tail(&tsk->list, &msm_fb_dma_task_list);
+ }
+ }
+#else
if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
down(&mfd->sem);
mdp_enable_irq(MDP_DMA_S_TERM);
@@ -167,5 +194,6 @@ void mdp_dma_s_update(struct msm_fb_data_type *mfd)
complete(&mfd->pan_comp);
}
}
+#endif
up(&mfd->dma->mutex);
}
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 14b1860..d355813 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -1025,8 +1025,10 @@ static int msm_fb_register(struct msm_fb_data_type *mfd)
mfd->sw_refreshing_enable = TRUE;
mfd->panel_power_on = FALSE;
+#if !defined(CONFIG_MSM_FB_TTY_WORKAROUND)
mfd->pan_waiting = FALSE;
init_completion(&mfd->pan_comp);
+#endif
init_completion(&mfd->refresher_comp);
init_MUTEX(&mfd->sem);
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index 2395cb2..2e1e38a 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -63,6 +63,10 @@
#define MFD_KEY 0x11161126
#define MSM_FB_MAX_DEV_LIST 32
+#ifdef CONFIG_MSM_FB_TTY_WORKAROUND
+extern struct list_head msm_fb_dma_task_list;
+#endif
+
struct disp_info_type_suspend {
boolean op_enable;
boolean sw_refreshing_enable;
@@ -91,12 +95,16 @@ struct msm_fb_data_type {
#endif
MDPIBUF ibuf;
+#if !defined(CONFIG_MSM_FB_TTY_WORKAROUND)
boolean ibuf_flushed;
+#endif
struct timer_list refresh_timer;
struct completion refresher_comp;
+#if !defined(CONFIG_MSM_FB_TTY_WORKAROUND)
boolean pan_waiting;
struct completion pan_comp;
+#endif
/* vsync */
boolean use_mdp_vsync;
@@ -167,6 +175,12 @@ struct msm_fb_data_type {
struct pm_qos_request_list *pm_qos_req;
};
+struct msm_fb_dma_task {
+ struct msm_fb_data_type* mfd;
+ MDPIBUF ibuf;
+ struct list_head list;
+};
+
struct dentry *msm_fb_get_debugfs_root(void);
void msm_fb_debugfs_file_create(struct dentry *root, const char *name,
u32 *var);
--
1.7.0.4
next reply other threads:[~2010-09-30 22:42 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-30 22:42 Tomasz Sterna [this message]
2010-09-30 23:04 ` [PATCH] [Streak] Add workaround for TTY kernel OOPS at the cost of performance Daniel Walker
2010-10-01 8:52 ` Tomasz Sterna
2010-10-01 15:47 ` Daniel Walker
2010-10-01 20:07 ` Tomasz Sterna
2010-10-02 0:26 ` Daniel Walker
2010-10-01 21:11 ` Tomasz Sterna
[not found] ` <AANLkTimVpsmWLpXwuLyFgC3sOSMVCbF38DNRL13_5bgk@mail.gmail.com>
2010-10-02 10:14 ` Bradley Smith
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1285886565.11486.26.camel@wing \
--to=tomek@xiaoka.com \
--cc=linux-arm-msm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.