ov3640 sensor -> CCDC won't become idle!
Hi all, 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? root@overo2:~/media_test/bin# sudo ./media-ctl -v -r -l '"ov3640 3-003c":0->"OMAP3 ISP CCDC":0[1], "OMAP3 ISP CCDC":1->"OMAP3 ISP CCDC output":0[1]' Opening media device /dev/media0 Enumerating entities Found 16 entities Enumerating pads and links Resetting all links to inactive Setting up link 16:0 -> 5:0 [1] Setting up link 5:1 -> 6:0 [1] root@overo2:~/media_test/bin# sudo ./media-ctl -v -V '"ov3640 3-003c":0 [Y8 2048x1536 (32,20)/2048x1536], "OMAP3 ISP CCDC":1 [Y8 2048x1536]' Opening media device /dev/media0 Enumerating entities Found 16 entities Enumerating pads and links Setting up selection target 0 rectangle (32,20)/2048x1536 on pad ov3640 3-003c/0 Selection rectangle set: (32,20)/2040x1536 Setting up format Y8 2048x1536 on pad ov3640 3-003c/0 Format set: Y8 2040x1536 Setting up format Y8 2040x1536 on pad OMAP3 ISP CCDC/0 Format set: Y8 2040x1536 Setting up format Y8 2048x1536 on pad OMAP3 ISP CCDC/1 Format set: Y8 2032x1536 root@overo2:~/yavta-HEAD-d9b7cfc# sudo ./yavta -p -f Y8 -s 2032x1536 -n 4 --skip 3 --capture=13 --file=image /dev/video2 Device /dev/video2 opened. Device `OMAP3 ISP CCDC output' on `media' is a video capture device. Video format set: Y8 (59455247) 2032x1536 (stride 2048) buffer size 3145728 Video format: Y8 (59455247) 2032x1536 (stride 2048) buffer size 3145728 4 buffers requested. length: 3145728 offset: 0 timestamp type: unknown Buffer 0 mapped at address 0xb6b36000. length: 3145728 offset: 3145728 timestamp type: unknown Buffer 1 mapped at address 0xb6836000. length: 3145728 offset: 6291456 timestamp type: unknown Buffer 2 mapped at address 0xb6536000. length: 3145728 offset: 9437184 timestamp type: unknown Buffer 3 mapped at address 0xb6236000. Press enter to start capture root@overo2:~/yavta-HEAD-d9b7cfc# dmesg [0.00] Booting Linux on physical CPU 0 [0.00] Initializing cgroup subsys cpuset [0.00] Initializing cgroup subsys cpu [0.00] Linux version 3.5.0 (linuxentwickler@linuxentwickler-OEM) (gcc version 4.3.3 (GCC) ) #43 PREEMPT Mon Sep 9 11:53:31 CEST 2013 [0.00] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7d [0.00] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [0.00] Machine: Gumstix Overo [0.00] Reserving 12582912 bytes SDRAM for VRAM [0.00] Memory policy: ECC disabled, Data cache writeback [0.00] On node 0 totalpages: 53248 [0.00] free_area_init_node: node 0, pgdat c07159e4, node_mem_map c07af000 [0.00] Normal zone: 512 pages used for memmap [0.00] Normal zone: 0 pages reserved [0.00] Normal zone: 52736 pages, LIFO batch:15 [0.00] OMAP3630 ES1.2 (l2cache iva sgx neon isp 192mhz_clk ) [0.00] Clocking rate (Crystal/Core/MPU): 26.0/332/600 MHz [0.00] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768 [0.00] pcpu-alloc: [0] 0 [0.00] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 52736 [0.00] Kernel command line: mem=93M@0x8000 mem=128M@0x8800 console=ttyO2,115200n8 vram=12M omapfb.mode=dvi:1024x768MR-16@60 omapfb.debug=y omapdss.def_disp=dvi root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait [0.00] PID hash table entries: 1024 (order: 0, 4096 bytes) [0.00] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes) [0.00] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes) [0.00] allocated 524288 bytes of page_cgroup [0.00] please try 'cgroup_disable=memory' option if you don't want memory cgroups [0.00] Memory: 93MB 115MB = 208MB total [0.00] Memory: 202572k/202572k available, 23732k reserved, 0K highmem [0.00] Virtual kernel memory layout: [0.00] vector : 0x - 0x1000 ( 4 kB) [0.00] fixmap : 0xfff0 - 0xfffe ( 896 kB) [0.00] vmalloc : 0xd080 - 0xff00 ( 744 MB) [0.00] lowmem : 0xc000 - 0xd000 ( 256 MB) [0.00] pkmap : 0xbfe0 - 0xc000 ( 2 MB) [0.00] modules : 0xbf
Re: ov3640 sensor -> CCDC won't become idle!
Hi Tom, Try adding "nohlt" boot option. I faced with the similar issue for another sensor and found this workaround. I'm out of office and can't find the link to the relative sources. Regards, Dmitry - Original Message - From: "Tom" To: linux-media@vger.kernel.org Sent: Monday, September 9, 2013 4:07:33 PM Subject: ov3640 sensor -> CCDC won't become idle! Hi all, 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? root@overo2:~/media_test/bin# sudo ./media-ctl -v -r -l '"ov3640 3-003c":0->"OMAP3 ISP CCDC":0[1], "OMAP3 ISP CCDC":1->"OMAP3 ISP CCDC output":0[1]' Opening media device /dev/media0 Enumerating entities Found 16 entities Enumerating pads and links Resetting all links to inactive Setting up link 16:0 -> 5:0 [1] Setting up link 5:1 -> 6:0 [1] root@overo2:~/media_test/bin# sudo ./media-ctl -v -V '"ov3640 3-003c":0 [Y8 2048x1536 (32,20)/2048x1536], "OMAP3 ISP CCDC":1 [Y8 2048x1536]' Opening media device /dev/media0 Enumerating entities Found 16 entities Enumerating pads and links Setting up selection target 0 rectangle (32,20)/2048x1536 on pad ov3640 3-003c/0 Selection rectangle set: (32,20)/2040x1536 Setting up format Y8 2048x1536 on pad ov3640 3-003c/0 Format set: Y8 2040x1536 Setting up format Y8 2040x1536 on pad OMAP3 ISP CCDC/0 Format set: Y8 2040x1536 Setting up format Y8 2048x1536 on pad OMAP3 ISP CCDC/1 Format set: Y8 2032x1536 root@overo2:~/yavta-HEAD-d9b7cfc# sudo ./yavta -p -f Y8 -s 2032x1536 -n 4 --skip 3 --capture=13 --file=image /dev/video2 Device /dev/video2 opened. Device `OMAP3 ISP CCDC output' on `media' is a video capture device. Video format set: Y8 (59455247) 2032x1536 (stride 2048) buffer size 3145728 Video format: Y8 (59455247) 2032x1536 (stride 2048) buffer size 3145728 4 buffers requested. length: 3145728 offset: 0 timestamp type: unknown Buffer 0 mapped at address 0xb6b36000. length: 3145728 offset: 3145728 timestamp type: unknown Buffer 1 mapped at address 0xb6836000. length: 3145728 offset: 6291456 timestamp type: unknown Buffer 2 mapped at address 0xb6536000. length: 3145728 offset: 9437184 timestamp type: unknown Buffer 3 mapped at address 0xb6236000. Press enter to start capture root@overo2:~/yavta-HEAD-d9b7cfc# dmesg [0.00] Booting Linux on physical CPU 0 [0.00] Initializing cgroup subsys cpuset [0.00] Initializing cgroup subsys cpu [0.00] Linux version 3.5.0 (linuxentwickler@linuxentwickler-OEM) (gcc version 4.3.3 (GCC) ) #43 PREEMPT Mon Sep 9 11:53:31 CEST 2013 [0.00] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7d [0.00] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [0.00] Machine: Gumstix Overo [0.00] Reserving 12582912 bytes SDRAM for VRAM [0.00] Memory policy: ECC disabled, Data cache writeback [0.00] On node 0 totalpages: 53248 [0.00] free_area_init_node: node 0, pgdat c07159e4, node_mem_map c07af000 [0.00] Normal zone: 512 pages used for memmap [0.00] Normal zone: 0 pages reserved [0.00] Normal zone: 52736 pages, LIFO batch:15 [0.00] OMAP3630 ES1.2 (l2cache iva sgx neon isp 192mhz_clk ) [0.00] Clocking rate (Crystal/Core/MPU): 26.0/332/600 MHz [0.00] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768 [0.00] pcpu-alloc: [0] 0 [0.00] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 52736 [0.00] Kernel command line: mem=93M@0x8000 mem=128M@0x8800 console=ttyO2,115200n8 vram=12M omapfb.mode=dvi:1024x768MR-16@60 omapfb.debug=y omapdss.def_disp=dvi root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait [0.00] PID hash table entries: 1024 (order: 0, 4096 bytes) [0.00] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes) [0.00] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes) [0.00] allocated 524288 bytes of page_cgroup [0.00] please try 'cgroup_disable=memory' option if
Re: ov3640 sensor -> CCDC won't become idle!
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-218 (mobile) -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: ov3640 sensor -> CCDC won't become idle!
Peter Meerwald pmeerw.net> writes: Hello Peter, Many thanks for posting your solution. Your idea sounds great and I'll give it a try on next monday. Thanks again. Best Regards, Tom -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: ov3640 sensor -> CCDC won't become idle!
Hi Peter, On Friday 17 January 2014 15:45:22 Peter Meerwald wrote: > 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 The best solution would obviously be to find out why the OV3640 doesn't start correctly and fix that. However, I've tried pretty hard to do so in the past, and the lack of support from Omnivision (not mentioning the bad documentation quality) eventually made me give up. It thus believe it's reasonable to work around the problem on the OMAP3 ISP side. How to mainline this is a different issue. The patch below is a good start and might need a bit of clean up to make it more generic (by skipping a configurable amount of VSYNCs for instance, and making this configurable somehow). On the other hand I don't think we want to introduce the same feature to all the ISP drivers that could be used with the OV3640 sensor, and there might not be a compelling reason to treat the OMAP3 ISP driver in a special way. Sakari, could I ask you for your opinion ? > 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->o