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?
解決済! 解決策の投稿を見る。
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
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)
rotation = 7(90_left)
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
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
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,
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
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
Hi all.
I use kernel 3.14.56 for Udoo. Have someone the patch to this version?
Thanks!
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.
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.
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
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?
This code rotates the fb0. Do you know if same way fb1 (overlay) also can be rotated?
Regards,
Vikash
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.
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
Hi Jerome, Marco Antonio,
QT app also works. I was using fb1 for weston, after chnaging it to fb0 it works.
Thanks.
Regards,
Vikas
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.
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
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.
Hi Marco!
Thank You very much! It works perfect!
Best regards,
Ivan.
Hello, Your changes can rotate the UI ?
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