AnsweredAssumed Answered

IPUv3 frame buffer question   (./driver/video/mxc/mxc_ipuv3_fb.c)

Question asked by jf simon on Nov 1, 2013
Latest reply on Nov 13, 2013 by Yixing Kong
Branched to a new discussion

Hi,

My platform is i.mx6 dual lite running Android JB. I have a HDMI screen connected to it.

Because I have a VSYNC problem under Android JB (logcat overflows screen with FBIO_WAITFORVSYNC errors) I am trying to understand how the IPUv3 frame buffer works.

I am familiar with linux framebuffers but there are parts I don't understand in the i.mx6 IPUv3 frame buffer, even after reading the IPUv3 chapter in the Reference manual, and also the linux BSP manual.

 

If I look at /sys/class/graphics on my card, I can see two nodes:

fb0

fb1

 

With following values:

 

# cat fb0/name                               

DISP3 BG

# cat fb0/fsl_disp_dev_property              

hdmi

# cat fb0/fsl_disp_property                  

2-layer-fb-bg


# cat fb1/name                               

DISP3 FG

# cat fb1/fsl_disp_dev_property              

overlay

# cat fb1/fsl_disp_property                  

2-layer-fb-fg

 

 

It looks as if, the HDMI screen uses the two fb0 and fb1 nodes for its usage. One being the foreground layer (fb0) and fb1 being the background layer.

My guess is that this is part of an anti-tearing strategy.

 

I have read that the IPU defines many channels to move data between memory, the display ports....

 

But I still do not understand the following snippets of code. The first one is the IOCTL VSYNC. Basically it says:

-If we are the foreground FB, then we look at the BG FB, for a reaon I don't get. Any idea?

 

The second one is the channel swapping code (swap_disp_chan() ). This code seems to be called when someone does an "echo <value> /sys/class/graphics/fsl_disp..."

Why would anyone want to switch channels? what is the  deal here?

...........................................................................................................................................

      case MXCFB_WAIT_FOR_VSYNC:

                {

                        if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {

                                /* BG should poweron */

                                struct mxcfb_info *bg_mxcfbi = NULL;

                                struct fb_info *fbi_tmp;

 

 

                                fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);

                                if (fbi_tmp)

                                        bg_mxcfbi = ((struct mxcfb_info *)(fbi_tmp->par));

 

                                if (!bg_mxcfbi) {

                                        retval = -EINVAL;

                                        break;

                                }

                                if (bg_mxcfbi->cur_blank != FB_BLANK_UNBLANK) {

                                        retval = -EINVAL;

                                        break;

                                }

                        }

                        if (mxc_fbi->cur_blank != FB_BLANK_UNBLANK) {

                                retval = -EINVAL;

                                break;

                        }  (snipped)

 

..................................................................................................................................

static ssize_t swap_disp_chan(struct device *dev,

                              struct device_attribute *attr,

                              const char *buf, size_t count)

{

        struct fb_info *info = dev_get_drvdata(dev);

        struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;

        struct mxcfb_info *fg_mxcfbi = NULL;

 

 

        console_lock();

        /* swap only happen between DP-BG and DC, while DP-FG disable */

        if (((mxcfbi->ipu_ch == MEM_BG_SYNC) &&

             (strstr(buf, "1-layer-fb") != NULL)) ||

            ((mxcfbi->ipu_ch == MEM_DC_SYNC) &&

             (strstr(buf, "2-layer-fb-bg") != NULL))) {

                struct fb_info *fbi_fg;

 

 

                fbi_fg = found_registered_fb(MEM_FG_SYNC, mxcfbi->ipu_id);

                if (fbi_fg)

                        fg_mxcfbi = (struct mxcfb_info *)fbi_fg->par;

 

 

                if (!fg_mxcfbi ||

                        fg_mxcfbi->cur_blank == FB_BLANK_UNBLANK) {

                        dev_err(dev,

                                "Can not switch while fb2(fb-fg) is on.\n");

                        console_unlock();

                        return count;

                }

 

 

                if (swap_channels(info) < 0)

                        dev_err(dev, "Swap display channel failed.\n");

        }

 

 

By the way, here is my kernel parameter line:

 

Kernel command line: androidboot.hardware=freescale enable_wait_mode=off console=ttymxc0,115200 vmalloc=400M consoleblank=0 video=mxcfb0:dev=hdmi,bpp=32,1280x720M@60,if=RGB24 video=mxcfb1:off video=mxcfb2:off fbmem=48M androidboot.hardware=freescale

 

If you have any information to share I will gladly take it.

Thanks so much

-jf simon

Outcomes