Merge changes I02b4f046,Iba6ef5e3,I37166389 into msm-3.0

* changes:
  msm_fb: display: add spinlock to protect dma status.
  msm_fb: display: Add SMP-safety for PPP Operations
  msm_fb: display: remove while loop in mdp ISR
This commit is contained in:
Linux Build Service Account
2012-02-10 06:34:33 -08:00
committed by QuIC Gerrit Code Review
2 changed files with 125 additions and 104 deletions

View File

@@ -468,11 +468,16 @@ error:
int mdp_ppp_pipe_wait(void)
{
int ret = 1;
boolean wait;
unsigned long flag;
/* wait 5 seconds for the operation to complete before declaring
the MDP hung */
spin_lock_irqsave(&mdp_spin_lock, flag);
wait = mdp_ppp_waiting;
spin_unlock_irqrestore(&mdp_spin_lock, flag);
if (mdp_ppp_waiting == TRUE) {
if (wait == TRUE) {
ret = wait_for_completion_interruptible_timeout(&mdp_ppp_comp,
5 * HZ);
@@ -548,6 +553,7 @@ void mdp_disable_irq_nosync(uint32 term)
void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd)
{
unsigned long flag;
/* complete all the writes before starting */
wmb();
@@ -561,7 +567,9 @@ void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd)
mdp_enable_irq(term);
INIT_COMPLETION(mdp_ppp_comp);
spin_lock_irqsave(&mdp_spin_lock, flag);
mdp_ppp_waiting = TRUE;
spin_unlock_irqrestore(&mdp_spin_lock, flag);
outpdw(MDP_BASE + 0x30, 0x1000);
wait_for_completion_killable(&mdp_ppp_comp);
mdp_disable_irq(term);
@@ -812,9 +820,12 @@ irqreturn_t mdp_isr(int irq, void *ptr)
{
uint32 mdp_interrupt = 0;
struct mdp_dma_data *dma;
unsigned long flag;
/* Ensure all the register write are complete */
mb();
mdp_is_in_isr = TRUE;
do {
mdp_interrupt = inp32(MDP_INTR_STATUS);
outp32(MDP_INTR_CLEAR, mdp_interrupt);
@@ -826,7 +837,7 @@ irqreturn_t mdp_isr(int irq, void *ptr)
}
if (!mdp_interrupt)
break;
goto out;
/* DMA3 TV-Out Start */
if (mdp_interrupt & TV_OUT_DMA3_START) {
@@ -861,6 +872,7 @@ irqreturn_t mdp_isr(int irq, void *ptr)
MDP_OUTP(MDP_BASE + 0x94000, 1);
}
}
/* LCDC Frame Start */
if (mdp_interrupt & LCDC_FRAME_START) {
/* let's disable LCDC interrupt */
@@ -878,16 +890,15 @@ irqreturn_t mdp_isr(int irq, void *ptr)
if (mdp_interrupt & MDP_DMA_S_DONE) {
dma = &dma_s_data;
dma->busy = FALSE;
mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_OFF,
TRUE);
mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
complete(&dma->comp);
}
/* DMA_E LCD-Out Complete */
if (mdp_interrupt & MDP_DMA_E_DONE) {
dma = &dma_s_data;
dma->busy = FALSE;
mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_OFF,
TRUE);
mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
complete(&dma->comp);
}
@@ -906,34 +917,40 @@ irqreturn_t mdp_isr(int irq, void *ptr)
}
#ifndef CONFIG_FB_MSM_MDP303
dma = &dma2_data;
spin_lock_irqsave(&mdp_spin_lock, flag);
dma->busy = FALSE;
mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF,
TRUE);
spin_unlock_irqrestore(&mdp_spin_lock, flag);
mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
complete(&dma->comp);
#else
if (mdp_prim_panel_type == MIPI_CMD_PANEL) {
dma = &dma2_data;
spin_lock_irqsave(&mdp_spin_lock, flag);
dma->busy = FALSE;
mdp_pipe_ctrl(MDP_DMA2_BLOCK,
MDP_BLOCK_POWER_OFF, TRUE);
spin_unlock_irqrestore(&mdp_spin_lock, flag);
mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF,
TRUE);
complete(&dma->comp);
}
#endif
}
/* PPP Complete */
if (mdp_interrupt & MDP_PPP_DONE) {
#ifdef CONFIG_FB_MSM_MDP31
MDP_OUTP(MDP_BASE + 0x00100, 0xFFFF);
#endif
mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
spin_lock_irqsave(&mdp_spin_lock, flag);
if (mdp_ppp_waiting) {
mdp_ppp_waiting = FALSE;
complete(&mdp_ppp_comp);
}
spin_unlock_irqrestore(&mdp_spin_lock, flag);
}
} while (1);
mdp_is_in_isr = FALSE;
out:
mdp_is_in_isr = FALSE;
return IRQ_HANDLED;
}

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -478,16 +478,20 @@ static void mdp_dma2_update_sub(struct msm_fb_data_type *mfd)
void mdp_dma2_update(struct msm_fb_data_type *mfd)
#endif
{
unsigned long flag;
down(&mfd->dma->mutex);
if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
down(&mfd->sem);
mfd->ibuf_flushed = TRUE;
mdp_dma2_update_lcd(mfd);
spin_lock_irqsave(&mdp_spin_lock, flag);
mdp_enable_irq(MDP_DMA2_TERM);
mfd->dma->busy = TRUE;
INIT_COMPLETION(mfd->dma->comp);
spin_unlock_irqrestore(&mdp_spin_lock, flag);
/* schedule DMA to start */
mdp_dma_schedule(mfd, MDP_DMA2_TERM);
up(&mfd->sem);