mirror of
https://github.com/genesi/linux-legacy.git
synced 2026-09-24 23:54:24 +00:00
ENGR00120428 v4l2 output: jitter after blank/unblank fb
blank/unblank fb during v4l2 playback, unblank will cause current buffer of display channel to be 1. This patch make the sequence of select display buffer correct. Signed-off-by: Jason Chen <b02280@freescale.com>
This commit is contained in:
@@ -246,6 +246,22 @@ static u32 bpp_to_fmt(struct fb_info *fbi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* we are using double buffer for video playback, ipu need make
|
||||
* sure current buffer should not be the same buffer of next display
|
||||
* one.
|
||||
*/
|
||||
static int select_display_buffer(vout_data *vout, int next_buf)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ipu_get_cur_buffer_idx(vout->display_ch, IPU_INPUT_BUFFER)
|
||||
!= next_buf)
|
||||
ret = ipu_select_buffer(vout->display_ch, IPU_INPUT_BUFFER,
|
||||
next_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void setup_next_buf_timer(vout_data *vout, int index)
|
||||
{
|
||||
unsigned long timeout;
|
||||
@@ -347,8 +363,7 @@ static void timer_work_func(struct work_struct *work)
|
||||
}
|
||||
|
||||
if (vout->ic_bypass)
|
||||
ret = ipu_select_buffer(vout->display_ch, IPU_INPUT_BUFFER,
|
||||
vout->next_rdy_ipu_buf);
|
||||
ret = select_display_buffer(vout, vout->next_rdy_ipu_buf);
|
||||
else if (LOAD_3FIELDS(vout))
|
||||
ret = ipu_select_multi_vdi_buffer(vout->next_rdy_ipu_buf);
|
||||
else
|
||||
@@ -580,8 +595,7 @@ static irqreturn_t mxc_v4l2out_work_irq_handler(int irq, void *dev_id)
|
||||
vout->next_done_ipu_buf = !vout->next_done_ipu_buf;
|
||||
|
||||
} else /* right stripe is done, run display refresh */
|
||||
ret = ipu_select_buffer(vout->display_ch, IPU_INPUT_BUFFER,
|
||||
disp_buf_num);
|
||||
select_display_buffer(vout, disp_buf_num);
|
||||
|
||||
vout->next_rdy_ipu_buf = !vout->next_rdy_ipu_buf;
|
||||
|
||||
@@ -609,8 +623,7 @@ static irqreturn_t mxc_v4l2out_work_irq_handler(int irq, void *dev_id)
|
||||
vout->pp_split_buf_num = (vout->pp_split_buf_num + 1) & 3;
|
||||
} else {
|
||||
/* show to display */
|
||||
ret = ipu_select_buffer(vout->display_ch, IPU_INPUT_BUFFER,
|
||||
vout->next_done_ipu_buf);
|
||||
select_display_buffer(vout, vout->next_done_ipu_buf);
|
||||
ret += ipu_select_buffer(vout->display_input_ch, IPU_OUTPUT_BUFFER,
|
||||
vout->next_done_ipu_buf);
|
||||
}
|
||||
|
||||
@@ -1204,6 +1204,21 @@ void ipu_clear_buffer_ready(ipu_channel_t channel, ipu_buffer_t type,
|
||||
{
|
||||
/*TODO*/
|
||||
}
|
||||
EXPORT_SYMBOL(ipu_clear_buffer_ready);
|
||||
|
||||
uint32_t ipu_get_cur_buffer_idx(ipu_channel_t channel, ipu_buffer_t type)
|
||||
{
|
||||
uint32_t reg, dma_chan;
|
||||
|
||||
dma_chan = channel_2_dma(channel, type);
|
||||
|
||||
reg = __raw_readl(IPU_CHA_CUR_BUF);
|
||||
if (reg & (1UL << dma_chan))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ipu_get_cur_buffer_idx);
|
||||
|
||||
/*!
|
||||
* This function disables a logical channel.
|
||||
|
||||
@@ -1788,6 +1788,7 @@ void ipu_clear_buffer_ready(ipu_channel_t channel, ipu_buffer_t type,
|
||||
__raw_writel(0x0, IPU_GPR); /* write one to set */
|
||||
spin_unlock_irqrestore(&ipu_lock, lock_flags);
|
||||
}
|
||||
EXPORT_SYMBOL(ipu_clear_buffer_ready);
|
||||
|
||||
static irqreturn_t disable_chan_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
@@ -2162,6 +2163,22 @@ void ipu_free_irq(uint32_t irq, void *dev_id)
|
||||
}
|
||||
EXPORT_SYMBOL(ipu_free_irq);
|
||||
|
||||
uint32_t ipu_get_cur_buffer_idx(ipu_channel_t channel, ipu_buffer_t type)
|
||||
{
|
||||
uint32_t reg, dma_chan;
|
||||
|
||||
dma_chan = channel_2_dma(channel, type);
|
||||
if (!idma_is_valid(dma_chan))
|
||||
return -EINVAL;
|
||||
|
||||
reg = __raw_readl(IPU_CHA_CUR_BUF(dma_chan/32));
|
||||
if (reg & idma_mask(dma_chan))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ipu_get_cur_buffer_idx);
|
||||
|
||||
uint32_t _ipu_channel_status(ipu_channel_t channel)
|
||||
{
|
||||
uint32_t stat = 0;
|
||||
|
||||
@@ -897,6 +897,7 @@ int32_t ipu_unlink_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch);
|
||||
int32_t ipu_is_channel_busy(ipu_channel_t channel);
|
||||
void ipu_clear_buffer_ready(ipu_channel_t channel, ipu_buffer_t type,
|
||||
uint32_t bufNum);
|
||||
uint32_t ipu_get_cur_buffer_idx(ipu_channel_t channel, ipu_buffer_t type);
|
||||
int32_t ipu_enable_channel(ipu_channel_t channel);
|
||||
int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop);
|
||||
int32_t ipu_swap_channel(ipu_channel_t from_ch, ipu_channel_t to_ch);
|
||||
|
||||
Reference in New Issue
Block a user