Tuesday, July 30, 2013

freedreno update: drm/kms and ifc6410

About a month ago, I received a new ARM dev board, a IFC6410!  Which despite the boring sounding name is quite an impressive bit of kit.  About $150, quad-core krait, 2G DDR, SATA, gigabit ethernet.. and adreno a320.  It is basically the same SoC that is in the nexus4 (or the new nexus7).  But in more convenient form factor for development.

And with this board that I've been developing a new msm drm/kms driver.  For a while now, freedreno has been limping along with the msm fbdev and kgsl drivers from their android kernel tree, while I focused on the userspace gallium driver and ddx (xf86-video-freedreno).  But that was always a short-term solution.. with the qcom android drivers, I can't really handle synchronization between processes, which gets really crazy w/ x11 and compositing window manager where you have sharing in both directions (as texture and/or render target), I can't handle page flipping (let alone page flipping synchronized with the GPU), and have general robustness issues.

Unfortunately, the msm android fbdev driver code is a real mess (at least the mdp4 parts).  Even by android / vendor kernel standards, which are pretty low to begin with.  And I don't have any docs on the display controller.  In the end, I ended up instrumenting the code to trace all the register reads/writes, etc, wrote a small parser tool using envytools/librnn, and starting writing rnndb register database for the display controller registers.  It was a lot easier to get a general picture of how the hardware works that way!  Plus I can generate register level headers from rnndb in the same way I do for the gallium driver.

So, earlier in the month, I sent first round of RFC patches, with just basic KMS support.  A couple weeks ago I send the 2nd round which added a3xx gpu support and basic kmscube working.  Since then I've fixed a few things, added HW cursor support and more gpu debugfs bits to help when things go wrong.  And added kms support in xf86-video-freedreno.  And so 3rd (and hopefully final-RFC round) of patches will go out soon.  But now, time for some eye candy:

gnome-shell running on freedreno + msm drm/kms:

and, now that we have drm/kms support, we can use wayland/weston drm compositor:

so, as gnome-shell as-a wayland compositor work progresses, freedreno should be in good shape for the next generation of linux desktop :-)


NOTE: If you look on the msm-drm branches in libdrm and xf86-video-freedreno trees, you'll notice that I've structured things to work on either current android drivers (with a couple small patches), or on msm drm/kms driver.  This is mainly because it is unlikely that I'll be able to support every random lcd panel on every snapdragon phone/tablet that someone might want to try out freedreno on.  Time permitting, I'll eventually add support for the LCD panels on devices I have (HP touchpad, nexus4), and support for some of the older generation adreno gpus.. although patches certainly welcome ;-)


  1. If you want implement lcd panel this should be interesting for you: http://lwn.net/Articles/512363/

  2. Rob, awesome work! Question though, were you able to try Freedreno with i.MX53 AMD Z430/Z160 (as you know this is basically Adreno 200)? Or at least do you know anyone reporting to have it working?

    1. Limak,

      I haven't yet.. although I do have some hardware. Just not the motivation to port to yet a different kernel interface. So my plan was to, once I've had a chance to add a2xx support to drm/kms driver, try to get msm drm/kms driver working on freescale in gpu-only (no kms) mode. To be useful, I'd need to add dmabuf support (to share buffers with imxdrm), and the dma-buf fence patches that Maarten Lankhorst recently posted would be useful to. So still some work to do to get to that point, but I have the imx5 stuff in mind. Of course, patches welcome ;-)

  3. Is a co-existence of both drivers possible?
    fbdev/kgsl for android and drm/kms for linux chroot.

    1. I don't think so.. this is why I keep support in the userspace bits for fbdev/kgsl.

      fwiw, drm/kms driver doesn't yet have support for any dsi/lcdc or any of the lcd panels in any android devices. Only hdmi so far, although I do plan to add dsi and/or lcdc support and panel support for a couple devices that I own.. but the focus will be booting linux natively. There isn't really any sane way to share the display or gpu hw blocks between fbdev+kgsl and drm/kms.

    2. This is rather disappointing to hear. :( I've recently discovered that EXA won't work on the Galaxy S4's SoC (APQ8064T), because it doesn't have support for kgsl_2d0 anymore. I have freedreno working, but without EXA it seems rather pointless. My next hope is the drm/kms driver, so I'm beginning to look into your source code to get this to work. So far, it just causes my device to reboot when the freedreno driver is loaded (still looking into that).

      Unfortunately, booting into native linux on the Galaxy S4 is rather difficult (if possible at all) because we have locked bootloaders. As you may have heard, an exploit was found that allows us to install custom kernels, but that's about it.

      I look forward to watching the progress on this project, and I will continue to toy around with everything you've provided, in an attempt to get it working for the Galaxy S4 community.

    3. fwiw, nexus4 (and ifc6410 and other apq8064 devices) also do not have 2d core. The msm-drm branches (libdrm/mesa/xf86-video-freedreno) also fix up a few things so xf86-video-freedreno will work in "soft EXA" (basically enough EXA to make DRI2 work, but falls back to sw for all EXA drawing). You probably want to use this branch. (Now that msm drm/kms driver is merged in drm-next, I'll soon be pushing changes on libdrm msm-drm branch to upstream libdrm master.. followed by the xf86-video-freedreno and mesa bits.)

      There *is* some experimental XA support (using 3d core for doing EXA 2d operations), although it has some issues which I've not had time to debug. That will most likely be the approach to get 2d accel on devices without a 2d core.

    4. Thanks for the response! Since my last post, I've been fighting with the msm-drm branches of libdrm/mesa/xf86-video-freedreno, and even tried the pre-compiled versions you included in the fedora4-nexus repositories. I've compared your defconfig to my custom kernel, and it appears I've got all I need in there. Result is the phone reboots completely right before X shows on-screen. No Xorg.0.log gets created when this happens. :(

      Older versions of the DDX/libdrm work fine but without EXA, and of course the BGR colors. The fbdev driver has similar results, but is mostly useless for me.

      I assume the problem lies in:
      1) My ./configure lines (likely specifically for mesa)
      2) My kernel config
      3) I'm missing something? A replacement kernel driver or something?

      I'd love to work with you more on this. I have been documenting everything, and I can paste-bin anything or whatnot.

      I'll continue to fiddle with this more. Thank you SO much for your time responding!

    5. Forgot to mention a couple key things:
      - Doing this within a chroot (very similar setup to the nexus4-fedora setup)
      - Trying this with the device screen
      - The framebuffer is /dev/graphics/fb0, but I've edited xorg.conf for this.

    6. hmm, well first off, you probably want to enable devtmpfs and mount devtmpfs for /dev in your chroot (like I do for n4 fedora), rather than using android's /dev. Otherwise I suspect you will run into various issues. (That might not explain this particular issue, but you'll be better off with devtmpfs so it is a good switch to make)

      Other than that.. well, I guess you're mesa config doesn't matter *yet*. It would be useful to pastebin the kernel traces (dmesg), that might give some hint about what is going on.

    7. Used the n4 example to work with devtmpfs, and that seems to bring things much more in-line with your setup, including /dev/fb0. Thank you for the tip! Also nice to know that I don't need to fret with Mesa at this point. I had assumed part of the problem may have been that it was missing or otherwise not built right. What would be your preferred method of gathering the dmesg output? I assume just "dmesg > dmesg.txt", but considering I don't get any opportunity before the device resets... is there a way to capture this on-the-fly?

    8. if you get a chance to dump log before reboot, then 'dmesg > dmesg.txt' does the trick. I usually increase CONFIG_LOG_BUF_SHIFT to 21 in the kernel config so that the kernel traces don't get truncated as soon.

      If you can't dump the log before reboot, and you don't have a debug UART to get traces on, then CONFIG_ANDROID_RAM_CONSOLE is useful to enable. After reboot, the previous traces should be in /proc/last_kmsg

    9. Appears I already had CONFIG_ANDROID_RAM_CONSOLE enabled in my kernel, so that made things easy. Here's a download link for the output of last_kmsg after it rebooted. Using the master branch of libdrm, and using the msm-drm branch of the ddx. Ubuntu 13.10, stock "mf3" android kernel with the kgsl and devtmpfs modifications.


    10. Aou, looks like you are missing some of the fixes I had to make to msm kernel. For this particular issue, you want:


      but you might want to have a look at the handful of commits I have on top of mako-kernel, there might be one or two others that you need to cherry-pick if they aren't already fixed in your kernel:


    11. You, sir, are an amazing person. Thank you for your help! With this patch to the kernel, it's working great! I also applied a couple other patches (such as the BGRA option - it was driving me nuts!). Now I just need to poke around to get some screen rotation and a few other enhancements. :P

      Again, I really appreciate the help.

  4. what branch names I should use to test xorg on Ifc6410 ?
    no specified in the wiki:

    I followed the instructions, but xf86OpenConsole: VT_ACTIVATE failed: No such device or address

    1. That branch should work.. (or there is the newer ifc6410-drm branch with the new kernel driver). Either way, I recommend starting with ifc6410_rob_defconfig as the android config misses a lot of things. In this case, I suspect you miss CONFIG_VT or something along those lines.

    2. i used the "ifc6410-boot-drm.img" & "ifc6410-freedreno-drm.tgz" to bring up the gdm. when i do "systemctl start gdm", i get "error: msm mdp.0: failed to load a3xx gpu"

    3. "failed to load a3xx gpu" -> double check that the firmware files are copied to /lib/firmware/{a300_pfp.fw,a300_pm4.fw}

  5. Dear Rob,

    Thank you very much for the work you've done with our board.
    Really great work.

  6. Really great work! I'm enjoying Fedora on my N4 :)

    Using this new DRM/KMS driver will it still be possible to run Android and a Linux distro in chroot? Or Android will always need fbdev/kgsl?
    Thank you for all your efforts!!

    1. well, I suppose it is possible to use mesa+kms with android.. I think this is what the android-x86 folks do.

  7. hi..Im college student, thanks for sharing :)