HDMI boot up time

Hello,

I’m trying to put a splash screen the fastest way as possible but the HDMI itself takes about 10s to start.
Is there a mean to make it starts at the very beginning of the boot up process, and how ?

Regards
Nicolas

Hi @Ntis

Are you using Android on your DragonBoard?

Hello,

No I’m with the 16.02 debian, I tried android hoping a splashscreen is set but it is worst, about 30s before HDMI wake up

And tried Openembedded too which is faster to boot but HDMI after 8/10s

Hi Nicolas

Unless you want to play tricks, such as a 720x480p60 static image in the bootloader (which is very hard here because current bootloader is not open source), then I think you’ll be looking mostly at “standard” boot time tuning techniques.

The most important of these would be to get rid of the console on the serial port (remove “console=ttyMSMx” or add “quiet” to kernel command line). The console output is synchronous so sending message via the sloooooooow serial port can costs several seconds during boot.

However that’s likely to be the only easy trick… after that you’ll be looking at a number fiddly things to reduce the amount of work the kernel has to do before it can load the display drivers.

Hello,

I made a try on removing serial output, add quiet, remove all unused systemd service (wifi, bt, saned, networking …)
Boot is shorter (12s to console) but hdmi startup doesn’t change :s
Is the initramfs the cause ?

Nicolas

The main sources of latency here are:

  1. Time spent in bootloader (not easily changed).
  2. Time until kernel establishes a video mode.
  3. Time for display device to lock onto the signal (also hard to change).

So the ambition with turning off the serial port is to reduce the time until kernel establishes the video mode.

On my system I see the following among the dmesg output:
>> [ 7.096801] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>> [ 7.097463] [drm] No driver support for vblank timestamp query.
>> [ 7.945160] Console: switching to colour frame buffer device 240x67
>> [ 7.978481] msm 1a00000.qcom,mdss_mdp: fb0: msm frame buffer device
>> [ 7.994089] [drm] Initialized msm 1.0.0 20130625 on minor 0

That tells us that my board (running slightly elderly software) took almost 8 seconds from the point the kernel booted until the video mode is established. This is also the figure we are trying to reduce.

What were the before and after values in your case?

Hello,
Here my tests :

Begin with
>> [ 7.110309] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>> [ 7.110889] [drm] No driver support for vblank timestamp query.
>> [ 7.974263] Console: switching to colour frame buffer device 240×67
>> [ 8.007510] msm 1a00000.qcom,mdss_mdp: fb0: msm frame buffer device
>> [ 8.023901] [drm] Initialized msm 1.0.0 20130625 on minor 0

After remove console and adding quiet
>> [ 5.934758] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>> [ 5.934974] [drm] No driver support for vblank timestamp query.
>> [ 6.767539] Console: switching to colour frame buffer device 240×67
>> [ 6.824595] msm 1a00000.qcom,mdss_mdp: fb0: msm frame buffer device
>> [ 6.839596] [drm] Initialized msm 1.0.0 20130625 on minor 0

disable console-setup (5s in systemd critical chain),
>> [ 5.847218] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>> [ 6.710077] [drm] No driver support for vblank timestamp query.
>> [ 6.759871] Console: switching to colour frame buffer device 240×67
>> [ 6.824595] msm 1a00000.qcom,mdss_mdp: fb0: msm frame buffer device
>> [ 6.771682] [drm] Initialized msm 1.0.0 20130625 on minor 0

disable NetworkManager (1s3 in systemd critical chain),
>> [ 5.847218] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
>> [ 5.850037] [drm] No driver support for vblank timestamp query.
>> [ 6.696200] Console: switching to colour frame buffer device 240×67
>> [ 6.729368] msm 1a00000.qcom,mdss_mdp: fb0: msm frame buffer device
>> [ 6.740943] [drm] Initialized msm 1.0.0 20130625 on minor 0

After that I can’t reduce anymore, and mesuring from cold start let display something after 10s on the screen, so it seems that boot loader and other take 3s more (before kernel measurment)
In dmesg I can see buetooth, audio, rfcomm drivers starting before display :frowning: how could I reorder this ?

Nicolas

So… the key to early tuning is to identify the big wins.

Personally I regard the changes to the kernel arguments, which reduced the time-to-HDMI by ~10%, as a big win. I’ll be (pleasantly) surprised if any other single change has the such a large effect.

Further reductions will require you to recompile the kernel in order to tailor it for what you want to use it for. Basically for all the drivers that load before DRM comes up we can either:

  1. Disable the driver completely if your use-cases don't need it
  2. Recompile the driver as a module (this will decreases time-to-HDMI but will actually increase full system boot time)
  3. Improve the driver so it can load more quickly

To identify the biggest wins take a look at: http://elinux.org/Initcall_Debug

This allows you to get a list of all drivers that are loaded and sort them by how long they take. Obviously you could try disabling drivers (or making modular) driver near the top of the list. You could also look at the other end of the list; drivers that load fast are probably not talking to any hardware (e.g. they are unused) and whilst each makes a tiny contribution there might be a lot of them.

Good luck!

Hello,

That’s what I’m trying to do, recompiling kernel options after options to decrease its size. There is no means of choosing kernel included drivers boot order ? only module can be rearranged ?
Top of that I see that MSM0/1 console are allways started event if I put quiet, remove tty from command lin, any clue for that ?
Is there really a need of initrd for dragon board ? the emmC mount is supported by kernel ? (I saw that unpack and launch init rd take about 1s, and I approach the 5s HDMI boot time for now)

Nicolas

The ordering of called comes from how the initcalls are declared (for example a “subsys_initcall” will occur before a “device_initcall”). Initcalls of the same type will run in an undefined order. See include/linux/init.h (around line 200).

When you read init.h you will notice that there are very few priority levels… as a result there is a strong risk of breaking drivers (or whole sub-systems) if you try to use initcalls to force HDMI to start early. That’s not to say you shouldn’t try this approach but “if it breaks, you get to keep both pieces”.

When you say MSM0/1 always has consoles, do you mean systemd is still starting gettys on them? If so that “just” a service like everything else: systemd for Administrators, Part XVI

Finally regarding initrd… it depends! Do you want the eMMC code in the kernel or as a module? If you really care about time to splash (I have no idea what you goals in tuning the boot time are or at what point you will say “done”) then you can have plymouth to put up HDMI splash image before the eMMC drivers are loaded from the initrd. Distro tools to generate initrd are often built with this usecase in mind.

Hum, seems tricky to change boot prio in initcalls so :slight_smile:
Aim for the moment is to have a splash as quickly as possible, global boot time of 15s could be OK. But actually the HDMI in 10s and total boot in 14, the splash is no more displayed. I tried to add plymouth in initrd but it doesn’t display images, just some square making a progression very very late (I think lauch but systemd on the normal rootfs and not in initrd) But I can’t see the tux logo neither so, it seem’s that fb is not really ready…
For the console I will check but event if no serial tty are initialised on them I’d prefere init the uart after…

Hello,

So I checked, and systemd is not loading gettty of MSMx port, only soc.serial tty devices
I’m trying to remove errors from boot, I removed DMI that was failing and here are the remaining errors :

[    2.686020] msm_dsi_manager_register: failed to register mipi dsi host for DSI 0
[    2.691173] msm 1a00000.qcom,mdss_mdp: failed to bind 1a98000.qcom,mdss_dsi (ops dsi_ops): -517
[    2.714809] msm 1a00000.qcom,mdss_mdp: master bind failed: -517
[    3.622872] qcom-tsens 4a8000.thermal-sensor: tsens calibration failed
[    4.188726]  remoteproc0: Direct firmware load for mba.mbn failed with error -2
[    4.188930]  remoteproc0: failed to load 4080000.qcom,mss
[    4.222154]  remoteproc1: Direct firmware load for wcnss.mdt failed with error -2
[    4.222260]  remoteproc1: failed to load soc:pronto_rproc
[    4.228693] qcom-tz-pil soc:vidc_tzpil@0: failed to read qcom,pll_uV, skipping
[    4.228718] qcom-tz-pil soc:vidc_tzpil@0: failed to read qcom,pll_uA, skipping
[    4.254450]  remoteproc2: Direct firmware load for venus.mdt failed with error -2
[    4.254529]  remoteproc2: failed to load soc:vidc_tzpil@0
[    4.738408] genirq: Setting trigger mode 1 for irq 156 failed (gic_set_type+0x0/0x5c)
[    4.740410] msm_iommu 1f00000.qcom,iommu: Request Global CFG IRQ 156 failed with ret=-22
[    4.782582] genirq: Setting trigger mode 1 for irq 156 failed (gic_set_type+0x0/0x5c)
[    4.783359] msm_iommu 1e00000.qcom,iommu: Request Global CFG IRQ 156 failed with ret=-22

But if I understand it tries to initialise a DSI panel, can’t I tell to not initialize the DSI but HDMI directlu instead ? or how can I disable this check ?

Regarding the activity on ttyMSM1 you might be able to use lsof to investigate. See:

Regarding removing errors during boot is this to reduce time-to-HDMI or just for cosmetic reasons?

Anyhow, a simple strategy to map log messages to code (whether the log messages are errors or not) is to use “git grep”. Some messages contain the name of the function which makes finding them easy but otherwise just guess which bits of the string are not parametrised and make up a pattern from that (e.g. git grep “failed to read.*skipping”). Also, if the message is from a utility function then try replacing the logging function with WARN() so you can see the backtrace.

Once you have found the driver code you will be able to use that to help you find the appropriate portions of the devicetree and will hopefully see how to avoid or conceal the error (changing either the kernel config, the driver or the device tree).

Following this approach for the first log message led me to CONFIG_DRM_MSM_DSI. If you know you will not use the DSI connector you can disable this driver feature…

I’ll get a try with lsof the evening.
For now I removed initramfs and gain a 2s kernel boot time.

For the errors, it is just hoping that removing them could reduce the boot time to HDMI, removing potential wait or scan before errors …
For the DSI, I tried to deactivate it in the kernel configuration but unfortunately I get unresolved symbols after that for the adv7533 if I remember well. There is no mean to force HDMI on this component ? or shoud I remove it from dtb ? Is saw some kernel boot option append by (I think) little kernel of a form : mss_dsi.panel=1:dsi:0 … is there a mean to customize via these options ?

Sorry… I forgot that these boards use the ADV7533 (which is connected via DSI). I usually work on SoCs with built-in HDMI.

The ideas for hunting down errors remain correct but you’re quire right, CONFIG_DRM_MSM_DSI is not to right thing to do.

I’m afraid I don’t know about changing the options passed by little kernel but you can certainly configure the kernel to ignore the options passed from the bootloader and substitute its own version. An example (not for DB410c) is:

scripts/config --enable CMDLINE_FORCE --set-str CMDLINE "console=ttyAMA0,115200 root=/dev/vda"

The exact option passed by LK is : mdss_mdp.panel=1:dis:0:qcom,mdss_dsi_adv7533_720p. If I just put this option on my command line, LK doesn’t re-add it anymore, but I don’t know what can be passed with this option and if it does something …

Result og lsof on ttyMSM shows that ttyMSM0 is openend 3 times by agetty, is this normal even with no console boot option ?
nothing on ttyMSM1

Having it opened three times is certainly normal (stdin, stdout, stderr).

You should also be able to use “systemctl status <pid-of-agetty>” to find out which service has been activated. Hopefully from there you can figure out what to disable within systemd.

Yes systemd is lauching the tty, but even if I tell disable, console is respawn next reboot, what the best way to disable these services in systemd ?
For all other drivers that start before drm, need I to remove them from dtb if I don’t use them ? or is it betterto keep it feature full ?

hi, sorry jumping kind of late in that thread… i missed it… couple of notes:

  • as you noticed this isn’t using a ‘native’ HDMI controller. The SoC doesn’t support HDMI, only DSI. So that will clearly adds delay whatever you end up doing… There is (or will be?) a mezzanine board with a DSI panel which was demo’d at last Linaro Connect, it is built by Lemaker.

  • the bootloader is not proprietary. There are proprietary pieces along the boot in the very early stage, but that’s only the initial bootloader whose job is only to load the power management companion and the trusted firmware (it’s the SBL). The main bootloader called APPSBL which is LK in our release is open source, and there are instructions to recompile it in the release notes. You can then reflash it in the ‘aboot’ partition. there is a ‘display driver’ in LK which is typically used for splashscreen on phones. So because we use DSI->HDMI it might not be too hard to enable ADV7533 in the bootloader, at least LK has DSI support…

  • the initrd is not needed at all. The only why we kept it is because we use partition by name in the bootargs for root= instead of hardcoding the partition number which is more convenient… In OE builds we don’t have initrd in fact.