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