> I have not tried this, but you might be able to use FBIOPAN_DISPLAY ioctl.
Unfortunately, it's not going to work in the 3.14 BSP. While we used the same driver that was in 3.8.13, I #defined out a lot of code because it was using the "output image generator" for the finally display layer, including support for things like FBIOPUT_FRAME and FBIOPAN_DISPLAY.
The reason for this is:
A) the output image generator IP is not compatible with RZ/A1L that didn't have that feature
B) you could not do any alpha blending or see any lower layer when the output image generator is used
The output image generator feature is for a specific purpose....and not really what should have been used in the driver.
But, if you really want to do double buffering, you can do what I did for a video demo that I put together: Just let the app change the frame buffer source register of the VDC5 layer.
Like Pecteilis said, first manually allocate the space for 2 full frame buffers.
Then, from the application side, keep changing the register that points to the live buffer back and forth between the two.
In my usage, I was display raw YCbCr on graphic plane 0 as a small window and using the normal graphic plane 2 (/dev/fb0) for other graphics.
struct gr_regs {
unsigned long GR_UPDATE;
unsigned long GR_FLM_RD;
unsigned long GR_FLM1;
unsigned long GR_FLM2;
unsigned long GR_FLM3;
unsigned long GR_FLM4;
unsigned long GR_FLM5;
unsigned long GR_FLM6;
unsigned long GR_AB1;
unsigned long GR_AB2;
unsigned long GR_AB3;
unsigned long GR_AB4;
unsigned long GR_AB5;
unsigned long GR_AB6;
unsigned long GR_AB7;
unsigned long GR_AB8;
unsigned long GR_AB9;
unsigned long GR_AB10;
unsigned long GR_AB11;
unsigned long GR_BASE;
unsigned long GR_CLUT_INT;
unsigned long GR_MON;
};
/* Memory Map base for Graphics Registers */
#define MMBASE_GR 0xFCFF7000
#define MMSIZE_GR (1 * PAGE_SIZE) /* must be multiple of PAGE_SIZE */
#define GR0_UPDATE 0xFCFF7600
#define GR2_UPDATE 0xFCFF7700
/* Memory Map base for Frame Buffers */
#define X_RES 320
#define Y_RES 240
#define FB_SIZE (X_RES * Y_RES * 2)
#define MMBASE_FB 0x20000000 + (10 * 0x100000) - (1.5 * 0x100000) /* 1.5 MB from end of internal RAM */
#define MMSIZE_FB (320 * 1024) /* must be multiple of PAGE_SIZE */
/* Open /dev/mem */
fd = open("/dev/mem", O_RDWR);
if (fd == -1) {
perror("can't open /dev/mem");
return -1;
}
/* Map in our Graphcis Registers */
maddr_gr = mmap(NULL, MMSIZE_GR, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MMBASE_GR);
if (maddr_gr == MAP_FAILED) {
perror("mmap for /dev/mem failed.");
goto done;
}
gr0 = (struct gr_regs *)(GR0_UPDATE - MMBASE_GR + maddr_gr);
gr2 = (struct gr_regs *)(GR2_UPDATE - MMBASE_GR + maddr_gr);
/* Map in our Frame buffers */
maddr_fb = mmap(NULL, MMSIZE_FB, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MMBASE_FB);
if (maddr_fb == MAP_FAILED) {
perror("mmap for /dev/mem failed.");
goto done;
}
fb0 = maddr_fb;
fb1 = maddr_fb + FB_SIZE;
/* switch LCD to use frame buffer 0 */
gr0->GR_FLM2 = MMBASE_FB;
gr0->GR_UPDATE = 0x111; /* latch the new value */
/* switch LCD to frame buffer 1 */
gr0->GR_FLM2 = MMBASE_FB + FB_SIZE;
gr0->GR_UPDATE = 0x111; /* latch the new value */
Chris