i.MX6 IPU and rotating a frame buffer

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX6 IPU and rotating a frame buffer

Jump to solution
72,090 Views
jasonhaedt
Contributor III

I'll try to make a long story as short as possible :smileyhappy: (let me know if I skip any important details).  Hopefully this is an easy one, but we're still a little green on this part and the IPU is a pretty complex beast, so I'm banging my head at the moment.  The LCD we're planning on using for this product is FHD/portrait mode (so, 1080x1920) connected via DSI.  We've written a driver for this to glue in to the existing DSI driver (so, pretty much like the hx8369 driver down in drivers/video/mxc).  So far so good - everything works at this point.  However, the physical orientation of the display will be landscape i.e. 1920x1080, so we were hoping to use the IPU's IRT to rotate the final framebuffer 90 degrees.  In order to not have to write plugins for our userspace application(s) to worry about setting up the IPU to do this (and also just to try to get a proof-of-concept going), I've tried to modify the IPU framebuffer driver (mxc_ipuv3_fb.c) to accommodate this.  The quick hack to test this out was just to have the driver allocate an extra framebuffer down in mxcfb_map_video_memory (we'll call this new buffer A and the original buffer B).  This new buffer is the one that now gets attached to the kernel framebuffer i.e. fb_info->screen_base (so this is the one that will get rendered in to).  I set up DMA through the IRT using MEM_ROT_VF_MEM (channel 46 in, channel 49 out) with buffer A being the input and buffer B being the output (initializing both with ipu_init_channel_buffer) (the rotation parameter is set to IPU_ROTATE_90_RIGHT, input resolution is x=1920/y=1080/stride=(3*1920) (we're running rgb/24bpp), output resolution is x=1080/y=1920/stride=(3*1080)).  Finally I link the rotation channel to the display channel (ipu_link_channels, MEM_ROT_VF_MEM -> MEM_FG_SYNC).

With this setup, my rotated screen is pretty much garbage (so much so that there's no discernible pattern to guess as to what might be wrong).  The weird part though is if I cut down horizontal resolution of the input framebuffer (and of course the framebuffer structure that gets registered) to 1080x1080, the rotation works fine (I believe I've tried non-square resolutions too with a lower x resolution and they worked okay, but I'll have to double-check that one).

Okay, I just did some more digging in to the underlying registers that are getting configured by the IPU driver and I see that the width/height fields in IPUx_IC_IDMAC_3/4 are limited to 10 bits (1024 pixels), so I assume that I'd need to figure a way to break the 1080x1920 rotation in to four separate DMA transfers, correct?

Labels (1)
Tags (1)
1 Solution
47,441 Views
rogerio_silva
NXP Employee
NXP Employee

Hi Jason,

You're right. The maximum IPU can rotate is 1024x1024. Linux kernel splits the image to show images bigger than 1024x1024.

You can check the file linux/drivers/mxc/ipu3/ipu_device.c about the way it splits. See the "create_split_task" function.

Rgds

Rogerio

View solution in original post

45 Replies
11,107 Views
ambika
Contributor II

Hello Frider  Schrempf,,

Thanks for the driver file.

It helped me out and rotation is working with my kernel source also.

But with 90 degree rotations (4 to 7) the display will be cropped. I have attached two images.

rotation = 0 (none)

original.jpg

            

rotation = 7(90_left)   

rotation_7.jpg

I work on 800*480 resolution display. Whether support can be done for h*w resolution where h=w?

What can be done to support all resolutions (less than 1024*1024) to see the rotated screen completely?

Thanks in advance.

Regards,

Ambika

0 Kudos
Reply
6,615 Views
ambika
Contributor II

Hello,

I'm trying to achieve 90 and 270 rotation.

I work on 3.14.28 kernel.

Applied the patch fix_rotation.diff.zip attached by Marco Antonio Segalla Cass also did used patch fix from Jérôme Pouiller's github.

I set 2,3,4,5,6,7 to /sys/class/graphics/fb0/rotate, still facing the below prints on terminal,

imx-ipuv3 2400000.ipu: IPU Warning - IPU_INT_STAT_10 = 0x60000000
imx-ipuv3 2400000.ipu: IPU Warning - IPU_INT_STAT_10 = 0x20000000
imx-ipuv3 2400000.ipu: IPU Warning - IPU_INT_STAT_10 = 0x40000000
mxc_sdc_fb fb.20: Error updating SDC buf 1 to address=0x44D00000, current buf 1, buf0 ready 1, buf1 ready 0, buf2 ready 0

Did you guys have any clue?

Thanks & Regards,

Ambika

0 Kudos
Reply
6,505 Views
jérômepouiller
Contributor III

Hello Ambika,

As specified in README of my github repository, this patch was designed for
kernel 3.10.17 and need to redesigned to work with latter kernels.

About your specifics messages, it looks likes IPU channels are not correctly
setup. Driver detect that IPU did not fill intermediate buffer (this is the
last line of error message). However, 3 first lines indicate that IPU try to
do something.

Don't forget to post your results, I think it may interest many other people.

BR,

0 Kudos
Reply
6,505 Views
ambika
Contributor II

Hello jerome-pouiller,

I have applied the fix_rotation patch which is already given above in this discussion, which is for 3.14.28

So I thought it should work in my code also without any redesign.

I have also got the same error as faced by Frieder Schrempf 

And I tried the fix you have given in the github (last update to mxc_ipuv3_fb.c file),

mxc_fbi->cur_ipu_buf = 1;
init_completion(&mxc_fbi->flip_complete);
- /*
- * We don't need to wait for vsync at the first time
- * we do pan display after fb is initialized, as IPU will
- * switch to the newly selected buffer automatically,
- * so we call complete() for both mxc_fbi->flip_complete
- * and mxc_fbi->alpha_flip_complete.
- */
- complete(&mxc_fbi->flip_complete);
if (mxc_fbi->alpha_chan_en) {
mxc_fbi->cur_ipu_alpha_buf = 1;
init_completion(&mxc_fbi->alpha_flip_complete);
- complete(&mxc_fbi->alpha_flip_complete);
}
if (fbi->var.rotate > IPU_ROTATE_VERT_FLIP && mxc_fbi->ipu_ch == MEM_BG_SYNC) {
@@ -470,6 +461,17 @@ static int _setup_disp_channel2(struct fb_info *fbi)
}
ipu_ch = MEM_ROT_VF_MEM;
} else {
+ /*
+ * We don't need to wait for vsync at the first time
+ * we do pan display after fb is initialized, as IPU will
+ * switch to the newly selected buffer automatically,
+ * so we call complete() for both mxc_fbi->flip_complete
+ * and mxc_fbi->alpha_flip_complete.
+ */
+ complete(&mxc_fbi->flip_complete);
+ if (mxc_fbi->alpha_chan_en) {
+ complete(&mxc_fbi->alpha_flip_complete);
+ }
ipu_ch = mxc_fbi->ipu_ch;

}

But error still exists. Did I miss anything??

Can you provide the any detailed document regarding IPU frame buffer?

Thanks & Regards,

Ambika

0 Kudos
Reply
6,505 Views
friederschrempf
Contributor IV

Hello Ambika,

I tried to get rid of those errors and a solution, that seems to work for me (though not fully tested) is in the attachment.

It is based on 3.10.17, but maybe it is still helpful for you.

Regards

Frieder

6,504 Views
johannobermayr
Contributor I

Hello,

thanks all for this rotation patches. All work correct for resolution < 1024.

But now we need this for resolution > 1024 pixel.

With big resolution we get follow error.

mxc_sdc_fb fb.22: Error updating SDC buf 1 to address=0x2C100000, current buf 1, buf0 ready 1, buf1 ready 0, buf2 ready 0

And sometime (every 50's reboot) the screen will show nothing. (black screen) But in framebuffer we see the correct

picture.

And solution or idee to fix this ?

Thanks & regards

  Johann

0 Kudos
Reply
6,539 Views
alexv
Contributor II

Hi all.

I use kernel 3.14.56 for Udoo. Have someone the patch to this version?

Thanks!

0 Kudos
Reply
6,539 Views
ivannikolaenko
Contributor IV

Hi all!

We moved to a imx-3.14.52 kernel and I was surprised that it still not implemented rotation of the image. Moreover, I was surprised and very disappointed that patch proposed by Jerome Pouiller is not working anymore. That made me write to this topic.

So, does anyone have any ideas how, after all, to implement a hardware rotation of the image once and for all? jasonhaedt​, could you share your solution?
Thank you.

0 Kudos
Reply
6,539 Views
jérômepouiller
Contributor III

Based on architecture proposed by Jason, I wrote a patch to support framebuffer rotation on imx6. It may help someone. It is available here:

  jerome-pouiller/mxc-video-rotate · GitHub

Obviously, there are a few limitations, but it works very well.

6,540 Views
wolnet
Contributor III

Dear Jerome,

thank you for your patch it works well for me when I use 90 degrees and 270 degrees,

but when I rotate 180 degrees the image is splitted into 5 columns.

Do you have any idea what could be the issue ?

Kind regards

Wolfgang

0 Kudos
Reply
6,540 Views
jérômepouiller
Contributor III

Hello Wolfgang,

Normally, it should be able to do 180° rotation. But, as Marco pointed out, I have only tested it on kernel 3.10.17 and I won't be surprised some changes will be necessary for other versions.

However, my patch should not be necessary for 180° rotation. Did you try to just call FBIOPUT_VSCREENINFO with rotate member of fb_var_screeninfo set to 1 or 2?

0 Kudos
Reply
6,540 Views
vikaspatil
Senior Contributor I

This code rotates the fb0. Do you know if same way fb1 (overlay) also can be rotated?

Regards,

Vikash

0 Kudos
Reply
6,540 Views
jérômepouiller
Contributor III

Hello Vikash,

I don't think it would be possible to also rotate fb1 without redesigning whole architecture. You can try to place `fb0` and `fb1` buffers in contiguous memory and rotate both buffer together, but I am not sure it would work.

0 Kudos
Reply
6,537 Views
vikaspatil
Senior Contributor I

Hi Jerome, Marco Antonio,

Thanks a lot for sharing your work.

I tried attached patch with linux 3.14.28 and I can see the "boot logo" rotated by 180 degree  after adding the "video=mxcfb2:dev=lcd,CLAA-WVGA,if=RGB24,rotate=3" in kernel command line.

However I don't see the QT application screens rotated by 180 degree.  Do you know if this works with GUI toolkits (e.g. QT) and display server/compositor (wayaland/weston)? or Do I need to add such support in those components?

My platform is based on

i.MX6 Duallite

Linux 3.14.28

Vivante GPU driver imx-gpu-viv_5.0.11.p4.4

Weston 1.8.0

Wyaland-ivi-extension 1.4.0

Qt 5.4.2

QTWayland 5.4.2

Thanks & Regards,

Vikas

0 Kudos
Reply
6,537 Views
vikaspatil
Senior Contributor I

Hi Jerome, Marco Antonio,

QT app also works. I was using fb1 for weston, after chnaging it to fb0 it works.

Thanks.

Regards,

Vikas

0 Kudos
Reply
6,537 Views
marco_cassol
NXP Employee
NXP Employee

Hi Wolfgang,

The issue is that the code is assuming that every rotation will invert width and height, which is not true for a 180deg rotation where the resolution stays the same.

The following diff based on the Freescale Kernel 3.14.28 and the implementation from Jerome should work with the 8 different kinds of rotation.

6,537 Views
friederschrempf
Contributor IV

Thank you Jérôme and Marco Antonio for providing the patch to enable rotation!

It works fine, but I'm getting error messages like this:

mxc_sdc_fb fb.17: Error updating SDC buf 1 to address=0x42F00000, current buf 2, buf0 ready 1, buf1 ready 0, buf2 ready 0

What do they mean? Is there any way to get rid of them?

Thanks and Regards

Frieder Schrempf

0 Kudos
Reply
6,537 Views
jérômepouiller
Contributor III

Hello Frieder,

It means a part of IPU try to access a buffer that is not yet ready. I have just pushed (on my github) a fix hat should solve this issue.

0 Kudos
Reply
6,537 Views
ivannikolaenko
Contributor IV

Hi Marco!


Thank You very much! It works perfect!

Best regards,

Ivan.

0 Kudos
Reply
6,537 Views
shanghuadai
Contributor I

Hello, Your changes can rotate the UI ?

0 Kudos
Reply
6,537 Views
michelesponchia
Contributor II

Hi, I wonder if you can post some code snippet of your changes in the framebuffer driver: I am stuck in a similar situation, but I get always a "timeout fl*ip" error and I can't figure out why :smileysad:

edit: some words