We used linux5.4.3 environment on imx8m mini soc to collect the data of TOF chip in RAW12 format. Now we have successfully obtained the data and parsed it into grayscale images, but the displayed images are abnormal. The whole picture is divided into four parts, and each part shows similar pictures. See the attachment for specific effects.
In order to achieve the imx8m mini support for RAW12 I have modified the "Linux/drivers/media/platform/MXC/capture/mx6s_capture.c, Linux/drivers/media/platform/MXC/capture/mxc_mipi_csi.c "two files and add tof camera driver, modify specific content see attachment. At the same time, using the test mode of tof camera, we found that soc processed the data returned by tof, that is, soc moved the 12 bits of data returned by tof 2 bits to the left, and then took the lower 8 bits of data, and the higher 8 bits of data would be equal to the lower 8 bits of data. such as tof: 0x266 -->soc:0x9999. May I ask how I should deal with this problem? Looking forward to your reply.
imx8mm can capture raw data, but couldn't handle it directly, how did you transfer raw data to the display?
is it the interlaced data from your camera? could you dump the mipi csi and csi registers with me? and send the logfile to me when you test the camera
I solved the problem of the screen being divided into 4 parts, but now we have found a new problem, normally raw12 storage takes 2 bytes and the high 4 bits are 0, but the data [12:15] we get at the application layer is not 0 bit and the data is changing. I checked the csi RXFIFO content and found that he was correct.
csi configuration
how did you fix your previous issue about 4 parts?
I checked your CSICR3 register, try to enable bit3 SENSOR_16BITS
For the Part 4 problem, I solved it by setting the PIXEL BIT
I set SENSOR_16BITS, but the final result didn't change .
static void mx6s_csi_frame_done(struct mx6s_csi_dev *csi_dev,
int bufnum, bool err)
{
struct mx6s_buf_internal *ibuf;
struct mx6s_buffer *buf;
struct vb2_buffer *vb;
unsigned long phys;
unsigned int phys_fb1;
unsigned int phys_fb2;
uint8_t *pmen;
ibuf = list_first_entry(&csi_dev->active_bufs, struct mx6s_buf_internal,
queue);
if (ibuf->discard) {
/*
* Discard buffer must not be returned to user space.
* Just return it to the discard queue.
*/
list_move_tail(csi_dev->active_bufs.next, &csi_dev->discard);
} else {
buf = mx6s_ibuf_to_buf(ibuf);
vb = &buf->vb.vb2_buf;
phys = vb2_dma_contig_plane_dma_addr(vb, 0);
if (bufnum == 1) {
phys_fb2 = csi_read(csi_dev, CSI_CSIDMASA_FB2);
if (phys_fb2 != (u32)phys) {
dev_err(csi_dev->dev, "%lx != %x\n", phys,
phys_fb2);
}
} else {
phys_fb1 = csi_read(csi_dev, CSI_CSIDMASA_FB1);
if (phys_fb1 != (u32)phys) {
dev_err(csi_dev->dev, "%lx != %x\n", phys,
phys_fb1);
}
}
dev_dbg(csi_dev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__, vb,
vb2_plane_vaddr(vb, 0),
vb2_get_plane_payload(vb, 0));
pmen=vb2_plane_vaddr(vb, 0);
dev_dbg(csi_dev->dev, "addr=0x%p 0x%08x\n",pmen ,__raw_readl(pmen));
dev_dbg(csi_dev->dev, "phys1 addr=0x%p \n",phys);
list_del_init(&buf->internal.queue);
vb->timestamp =ktime_get_ns();
to_vb2_v4l2_buffer(vb)->sequence = csi_dev->frame_count;
if (err)
vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
else
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
}
csi_dev->frame_count++;
csi_dev->nextfb = (bufnum == 0 ? 1 : 0);
/* Config discard buffer to active_bufs */
if (list_empty(&csi_dev->capture)) {
if (list_empty(&csi_dev->discard)) {
dev_warn(csi_dev->dev,
"%s: trying to access empty discard list\n",
__func__);
return;
}
ibuf = list_first_entry(&csi_dev->discard,
struct mx6s_buf_internal, queue);
ibuf->bufnum = bufnum;
list_move_tail(csi_dev->discard.next, &csi_dev->active_bufs);
mx6s_update_csi_buf(csi_dev,
csi_dev->discard_buffer_dma, bufnum);
return;
}
buf = list_first_entry(&csi_dev->capture, struct mx6s_buffer,
internal.queue);
buf->internal.bufnum = bufnum;
list_move_tail(csi_dev->capture.next, &csi_dev->active_bufs);
vb = &buf->vb.vb2_buf;
vb->state = VB2_BUF_STATE_ACTIVE;
phys = vb2_dma_contig_plane_dma_addr(vb, 0);
mx6s_update_csi_buf(csi_dev, phys, bufnum);
}
At the same time I did some other checks that the data received at the application layer was correct when the tof sensor was in test mode (the transmission data was fixed). However, if it is switched to the normal mode, there will be anomalies in the data received at the application layer. Specific anomalies are as I described before. I think the possibility of error of tof sensor can be eliminated, because the data received in RXFIFO is correct. I initially thought there might be a problem with synchronization after the DMA transfer, but now I can't figure out the reason. I hope you can give us a good method.
let me remind, bit SENSOR_16BITS in RM, in driver, the name is TWO_8BIT_SENSOR
I checked your mx6s_capture.c, you should used gated clock mode, but refer to the register, you set GCLK_MODE to 0, so your dump registers are all correct or did you changed the mx6s_capture after you send the patch?
I checked your mx6s_capture.c, you should used gated clock mode, but refer to the register, you set GCLK_MODE to 0, so your dump registers are all correct or did you changed the mx6s_capture after you send the patch?
test mode (the transmission data was fixed)
> what about test mode? do you mean that each frame has the same data?
as you mentioned before, higher 4bits doesn't correct, are they random or shift data? I mean could you know where are the higher 4bits from?
I checked your status register, why didn't your board detect SOF or EOF? after you enable SENSOR_16BITS, nothing different? if this is sync issue, you shouldn't get correct data from CSI, I checked the sync related register, it seems they are ok, did you check your application?
I have checked why the high 4 bits are not 0. The reason is that there is a problem in the analysis of our software. After changing the analysis software, the data is normal. But now we have a new problem, which is that each PIXEL is 12 bits, but I set the PIXEL BIT to 1 to solve the problem of splitting the image into 4 parts, so we only get 10 bits of data. I would like to know how to configure csi to receive 12bit RAW12 data.
how about change BIT_PIXEL_BIT to 0 and enable SENSOR_16BITS?