Vim3l ov5640 sensor bringup help needed

Hi,
I am working on bring up of camera OV5640 with the following system setup.
Board : VIM3L
OS : Debian10 (Build by fenix)
Kernel : 4.9

I could probe camera and faced issue https://forum.khadas.com/t/vim3-a311d-with-gc2145-camera/11445?u=kd_1993.
I solved this issue by using direct memory allocation instead of using function vm_init_resource.
Now I can read setting using v4l2-ctl -d /dev/video0 -all but when try to capture the picture it sink too much memory and gstreamer pipeline killed by out of memory killer.

Can you provide some pointers related to this?

Also, While deselect ANDROID option from kernel-config, facing issues in compilation. Is there any possibility of any issue due to this option selection and not using android on Khadas VIM3L?

[EDIT] - to resolve error of CMA I have applied patch as per attached as a alternative into vmalloc.

diff --git a/drivers/amlogic/media/camera/ov5640.c b/drivers/amlogic/media/camera/ov5640.c
index e58387a5..29d202ba 100644
--- a/drivers/amlogic/media/camera/ov5640.c
+++ b/drivers/amlogic/media/camera/ov5640.c
@@ -38,6 +38,7 @@
 #include <linux/highmem.h>
 #include <linux/freezer.h>
 #include <linux/amlogic/media/v4l_util/videobuf-res.h>
+#include <media/videobuf-vmalloc.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #ifdef CONFIG_HAS_WAKELOCK
@@ -2192,8 +2193,13 @@ static void ov5640_fillbuff(struct ov5640_fh *fh, struct ov5640_buffer *buf)
 {
 	int ret;
 	struct ov5640_device *dev = fh->dev;
-	void *vbuf = (void *)videobuf_to_res(&buf->vb);
+	void *vbuf; 
 	struct vm_output_para para = {0};
+	if (dev->vminfo.mem_alloc_succeed)
+		vbuf = (void *)videobuf_to_res(&buf->vb);
+	else
+		vbuf = videobuf_to_vmalloc(&buf->vb);
+
 
 	dprintk(dev, 1, "%s\n", __func__);
 	if (!vbuf)
@@ -2267,6 +2273,26 @@ static void ov5640_thread_tick(struct ov5640_fh *fh)
 	spin_unlock_irqrestore(&dev->slock, flags);
 }
 
+static void free_vmall_buffer(struct videobuf_queue *vq,
+			      struct ov5640_buffer *buf)
+{
+	struct ov5640_fh *fh;
+	//struct ov5640_device *dev;
+
+	fh = vq->priv_data;
+
+	printk( "%s, state: %i\n", __func__, buf->vb.state);
+
+	videobuf_waiton(vq, &buf->vb, 0, 0);
+	if (in_interrupt())
+		WARN_ON(1);
+	videobuf_vmalloc_free(&buf->vb);
+	printk("free_vmall_buffer: freed\n");
+	buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+
+
 static void ov5640_sleep(struct ov5640_fh *fh)
 {
 	struct ov5640_device *dev = fh->dev;
@@ -2345,6 +2371,106 @@ static void ov5640_stop_thread(struct ov5640_dmaqueue  *dma_q)
 	}
 }
 
+static int
+vmall_buffer_setup(struct videobuf_queue *vq, unsigned int *count,
+		   unsigned int *size)
+{
+	struct ov5640_fh  *fh = vq->priv_data;
+	struct ov5640_device *dev  = fh->dev;
+	/* int bytes = fh->fmt->depth >> 3 ; */
+	*size = (fh->width * fh->height * fh->fmt->depth) >> 3;
+	if (*count == 0)
+		*count = 32;
+
+	while (*size * *count > vid_limit * 1024 * 1024)
+		(*count)--;
+
+	dprintk(dev, 1, "%s, count=%d, size=%d\n", __func__,
+		*count, *size);
+
+	return 0;
+}
+
+#define norm_maxw() 1920
+#define norm_maxh() 1600
+static int
+vmall_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+		     enum v4l2_field field)
+{
+	struct ov5640_fh *fh;
+	struct ov5640_device *dev;
+	struct ov5640_buffer *buf;
+	int rc;
+
+	fh  = vq->priv_data;
+	dev = fh->dev;
+	buf = container_of(vb, struct ov5640_buffer, vb);
+	/* int bytes = fh->fmt->depth >> 3 ; */
+	dprintk(dev, 1, "%s, field=%d\n", __func__, field);
+
+	WARN_ON(fh->fmt == NULL);
+
+	if (fh->width  < 48 || fh->width  > norm_maxw() ||
+	    fh->height < 32 || fh->height > norm_maxh())
+		return -EINVAL;
+
+	buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
+	if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size)
+		return -EINVAL;
+
+	/* These properties only change when queue is idle, see s_fmt */
+	buf->fmt       = fh->fmt;
+	buf->vb.width  = fh->width;
+	buf->vb.height = fh->height;
+	buf->vb.field  = field;
+
+	/* precalculate_bars(fh); */
+
+	if (buf->vb.state == VIDEOBUF_NEEDS_INIT) {
+		rc = videobuf_iolock(vq, &buf->vb, NULL);
+		if (rc < 0)
+			goto fail;
+	}
+
+	buf->vb.state = VIDEOBUF_PREPARED;
+
+	return 0;
+
+fail:
+	free_vmall_buffer(vq, buf);
+	return rc;
+}
+
+static void
+vmall_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct ov5640_fh *fh;
+	struct ov5640_device *dev;
+	struct ov5640_dmaqueue *vidq;
+	struct ov5640_buffer *buf  = container_of(vb, struct ov5640_buffer, vb);
+
+	fh = vq->priv_data;
+	dev = fh->dev;
+	vidq = &dev->vidq;
+
+	dprintk(dev, 1, "%s\n", __func__);
+	buf->vb.state = VIDEOBUF_QUEUED;
+	list_add_tail(&buf->vb.queue, &vidq->active);
+}
+
+static void vmall_buffer_release(struct videobuf_queue *vq,
+				 struct videobuf_buffer *vb)
+{
+	struct ov5460_fh *fh;
+	struct ov5640_buffer  *buf  =
+		container_of(vb, struct ov5640_buffer, vb);
+	fh   = vq->priv_data;
+
+	printk("%s\n", __func__);
+
+	free_vmall_buffer(vq, buf);
+}
+
 static int
 buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
 {
@@ -2385,8 +2511,8 @@ static void free_buffer(struct videobuf_queue *vq, struct ov5640_buffer *buf)
 	buf->vb.state = VIDEOBUF_NEEDS_INIT;
 }
 
-#define norm_maxw() 3000
-#define norm_maxh() 3000
+//#define norm_maxw() 3000
+//#define norm_maxh() 3000
 static int
 buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
 		enum v4l2_field field)
@@ -2458,6 +2584,14 @@ static void buffer_release(struct videobuf_queue *vq,
 	free_buffer(vq, buf);
 }
 
+
+static struct videobuf_queue_ops ov5640_video_vmall_qops = {
+	.buf_setup      = vmall_buffer_setup,
+	.buf_prepare    = vmall_buffer_prepare,
+	.buf_queue      = vmall_buffer_queue,
+	.buf_release    = vmall_buffer_release,
+};
+
 static struct videobuf_queue_ops ov5640_video_qops = {
 	.buf_setup      = buffer_setup,
 	.buf_prepare    = buffer_prepare,
@@ -2470,7 +2604,7 @@ static int vidioc_querycap(struct file *file, void  *priv,
 {
 	struct ov5640_fh  *fh  = priv;
 	struct ov5640_device *dev = fh->dev;
-
 	strcpy(cap->driver, "ov5640");
 	strcpy(cap->card, "ov5640.canvas");
 	if (dev->cam_info.front_back == 0)
@@ -2507,6 +2641,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 {
 	struct ov5640_fh *fh = priv;

 	pr_info("%s, fh->width =%d,fh->height=%d\n",
 		__func__, fh->width, fh->height);
 	f->fmt.pix.width        = fh->width;
@@ -2595,6 +2730,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 	int ret;
 	int cap_fps, pre_fps;

 	f->fmt.pix.width = (f->fmt.pix.width + (CANVAS_WIDTH_ALIGN - 1)) &
 		(~(CANVAS_WIDTH_ALIGN - 1));
 	if ((f->fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) ||
@@ -2669,6 +2805,7 @@ static int vidioc_g_parm(struct file *file, void *priv,
 	struct ov5640_device *dev = fh->dev;
 	struct v4l2_captureparm *cp = &parms->parm.capture;

 	dprintk(dev, 3, "vidioc_g_parm\n");
 	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -3005,26 +3142,30 @@ static int ov5640_open(struct file *file)
 	struct ov5640_fh *fh = NULL;
 	int retval = 0;
 
 	dev->vminfo.vdin_id = dev->cam_info.vdin_path;
 	dev->vminfo.bt_path_count = dev->cam_info.bt_path_count;
 
 #ifdef CONFIG_CMA
-	retval = vm_init_resource(24 * SZ_1M, &dev->vminfo);
-	if (retval < 0) {
-		pr_err("error: no cma memory\n");
-		return -1;
-	}
+	dev->vminfo.mem_alloc_succeed = false;
+	//vm_init_resource(24 * SZ_1M, &dev->vminfo);
 #endif
 	mutex_lock(&firmware_mutex);
 	ov5640_have_opened = 1;
 	mutex_unlock(&firmware_mutex);

 	aml_cam_init(&dev->cam_info);
 	OV5640_init_regs(dev);
 
 	msleep(20);
 
 	mutex_lock(&dev->mutex);
 	dev->users++;
 	if (dev->users > 1) {
@@ -3033,12 +3174,16 @@ static int ov5640_open(struct file *file)
 		return -EBUSY;
 	}
 
 	dprintk(dev, 1, "open %s type=%s users=%d\n",
 		video_device_node_name(dev->vdev),
 		v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);

 	INIT_LIST_HEAD(&dev->vidq.active);
 	init_waitqueue_head(&dev->vidq.wq);
 	spin_lock_init(&dev->slock);
 
 	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
@@ -3048,9 +3193,11 @@ static int ov5640_open(struct file *file)
 	}
 	mutex_unlock(&dev->mutex);
 
 	if (retval)
 		return retval;
 
 #ifdef CONFIG_HAS_WAKELOCK
 	wake_lock(&(dev->wake_lock));
 #endif
@@ -3067,19 +3214,31 @@ static int ov5640_open(struct file *file)
 
 	dev->jiffies = jiffies;
 

 	if (dev->vminfo.mem_alloc_succeed) {
 		fh->res.start = dev->vminfo.buffer_start;
 		fh->res.end = dev->vminfo.buffer_start +
 						dev->vminfo.vm_buf_size - 1;
 		fh->res.magic = MAGIC_RE_MEM;
 		fh->res.priv = NULL;
 		videobuf_queue_res_init(&fh->vb_vidq, &ov5640_video_qops,
 						NULL, &dev->slock, fh->type,
 						V4L2_FIELD_INTERLACED,
 						sizeof(struct ov5640_buffer),
 						(void *)&fh->res, NULL);
+	} else {
+		videobuf_queue_vmalloc_init(&fh->vb_vidq,
+				&ov5640_video_vmall_qops, NULL,
+				&dev->slock, fh->type,
+				V4L2_FIELD_INTERLACED,
+				sizeof(struct ov5640_buffer), fh, NULL);
+
 	}
 
 	bDoingAutoFocusMode = false;
 	ov5640_start_thread(fh);
 	return 0;
@@ -3244,13 +3403,15 @@ static int ov5640_probe(struct i2c_client *client,
 	int ret;
 	struct ov5640_device *t;
 	struct v4l2_subdev *sd;
-
+	
 	vops = get_vdin_v4l2_ops();
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 		client->addr << 1, client->adapter->name);
 	t = kzalloc(sizeof(*t), GFP_KERNEL);
 	if (t == NULL) {
 		pr_err("ov5640 probe kzalloc failed.\n");
 		return -ENOMEM;
 	}
 
@@ -3260,6 +3421,7 @@ static int ov5640_probe(struct i2c_client *client,
 	ret = v4l2_device_register(NULL, &t->v4l2_dev);
 	if (ret) {
 		pr_info("%s, v4l2 device register failed", __func__);
 		kfree(t);
 		return ret;
 	}
@@ -3271,6 +3433,7 @@ static int ov5640_probe(struct i2c_client *client,
 
 	t->vdev = video_device_alloc();
 	if (t->vdev == NULL) {
 		kfree(t);
 		return -ENOMEM;
 	}
@@ -3278,6 +3441,7 @@ static int ov5640_probe(struct i2c_client *client,
 	t->vdev->v4l2_dev = &t->v4l2_dev;
 	video_set_drvdata(t->vdev, t);
 
 #ifdef CONFIG_HAS_WAKELOCK
 	wake_lock_init(&(t->wake_lock), WAKE_LOCK_SUSPEND, "ov5640");
 #endif
@@ -3285,16 +3449,19 @@ static int ov5640_probe(struct i2c_client *client,
 	plat_dat = (struct aml_cam_info_s *)client->dev.platform_data;
 	if (plat_dat) {
 		memcpy(&t->cam_info, plat_dat, sizeof(struct aml_cam_info_s));
 		pr_info("%s, front_back = %d\n",
 			__func__, plat_dat->front_back);
 		video_nr = plat_dat->front_back;
 	} else {
 		pr_err("camera ov5640: have no platform data\n");
 		video_device_release(t->vdev);
 		kfree(t);
 		return -1;
 	}
 
 	t->cam_info.version = OV5640_DRIVER_VERSION;
 	if (aml_cam_info_reg(&t->cam_info) < 0)
 		pr_err("reg caminfo error\n");
@@ -3302,12 +3469,14 @@ static int ov5640_probe(struct i2c_client *client,
 	pr_info("t->vdev = %p, video_nr = %d\n", t->vdev, video_nr);
 	err = video_register_device(t->vdev, VFL_TYPE_GRABBER, video_nr);
 	if (err < 0) {
 		video_device_release(t->vdev);
 		kfree(t);
 		return err;
 	}
 
 	pr_info("ov5640_probe successful.\n");
 
 	return 0;
 }

Update from my side:
Now i can capture image using OV5640 but image is too bad and facing repeated data issue in raw frame data.

Command to capture

v4l2-ctl --device /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=YUV --stream-mmap --stream-to=frame.raw --stream-count=1

The frame is attached.

Below are the dmesg logs,


[   52.738645] DEBUG ov5640_open.
[   52.738656] DEBUG OPEN : vm_init_resource, 2091, info->vdin_id : 0
[   52.738660] DEBUG OPEN : vm_init_resource, 2109
[   52.738665] DEBUG OPEN : dma_alloc_from_contiguous, 193, align = 0, count = 6144
[   52.738668] DEBUG OPEN : dma_alloc_from_contiguous, 197, align = 0, count = 6144
[   52.738673] cma: cma_alloc(cma ffffff800ad272e8, count 6144, align 0)
[   52.761854] cma: cma_alloc(): returned ffffffbf01570000
[   52.761865] DEBUG OPEN : vm_init_resource, 2119
[   52.761868] DEBUG OPEN : vm_init_resource, 2123
[   52.761871] DEBUG OPEN : vm_init_resource, 2125
[   52.761875] DEBUG OPEN : vm_init_resource, 2137
[   52.762011] DEBUG : clk_rate : 24000000 
[   52.902032] aml_cams: ov5640 init OK
[   52.942703] OV5640_init_regs-success in initial OV5640
[   52.970141] DEBUG ov5640_open-3446 Open compelte 
[   52.970242] res_para->size_type = 19, res_param->frmsize.width = 1920, height = 1080
[   53.004233] setting resolutin param complete
[   53.005036] DEBUG vidioc_streamon-3101
[   53.005044] vidioc_streamon: h_active=1920; v_active=1080, frame_rate=30,vdin_path=0
[   53.005047] DEBUG ov5640 stream on.
[   53.005052] ov5640 start tvin service.
[   53.005056] **[start_tvin_service]cfmt:1;dfmt:1;dest_hactive:0;
[   53.005060] dest_vactive:0;frame_rate:30;h_active:1920,
[   53.005063] v_active:1080;scan_mode:1**
[   53.005338] settle = 0x001a
[   53.005343] info->lanes = 2
[   53.005457] DEBUG : vdin_start_dec, 471, vdin_dbg_en : 1
[   53.005460] DEBUG : vdin_start_dec, 478
[   53.005464] devp->para.cfmt=1, devp->para.dfmt=1
[   53.005467] DEBUG : vdin_start_dec, 504
[   53.005471] DEBUG : vdin_start_dec, 514
[   53.005480] DEBUG : vdin_start_dec, 521
[   53.005485] DEBUG : vdin_start_dec, 545
[   53.005489] DEBUG : vdin_start_dec, 550
[   53.005492] DEBUG : vdin_start_dec, 555
[   53.005496] vdin0 init afbce_mode: 0
[   53.005499] DEBUG : vdin_start_dec, 563
[   53.005502] DEBUG : vdin_start_dec,566
[   53.005507] DEBUG OPEN : dma_alloc_from_contiguous, 193, align = 0, count = 16384
[   53.005511] DEBUG OPEN : dma_alloc_from_contiguous, 197, align = 0, count = 16384
[   53.005515] cma: cma_alloc(cma ffffff800ad27238, count 16384, align 0)
[   53.050788] cma: cma_alloc(): returned ffffffbf016f0000
[   53.050798] vdin0 mem_start = 0x5bc00000, mem_size = 0x1db1000
[   53.050801] vdin0 cma alloc ok!
[   53.050805] DEBUG : vdin_start_dec, 574
[   53.050819] DEBUG : vdin_start_dec, 586
[   53.050833] vdin_game_mode_check: game_mode flag=0, game_mode=0
[   53.050837] vdin.0 vframe initial information table: (5 of 9)
[   53.050844] 	 0: 0x26 1920x1080, duration = 3200
[   53.050849] 	 1: 0x27 1920x1080, duration = 3200
[   53.050853] 	 2: 0x28 1920x1080, duration = 3200
[   53.050857] 	 3: 0x29 1920x1080, duration = 3200
[   53.050861] 	 4: 0x2a 1920x1080, duration = 3200
[   53.050864] DEBUG : vdin_start_dec, 616
[   53.050867] DEBUG : vdin_start_dec, 626
[   53.050873] DEBUG : vdin_start_dec, 634
[   53.050891] DEBUG : vdin_start_dec, 639
[   53.050895] start_amvdec_csi.
[   53.050898] start_amvdec_csi port = 10000
[   53.050901] init_csi_dec_parameter.
[   53.050904] reinit_csi_dec, 80
[   53.050908] DEBUG : vdin_start_dec, 649
[   53.051049] DEBUG : vdin_start_dec, 673
[   53.051053] ****[vdin_start_dec]ok!****
[   53.051056] DEBUG : vdin_start_dec, 692
[   53.051059] DEBUG : vdin_start_dec, 698
[   53.057996] DEBUG CAM: vm_fill_this_buffer, 927
[   53.058003] DEBUG CAM: vm_fill_this_buffer, 934
[   53.058006] DEBUG CAM: vm_fill_this_buffer, 949
[   53.058010] DEBUG CAM: vm_fill_this_buffer, 956
[   53.058013] DEBUG CAM: vm_fill_this_buffer, 959
[   53.058016] DEBUG CAM: vm_fill_this_buffer, 972
[   53.058019] DEBUG CAM: vm_fill_this_buffer, 982
[   53.058027] DEBUG CAM: vm_fill_this_buffer, 1013
[   53.063669] DEBUG CAM: vm_fill_this_buffer, 1029
[   53.063677] DEBUG CAM: vm_fill_this_buffer, 1035
[   53.070051] DEBUG CAM: vm_fill_this_buffer, 927
[   53.070058] DEBUG CAM: vm_fill_this_buffer, 934
[   53.070061] DEBUG CAM: vm_fill_this_buffer, 949
[   53.070064] DEBUG CAM: vm_fill_this_buffer, 956
[   53.070067] DEBUG CAM: vm_fill_this_buffer, 959
[   53.070070] DEBUG CAM: vm_fill_this_buffer, 972
[   53.070073] DEBUG CAM: vm_fill_this_buffer, 982
[   53.070081] DEBUG CAM: vm_fill_this_buffer, 1013
[   53.075736] DEBUG CAM: vm_fill_this_buffer, 1029
[   53.075744] DEBUG CAM: vm_fill_this_buffer, 1035
[   53.080450] DEBUG ov5640 stream off.
[   53.080466] DEBUG : vdin_stop_dec, 716
[   53.080472] reset_btcsi_module, 75
[   53.080556] cma: cma_release(page ffffffbf016f0000)
[   53.081079] vdin0 cma release ok!
[   53.081091] vdin_stop_dec ok
[   53.081689] aml_cams: ov5640 uninit.
[   53.133982] Success disable mclk
[   53.133991] cma: cma_release(page ffffffbf01570000)
[   53.134182] DEBUG ov5640_close-3528 Close compelte 

Also wanted to understand if I can generate test pattern in CSI or CSI decoder ?

Any help will be appreciated.

Update from my side,

This seems to capture vim3l connected HDMI display’s screen,
Surprisingly its c screen capture/screenshot mode.

Also my dts file has diffrenet node here in cam_0 as per below for ov5640 sensor,

   cam_0{
           cam_name = "ov5640";
           front_back = <0>;
           camera-i2c-bus = <&i2c_AO>;
           gpio_pwdn-gpios = <&gpio_expander 3 GPIO_ACTIVE_HIGH>;
           gpio_rst-gpios = <&gpio_expander 2 GPIO_ACTIVE_HIGH>;
           mirror_flip = <1>;
           vertical_flip = <0>;
           spread_spectrum = <0>;
           bt_path = "csi";
           interface = "mipi";
           vdin_path = <0>;
           clk_channel = "a";
           bt_path_count = <1>;
           status = "okay";
   };

@numbqq can you help or tag someone from khadas team to help ?

Really appreciate

Sorry, I don’t have much experience about OV5640 on VIM3L, so you have to debug youself.
As the isp driver from Ubuntu linux kernel is not latest, maybe you can try to sync latest driver from Android source code to check.

Hi @numbqq,

Thanks for reply.

As VIM3L, there is no ISP, do we still need ISP driver from the mentioned source ?

Can you help me with the link from where can i get it ?

Also I have seen many camera forums is being addressed by @Gouwa, @chewitt, @Spikerguy, @Electr1 and @Frank , So I would like to ask them as well for any pointers.

  1. I am also getting confused in DTS between sensor(vim3) node,
	sensor: sensor {
		compatible = "soc, sensor";
                .............
	};

and cam_X node (vim3l) being on a same BSP.

aml_cams {
         compatible = "amlogic, cams_prober";
         ............
          cam_0{
                  cam_name = "ov5640";
                  .......
            };
    };
  1. After adding cam_X node and enabling ov5640 , why i am seeing screen shot and not the capture image ?

目前 我也需要再VIM3L调试camera 以下是我理解:
1.S905D3不内置ISP模块,需要sensor自带ISP模块,所以camera底层不能走vendor arm_isp驱动,走cams_prober + amvdec_csi框架;,同时I2C配置ISP模块。
2.数据格式。OV5640是支持YUV RGB等格式,S905D3 CSI采集支持哪些格式?从以下寄存器看是支持YUV RGB采集的。

3.A311D 模块CSI data path: CSI DPHY–>mipi adapter,S905D3 手册没有这块的介绍。从代码来看
vidioc_streamon -->start_tvin_service会调用VDIN模块,data path是 CSI DPHY->VDIN?

不知道我的理解是否正确 @ KD_1993 @numbqq

2 Likes

@seekdream1990 , It seems you and I are having same assumptions.
We have two different kind of frameworks for Camera.

  1. Framework with ISP - soc sensor :
  • This framework seems like it can work with only VIM3 and we can not use it with VIM3L. Here we have many registers which are not present in Amlogic S905D3.
  • The framework is not as per v4l2 complaint.
    I.e stream-on IOCTL is not bind with v4l2_ioctl_ops, can not see videobuffer events like VIDEOBUF_DONE
  • In s905d3 in video path, video path is provided and have different register sets for mipi adapter, I believe they want developer to assume how hardware will work.
  1. Framework without ISP - cam prober :
  • Here in (as you mentioned ) streamon I could see starting csi but not from hardware level , no hardware registers are being written,
  • No communication seems to be happening between sensor and CSI
  • Getting ISR in decoder but nothing from CSI (because nobody told him to do his job via register writing) hence may be I am getting wrong information in frames and seeing own screenshot.

I may be wrong on these but currently it seems so.

Gc2145摄像头显示花屏,如何确定问题, here is also same thing happening (of course in android ),

At the end of the story, lack of documentation and proper implementations is making people suffer.

What bothering me is, this is going to be our production board and not the hobby board, but this lack of support from community, documentation and other relevant thing is not helping us.

Khadas team, @numbqq , @Frank @Gouwa , at least provide some pointers, we are not asking you to develop for us. lets try to make a batter world by helping each other.

Thanking you in anticipation.

1.关于S905D3 sensor与CSI mipi的通信疑问:
实际上,在对应sensor的驱动中(例如ov5640),打开camera后vidioc_streamon 接口会调用VDIN驱动模块的start_tvin_service,最终通过amcsi_feopen–>am_mipi_csi2_init(该接口最终配置adapter以及PHY寄存器配置)。但是VDIN模块与sensor的关系还是有些不明白的地方,就如上面所说,难道data数据patch:
CSI DPHY->VDIN

@ KD_1993

Hi @seekdream1990

I agree on this.

Moving forward, from vdin after start_tvin_service, it is registering in vdin_v4l2_isr for mipi port. sometime in future from vdin_v4l2_isr will call decoder_isr and in decoder_isr, it seems to it read the frame infos in amcsi_isr (afifo).

In my case
amcsi_isr, data1- 0x00, frame.w-0, frame.h -0,ddr_address:0x0, index:0, status-0, read_cnt-0

everything is zero.

I suspect, here i should get a frame or at least its height width and other information.

However as you rightly mentioned, I also dont see a way to pass this info to vdin.

@numbqq , at least can we check for any missing patch from amlogic repo for this ?

For Android source has latest drivers & patches. For Ubuntu source code we only test our camera module OS08A10 on VIM3, we haven’t checked other camera modules. So for new camera bringup, you can use android.

@numbqq
I have already asked for the link. kindly provide it ASAP.

@numbqq
Thanks for the link.

I had clone the android source immediately. But, I can not find csi driver, dts of vim3L, registers of MIPI(i.e. MIPI_PHY_CLK_LANE_CTRL) in branch khadas_vims_pie and naught.

Can you guide where to find them?

Dear @numbqq ,

This situation forced us to move from vim3l to vim3, but at least on that do we see ov5640 running with vim3 with ISP with some sort of modification ?

Do khadas team has proper documentation on vim3 ?

Definitely development is our responsibility but as this is “non v4l2 compliant”, we may need your pointers in moving further with vim3.

Also I hope that there not any closed source blobs running under the hood for ISP under GPL licensing ?

Kindly share your inputs, we have spent lot financial efforts till now, for us its now a crucial moment.

We don’t have OV5640 module, so we don’t know the status on VIM3, we only tested OS08A10 on VIM3.

There is no documentation for this, all the documentation is the source code.

from compatible

amlogic, amvdec_csi
from
image

I dont see any entries which mean still no CSI driver present
image

My grep result

I can see it in arm, i believe our arch is arm64, I assume we can modify this as a reference in arch64 but still CSI driver is a question ?

Also I will be able and glad to ship one ov5640 with custom made connector especially for Khadas board, in hope of getting at least some sort of help pointers.(of course with proper NDA and documentation in place )

Android use the 32bit kernel.

@numbqq , and what about csi driver ?

How compatible is going to probe csi drver from amlogic, amvdec_csi ?