July 25, 2013

DVI Support on i.MX6 boards

At long last, DVI support is here for our i.MX6 boards.

When we built our very first SABRE Lite boards, one of the first things we tested was the HDMI video port, and at that time, most of the monitors we used for testing were natively DVI, not HDMI. All of the newer monitors were being used by our staff, and the ones available for testing were older monitors which only supported DVI.

Way back then, we weren’t booting Linux, and were running some bare metal code, and we found that the hot-plug detect code wasn’t working quite right. If we looked at the HDMI_PHY_STAT0 register, we could see that bits 7-4 (the RX_SENSE bits) would toggle along with connection to the monitor, but bit 1 (HPD) wouldn’t.

We updated the code to look at the others and didn’t look back until very recently. Along the way, we’ve told customers to just use HDMI instead, knowing that there was a software fix, but kicked the can down the road. Sorry about that.

We finally had a chance to investigate more fully, and to compare the operation of Freescale’s SABRE SDB board with ours. With a little nudge from RooT, we figured out that the core of the issue is a voltage dividing resistor we placed on the HPD signal to prevent 5V from hitting the CPU.

With the latest specs from Freescale, we found that this resistor could be bypassed (the pad is 5V-tolerant), but we also added some patches to allow the RX_SENSE bits to be used instead, providing a software solution.

The patches come in three parts:
  1. U-Boot patch to change the hdmidet command and internal HDMI detection to use the RX_SENSE bits, and
  2. A non-Android Linux patch to do the same, and
  3. A patch for the Android (Jellybean) kernel
Note that the U-Boot patch is only in our staging branch at the moment, and will be released to production in the next couple of weeks.

Comments 12

  1. Post
  2. Tele

    Very important patch, thank you very much. Now I can use my old Viewsonic 191b LCD. It works like charm.
    But may I have a question?
    This display’s resolution is 1280×1024
    How should I set the fbmem variable in the 6x_bootscript file?
    At 1280×720, fbmem was 28M.
    Is it proportional? It should be 40M at 1280×1024?
    What is fbmem exactly?

  3. Tele

    Hi again,

    Sorry I was wrong just before. This patch works but not like charm. Still much better than nothing.
    If I give a software reset (I type “reboot”) to the Sabre-Lite, it doesn’t switch the DVI display on anymore. It boots and works, but without display. It needs a hardware reset, green lil button or power off-on cycle to get it work again.

    My kernel was just downloaded from git-repo, branch “boundary-imx_3.0.35_4.0.0”. Patch was applied already, I had to do nothing but make it.
    My kernel was downloaded from git-repo also, from production branch. I had to apply the above patches and I did. It says:

    U-Boot 2013.04-04341-g1903727-dirty (Aug 04 2013 – 12:42:14)

    CPU: Freescale i.MX6Q rev1.2 at 792 MHz
    Reset cause: POR
    Board: SABRE Lite
    DRAM: 1 GiB
    SF: Detected SST25VF016B with page size 4 KiB, total 2 MiB
    No panel detected: default to HDMI
    enable_hdmi: setup HDMI monitor
    Display: HDMI (1024×768)
    In: serial
    Out: serial
    Err: serial
    Net: using phy at 6
    Warning: failed to set MAC address

    1. Post

      Hi Tele,

      This is actually a very old bug. The initialization of the display in U-Boot doesn’t function properly when the display has been (re)initialized by Linux.

      In other words, this was the case before the addition of DVI support.

  4. Tele

    Thanks Eric,

    Is it a well known old bug and no one wants to fix it, patch it? Thats strange. Why is that?
    You forgot about my question about fbmem. Have I set it correctly? Is it 40M for 1280×1024?

    1. Post

      Hi Laci,

      Well, “bug” is maybe not the right term here. When we implemented HDMI support, we noticed it and because the primary need (show something at power on or reset) worked, addressing re-initialization just never made it to top priority. AFAIK, no i.MX6 based boards have anything different here. Patches are certainly welcome.

      As for the fbmem thing, the notes on this are sketchy, but the latest docs from Freescale have fbmem=28M for 1080P resolution.

  5. Tele

    Thx Eric,

    I’m gonna try to find that bug, it annoys me. Its bug, that is right term in my opinion, because restarting is a regular functionality of linux, nothing special about it. I’ll keep you posted about the progress. I would appreciate any help or info you know about it.

    Another question just popped in my mind. The shutdown. When I’m in command line mode, there is no problem at all, I type ‘halt’ or ‘shutdown now’ and problem solved, few seconds later I can switch the power off.
    But when I’m in GUI, like Ubuntu Gnome or something like that, the shutdown command does do a logging out only. Is that login prompt a safe state to switch the power off ? I don’t wanna ruin my file system, and shutting down is a very frequent, daily thing. What is the correct sequence to shut the sabre down if you are in GUI Ubuntu ?

    1. Post

      Thanks Laci,

      You might want to check register IOMUXC_GPR3. Does this bring back the display after reboot?

      U-Boot > mm 020e000c
      020e000c: 00000004 ? 0
      020e0010: f00000cf ? x

      If so, then the problem lies in how we have HDMI mapped. Under Linux, we have the HDMI transmitter connected to IPU #0, display, but U-Boot maps a single display on IPU0, DI0.

      You can see how this happens in Linux in this block of code.

      As for rebooting with a GUI, the best bet is to use the reboot function, and then pull power after the display goes dark and before Linux re-starts (i.e. in U-Boot), since nothing in U-Boot writes to the filesystem(s).

      1. Tele

        Hi Eric,

        Bingo!!! Yes, the problem is there.
        If I write 0 in that register then I get my HDMI/DVI back.

        The only place where u-boot sets IOMUXC_GPR3 register is “setup_display(void)” function. (make a search for “iomux->gpr[3]” on all u-boot tree.)
        Looks like this:

        reg = readl(&iomux->gpr[3]);
        reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)

        Reads the reg, then it clears bit6, bit7 (LVDS0_MUX_CTL IPU1, DI0), then writes it back. It doesn’t bother about HDMI_MUX_CTL bits (bit2,bit3). Not at all. I don’t understand.

        When I switch the power on(hard reset):

        U-Boot > mm 020e000c
        020e000c: 01e00000 ?
        020e0010: f00000cf ? x

        so bit3=0, bit2=0 (HDMI_MUX_CTL mm 020e000c
        020e000c: 00000004 ?
        020e0010: f00000cf ? x

        so bit3=0, bit2=1 (HDMI_MUX_CTL <- IPU1, DI1) and that doesn't work for me.

        So I've comitted an ugly hack:
        reg &= ~IOMUXC_GPR3_HDMI_MUX_CTL_MASK;

        I cleared HDMI_MUX_CTL bits. Its monkey job, without deep understanding, but it works for me. Now I have HDMI/DVI after reboot, thank you very much you are a genius 🙂

        1. Post
  6. Tele

    Something went wrong in the middle of my previous comment:

    It should be:

    “When I switch the power on(hard reset):

    U-Boot > mm 020e000c
    020e000c: 01e00000 ?
    020e0010: f00000cf ? x

    so bit3=0, bit2=0 (HDMI_MUX_CTL mm 020e000c
    020e000c: 00000004 ?
    020e0010: f00000cf ? x

    so bit3=0, bit2=1 (HDMI_MUX_CTL <- IPU1, DI1) and that doesn't work for me."

    Sorry for that.

Leave a Reply