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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox