Re: ov3640 sensor -> CCDC won't become idle!

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

> as the subject says I got a problem with the ccdc.
> 
> My pipeline is: sensor -> ccdc -> memory
> 
> By doing some research I found a appropriate answer from Laurent:
> 
> "The OMAP3 ISP is quite picky about its input signals and doesn't gracefully 
> handle missing or extra sync pulses for instance. A "CCDC won't become idle!" 
> message usually indicates that the CCDC received a frame of unexpected size 
> (this can happen if the sensor stops in the middle of a frame for instance), 
> or that the driver had no time to process the end of frame interrupt before 
> the next frame arrived (either because of an unsually long interrupt delay on 
> the system, or because of too low vertical blanking)."
> 
> That sounds logical, but whatever I do nothing works for me. 
> 
> Can anyone who had that problem share what you did to solve that problem?
> Or does anyone have a hint for me how to solve this?

I think I've stumbled upon a solution for this problem (stream doesn't 
start properly, resulting in 'CCDC won't become idle') today; the idea is 
to delay ccdc_enable() and SYN_MODE_VDHDEN after the first VSYNC has been 
received

the assumption is that the ov3640 outputs HSYNC/VSYNC in some 
weird/undeterministic way when started, but stabilizes afterwards; the 
OMAP3 ISP gets confused by inproper HSYNC/VSYNC and never recovers...

OMAP3 ISP observations:
SYN_MODE_VDHDEN enables the VSYNC/HSYNC processing of the CCDC (when 
VSYNC/HSYNC configured as input) of the ISP, i.e. the ISP starts counting
horizontal lines needed to trigger VDINT0/VDINT1

the VS_HS_IRQ can be configured to trigger on VSYNC, this is independent 
from SYN_MODE_VDHDEN and VDINT0/VDINT1 and works even when neither 
SYN_MODE_VDHDEN nor CCDC_PCR_EN is set (i.e. before starting the CCDC)

so ccdc_hs_vs_isr() can be used to trigger on the first (maybe n-th) VSYNC 
(when the ov3640 has stabilized); at this point SYN_MODE_VDHDEN and 
CCDC_PCR_EN can be turn on

so the workflow is as follows:

1. configure ISP: ccdc_set_stream() but no ccdc_enable() and no 
SYN_MODE_VDHDEN
2. start ov3640: ov3640_set_stream()
3. wait for VSYNC to trigger, enable SYN_MODE_VDHDEN and ccdc_enable() in 
ccdc_hs_vs_isr()

works for me :)
tested with beagle-xm, ov3640 (Laurent's patches) in YUV 640x480, ISP 
direct to memory, kernel 3.7

the patch below illustrates this

regards, p.


diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index aa9df9d..7d587ee 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -976,7 +976,8 @@ static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
 {
 	struct isp_device *isp = to_isp_device(ccdc);
 	const struct v4l2_mbus_framefmt *format;
-	u32 syn_mode = ISPCCDC_SYN_MODE_VDHDEN;
+	u32 syn_mode = 0; // ISPCCDC_SYN_MODE_VDHDEN;
+	ccdc->vdhden = 0;
 
 	format = &ccdc->formats[CCDC_PAD_SINK];
 
@@ -1416,9 +1417,19 @@ static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event)
 static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
 {
 	struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
+	struct isp_device *isp = to_isp_device(ccdc);
 	struct video_device *vdev = ccdc->subdev.devnode;
 	struct v4l2_event event;
 
+	if (!ccdc->vdhden) {
+		isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE,
+			ISPCCDC_SYN_MODE_VDHDEN);
+		ccdc_enable(ccdc);
+		ccdc->vdhden = 1;
+
+		return;
+	}
+
 	/* Frame number propagation */
 	atomic_inc(&pipe->frame_number);
 
@@ -1765,8 +1776,9 @@ static int ccdc_set_stream(struct v4l2_subdev *sd, int enable)
 		if (ccdc->output & CCDC_OUTPUT_MEMORY)
 			omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
 
-		if (ccdc->underrun || !(ccdc->output & CCDC_OUTPUT_MEMORY))
-			ccdc_enable(ccdc);
+		if (ccdc->underrun || !(ccdc->output & CCDC_OUTPUT_MEMORY)) {
+//			ccdc_enable(ccdc);
+		}
 
 		ccdc->underrun = 0;
 		break;
diff --git a/drivers/media/platform/omap3isp/ispccdc.h b/drivers/media/platform/omap3isp/ispccdc.h
index a5da9e1..a502bc3 100644
--- a/drivers/media/platform/omap3isp/ispccdc.h
+++ b/drivers/media/platform/omap3isp/ispccdc.h
@@ -146,6 +146,7 @@ struct isp_ccdc_device {
 	struct ispccdc_lsc lsc;
 	unsigned int update;
 	unsigned int shadow_update;
+	unsigned int vdhden;
 
 	unsigned int underrun:1;
 	enum isp_pipeline_stream_state state;


-- 

Peter Meerwald
+43-664-2444418 (mobile)
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux