[Home] Exploring ISP and CCDC

Goal

Trace from a hardware CCDC register setting through the ISP / CCDC module, through the driver, through V4L2, right to the application interface.

This example traces from the hardware bit for interlace mode in the CCDC regisetrs.

Warning: this is just thought-jotting. Not well organized yet.

Register Names

The #defines in the kernel are very nearly 1:1 mapped with the documentation in the TRM (spruf98g).

For example: CCDC_SYN_MODE[7] FLDMODE in the TRM is ISPCCDC_SYN_MODE_FLDMODE in the kernel. Almost exactly the same.

My general rule is to grep the most unique part of the name in question from the root of the kernel directory.

For example: grep FLDMODE -R ./

Interlaced Mode

The device is running in interlace mode even with CCDC_SYN_MODE[7] FLDMODE set to 0. Tracing...

Where is interlace mode set?

grep FLDMODE -R ./ shows

it is defined in ./drivers/media/video/isp/ispreg.h

#define ISPCCDC_SYN_MODE_FLDMODE (1 << 7)

and used in ./drivers/media/video/isp/ispccdc.c

if (syncif.fldmode)
  syn_mode |= ISPCCDC_SYN_MODE_FLDMODE;
else
  syn_mode &= ~ISPCCDC_SYN_MODE_FLDMODE;

What is syn_mode?

It appears to be the value as read from the 32-bit isp register

u32 syn_mode = isp_reg_readl(isp_ccdc->dev, OMAP3_ISP_IOMEM_CCDC,
           ISPCCDC_SYN_MODE);

What values it is set to depend heavily upon syncif (of type ispccdc_syncif) and then it is written back to the register.

What is syncif?

A struct defined in ./drivers/media/video/isp/ispccdc.h

It is set according to pipe->ccdc_in, which is an enum used to describe a format such as CCDC_RAW_GBRG (in the same file).

If the value is CCDC_OTHERS, syncif is not set, which means that the values already in the register stay in the register?

Not necessarily; since the ISP only knows about certain CCDC_XXX_XXXX formats it will unset certain registers for all CCDC_OTHERS formats.

However, it appears that CCDC_OTHERS and DAT12 are reserved for future use. CCDC_OTHERS isn't handled in isp_try_pipeline.

Where does pipe->ccdc_in come from?

It is of type isp_pipeline and the ccdc_in comes from ./drivers/media/video/isp/isp.c

It is determined by pix_input->pixelformat

What's the deal with pix_input->pixelformat?

It's a V4L format, such as V4L2_PIX_FMT_UYVY, as set in ./drivers/media/video/your_driver_here.c

The formats supported by the OMAP ISP are defined in ./drivers/media/video/isp/isp.c.

Where would I define it in ./drivers/media/video/your_driver_here.c

hmm... various places... I don't understand this stack well enough to say yet...

Where would I find these V4L2_PIX_FMT_XXX?

./include/linux/videodev2.h

And, fancy this - Documentation: ./Documentation/DocBook/v4l/videodev2.h.xml

How would I create my own V4L2_PIX_FMT_XXX?

In ./include/linux/videodev2.h there's a special place for that

/*  Vendor-specific formats   */
#define V4L2_PIX_FMT_CUSTOM v4l2_fourcc('C','F','M','T') // Arbitrary 4-characters which must be unique among V4L defines

For quick reference: V4L2_PIX_FMT_XXX is a u32

/*  Four-character-code (FOURCC) */
#define v4l2_fourcc(a, b, c, d)\
  ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24))

How is pipe->modules determined?

modules is an |d register including things like resizer and preview. In fact, I believe those are the only two modules to date.

Updated at 2010-08-05
blog comments powered by Disqus