Hello all,in our project,we need display camera data to multi display device( adv739x ,ldb and hdmi).here is our design:
we use imx6d process with ov5640 camera. our BSP is linux-3.0.35;
the fb device configured as below:
fb0/fb1 -> adv739x IPU0/DI0
fb4->hdmi IPU0/DI1
fb2/fb3-> ldb IPU1/DI0 (primary display)
Now we can display camera data to each device seperately,but we don't know how to mirror camera data to all three display device. So we hacked into kernel driver(driver/media/video/caputre/ipu_prp_vf_sdc_bg.c)
In the original driver,camera data buffer into vf_bufs0/1 through CSI_PRP_VF_MEM channel,then route to fb device through MEM_ROT_VF_MEM channel)
it's sync interrupt is IPU_IRQ_PRP_VF_OUT_EOF and IPU_IRQ_BG_SF_END.
so we try something like this:
we set IPU1 MEM_PRP_VF_MEM channel input buffer to vf_bufs0/1 ,output buffer to FB4(HDMI),
IPU0 MEM_PP_MEM channel input buffer to vf_bufs0/1,output buffer to FB1(CVBS)
so when we display camera on FB2,it will automatically mirror to FB1&FB4.
it's not beauty but it's worked.
BUT! we found tearing effect on fb1 & fb4,The key problem is we don't know how to sync output frame.
we start MEM_PP_MEM and MEM_PRP_VF_MEM process when IPU_IRQ_PRP_VF_OUT_EOF interrupt arrival,
here is out interrupt service function:
static irqreturn_t prpvf_vf_eof_callback(int irq, void *dev_id)
{
cam_data *cam = dev_id;
ipu_select_buffer(disp_ipu, MEM_PRP_VF_MEM, IPU_INPUT_BUFFER, buffer_num);
ipu_select_buffer(disp_ipu, cvbs_channel, IPU_INPUT_BUFFER, cvbs_num);
ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM, IPU_INPUT_BUFFER, buffer_num);
buffer_num = (buffer_num == 0) ? 1 : 0;
ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, buffer_num);
buffer_ready++;
hdmi_ready++;
return IRQ_HANDLED;
}
static irqreturn_t mem_pp_eof_callback(int irq, void *dev_id)
{
ipu_select_buffer(cvbs_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER, cvbs_num);
cvbs_num = (cvbs_num == 0 ) ? 1 : 0;
ipu_select_buffer(disp_ipu, cvbs_channel, IPU_OUTPUT_BUFFER, cvbs_num);
return IRQ_HANDLED;
}
static irqreturn_t mem_prp_vf_eof_callback(int irq, void *dev_id)
{
cam_data *cam = dev_id;
if (hdmi_ready > 0) {
ipu_select_buffer(disp_ipu, MEM_PRP_VF_MEM, IPU_OUTPUT_BUFFER, 0);
hdmi_ready--;
}
return IRQ_HANDLED;
}
We know it's not a normal way, but we really don't know how to mirror camera data to triple FB,
Is any one know how to implement triple mirror display or how to fix our tearing effect?
our source code attached below
any suggestion will be appreciated.
Original Attachment has been moved to: ipu_prp_vf_sdc_bg.c.zip