Configuring HDMI and LCD

  • Hello,


    as described in README, I changed /etc/S17hdmicfg to 1080p@60 and recompiled the kernel for serveral resolutions: 800x600,1024x768,1368x768,1680x1050 and 1920x1080. However, no greater fb/LCD resoluion than 1024x768 (and the default 800x600 of course) will work.


    Is it possible (how?) to get a full screen fb window?


    TIA,
    Chris


  • Well there are several possibilities to target this problem. First of all, what is the problem after all?


    The Problem
    The framebuffer driver of the board tries to allocate memory for the framebuffer window. This memory must be special memory as it must be accessible by DMA (Direct Memory Accesses) through the LCD controller. This memory is continuously read by the LCD controller (and/or the HDMI controller) when it transmits the image to the display, about 60 times a second. So this memory must be a consecutive area in RAM. This seems simple to do, but it is not, because Linux is a demand page system. Here RAM is divided into pages and the pages are dealt to the applications as they need them. These pages may form a consecutive memory area from the point of view of the application, i.e. in the virtual address space, but in reality these pages may be scattered across the whole RAM from the physical address point of view. The conversion from virtual addresses to physical addresses is done by the MMU (Memory Management Unit) and by the help of so-called page tables. These tables are set up by the Kernel and with these tables Linux tells the MMU which virtual page belongs to which physical address. So a page with virtual address A may be located at physical RAM position X at one time and at physical address Y at another time. This concept is rather simple and efficient as it usually avoids the need for moving data around in RAM. If an application needs another page, the system simply takes one arbitrary free page and sets up a page table entry so that the requested virtual address now points to this physical page. Done.


    So after a while of running, this allocation process tends to spread pages across the whole RAM from start to end. Probably leaving lots of small gaps (single free pages) here and there. And even these gaps are filled by data that is read from data files of the file system and form the so-called buffer cache. So in fact it is rather difficult to get a free consecutive area in physical RAM. Trying to allocate one usually requires to relocate some pages to other physical addresses to make room for this consecutive space. A page is relocated by actually copying the data of one place in RAM to another place in RAM and then changing the page table entry for the according virtual page. Thus trying to allocate such a consecutive buffer actually requires real copying of data in RAM. So this is a rather costly operation and therefore the kernel tries to restrict the size for such regions. The standard setting for the size of such DMA capable buffers is 2^10 * pagesize, which is 4MB on nearly all architectures, even on x86.


    The default pixel size on the armStoneA8 is 24 bits (8 bits red, 8 bits green, 8 bits blue), resulting in a 32 bit value in RAM, or 4 bytes. So if the armStoneA8 framebuffer driver tries to allocate a buffer that contains more than 1 million pixels, this exceeds the 4MB limit and the allocation request is denied by the Kernel. This is the error message that you see when booting the system.


    Solution 1: Reduce Pixel Size
    The idea is rather simple. Instead of using 4 bytes per pixel, we can reduce the color depth to 16 bits and use 2 bytes per pixel only. Unfortunately we haven't included the pixel depth in our generic LCD settings yet, so you have to edit the machine file directly: arch/arm/mach-s5pv210/mach-armstonea8.c. Search for the variable "armstonea8_fb_win0" and change both entries ".max_bpp" and ".default_bpp" (currently at or around line #357) from 32 resp. 24 to 16.

    Code
    1. static struct s3c_fb_pd_win armstonea8_fb_win0 = {
    2. .win_mode = {
    3. ...
    4. },
    5. .max_bpp = 32, <--- Set to 16
    6. .default_bpp = 24, <--- Set to 16


    Then recompile your kernel. Now you can define framebuffer sizes of up to 2 million pixels.


    Disadvantage: You now have less color shades than before. However this is often acceptable, especially on LCDs that only provide 18 RGB lines and not the full 24.


    Solution 2: Increase Maximum Allocation Size In The Kernel
    Change the setting for MAX_ORDER in the kernel so that it also accepts larger buffer requests (see file include/linux/mmzone.h). For example we can change the file arch/arm/Kconfig by adding a line at or around line #1736 to set FORCE_MAX_ZONEORDER which will eventually set MAX_ORDER accordingly.

    Code
    1. config FORCE_MAX_ZONEORDER
    2. int "Maximum zone order" if ARCH_SHMOBILE
    3. range 11 64 if ARCH_SHMOBILE
    4. default "9" if SA1111
    5. default "12" if ARCH_S5PV210 <--- add this line
    6. default "11"
    7. help
    8. The kernel memory allocator divides physically contiguous memory


    This requires updating your kernel configuration, which can be done by simply calling "make menuconfig" and immediately exiting again, saving the new config file. Then recompile the kernel.


    Disadvantage: At the moment we don't know if increasing this value has some other negative side effects, for example by a now less efficient system memory allocator in general. In general it is not a good idea to use a value different to all other architectures for such a low-level system parameter where the system heavily depends on. You never know if this leads to incompatibilities at some other place, if not now, then probably in the future. So I don't have a good feeling when touching this value.


    Solution 3: Get Framebuffer Memory By Other Means
    Both solutions above have their own disadvantages. For example consider that you want to have a rather large virtual screen where you can move (pan) your visible window arbitrarily around, then even the 8MB of the new allocation system won't be sufficient. And reducing the color depth is also not such a great solution.


    In fact we have other plans for this problem. Our idea is to make the display already available in U-Boot. Actually to do all the display configuration in U-Boot and not the Linux kernel anymore. People familiar with the PicoMOD6 or PicoCOM3 already know what I'm talking about. This means all the framebuffers are already defined in U-Boot and can be made available in Linux in another way by reserving some memory space. So the Linux framebuffer driver does not need to allocate the RAM by a call to the page allocator anymore, but can simply use any region of this reserved area.


    In addition, the current solution, where the HDMI output only clones the LCD image, is not optimal. To show a Full-HD image on HDMI without any borders requires to also increase the LCD image to this size. So the LCD controller *and* the HDMI controller are accessing this framebuffer, increasing the internal bus load significantly even if we don't use the LCD at all. In fact the LCD controller even isn't capable of driving such a large display. So here we also want to do some changes by separating LCD and HDMI framebuffers. In the future you should be able to


    - Use LCD only
    - Use HDMI only
    - Use LCD and HDMI with separate framebuffers
    - Use LCD and HDMI with the same framebuffer (like now, but with more possibilities)
    - Use a special clone-mode, where the HDMI shows the LCD image, but scaled to full screen size


    However as you can guess this requires quite a few modifications in U-Boot and the Linux LCD and HDMI drivers. So this improvement will only come with the V2.0 release of the armStoneA8 Linux system which will still take a little while.


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • The attached patch adds the possibility to also set the color depth (bits per pixel) in the generic LCD configuration of the Kernel configuration system (e.g. using make menuconfig). It is a more straightforward way of implementing solution 1 from above.


    Just go into the top directory of your Linux kernel source and call

    Code
    1. patch -p1 < 0003-Add-default-and-maximum-bpp-to-generic-LCD-configuration.patch


    Then update your configuration, for example by calling make menuconfig, go to Device Drivers -> Graphics Support -> Generic LCD configuration and modify Default numver of bits per pixel and Maximum allowed number of bits per pixel. Now exit and save the config file. Finally recompile the kernel.


    Your F&S Support Team

  • Quote from "fs-support_HK"

    - Use LCD only
    - Use HDMI only


    Hello,
    this is the option we would need.

    Quote


    However as you can guess this requires quite a few modifications in U-Boot and the Linux LCD and HDMI drivers. So this improvement will only come with the V2.0 release of the armStoneA8 Linux system which will still take a little while.


    We are using 2.0, but I did not find any information on this option. How do I have to configure the system to get HDMI output at Full HD (1920x1050)?


    Kind regards


    Stephan

  • As mentioned in the release notes of V2.0, this version was released because of urgent requests for PicoMOD7A and NetDCU14. So we were forced to move some of the planned features to a later release. The flexible display interface requires quite a lot of changes in U-Boot and Linux and so it is unfortunately among these features that did not make it into the V2.0 release. It will come with one of the next releases. Sorry.


    So you have to go with one of the other two solutions for now.


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Dear F&S Support team,


    what about the plans allocating the display framebuffer in U-Boot because of the paging problem for high display resolutions? Is there a timetable for a next Linux multiplatform release? What are the next things to be added/changed?


    RSchubert

  • We are currently working on Linux for armStoneA5, PicoCOMA5 and NetDCUA5. As they are the replacements for several boards/modules that had to be discontinued rather surprisingly, this is our top priority. In parallel we are developing Linux for QBlissA9 and armStoneA9. When these first releases are out, then we'll look after the display stuff.


    Sorry for the inconvenience, but it was also surprising for us and we had to throw away our whole schedule for the past few months. For example the work on integrating the S3C64xx boards PicoMOD6 and PicoCOM3 into the Multi-Platform Linux was already rather advanced (NBoot, U-Boot, BuildRoot are done, Linux was on its way), but now it does not make much sense anymore to continue with it.


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.