 A very good afternoon to all of you. Thanks for joining us. Today we will be talking about early splash screen using UBoot. I am Deva Stucker and this is my colleague Nikhil. We both work as software engineers at Texas Instruments. At Texas Instruments, we strongly believe in supporting open source ecosystems and have upstream-first mentality. We strongly believe these are necessary ingredients to create long-term, sustainable and quality products. We would like to thank you, Linux Foundation and Open Source Community to help us achieve this. This is the outline of the presentation. We will start with introduction like what is bootloader, what is UBoot, what is splash screen and what is early splash screen. We will see then where does the splash screen sits in the boot flow. We will go through then understanding the basics of the splash screen framework and then see what has changed with the early splash screen. We will then go through a step-by-step guide on how you can add splash screen support for your own display controller and your own display panel at the UBoot proper and then see what are the steps you need to follow to have this support as early splash screen in the UBoot SPL 2. Lastly, we will see how you can have persistent splash screen and flicker-free transition to operating system so that your splash screen stays until the OS is booted up. So what is bootloader and why is it needed? Bootloader is a software which basically loads your operating system. Why is it needed? It is needed because operating system has certain prerequisites like it needs your DDR initialized, it needs certain peripherals to be already up and running before it can be started. So bootloader plays that role where it prepares the necessary environment by initializing DDR and any other required peripherals so that operating system can be loaded. What is UBoot? UBoot is an open-source bootloader which helps in booting the operating system in embedded systems. It supports vast variety of 32-bit and 64-bit associate architectures like ARM, MIPS, RISC-5, etc. and it has a community support across multiple board vendors and different boards. What is splash screen? Splash screen is an introductory screen that comes up when your device is booted up. So for example, you have a phone and you power on that phone. So before your phone gets powered on fully, there is a logo that comes up on the display before your device is fully booted. So that logo is nothing but a splash screen. Why splash screen is useful? So splash screen basically serves two purposes. For the manufacturers, it provides a way to show their branding logo as early as possible when your device is powered on. And for the consumer, it acts as a feedback so that your device is started, is booting up. The other advantage is it also facilitates enabling an on-display console so that you can debug and see your prompt on the display panel instead of using any other peripheral like UART or anything else. So we'll go to the boot flow which UBoot uses and we'll see where there's a splash screen sits in this boot flow. So as soon as you power on your board, power on reset happens and software called ROM bootloader gets started, which is nothing but a hard-coded software loaded on your eProm and it starts running when your device gets powered on. Its role is to initialize the boot media which is required to load the next state of bootloader in the chain. It is very limited in size and it uses static RAM for any operations. So then SPL comes into picture which is loaded by ROM. It is nothing but secondary program loader. Its main role is to initialize DDR and any other necessary peripherals of boot media that are needed to support the loading of the next bootloader in chain, that is the UBoot proper. UBoot proper is the full flash bootloader which runs from DDR and its main advantage is like it is easily upgradable. So for example if you are rolling out a firmware update or you want to replace your UBoot with a new version with some bug fixes then you can easily replace this UBoot proper instead of replacing SPL. It also provides command line support through that you can load different images or display the splash screen and some debug functionalities etc. The UBoot proper loads operating system which your Linux kernel starts executing and it initializes the DDR and different peripherals as per the device tree. Its main role is to act as a memory manager and a program scheduler and it acts as an interface between application and the hardware. So until now the splash screen support was present only at the UBoot proper stage which is third in the pipeline. With early splash screen we added support for splash screen in the SPL stage so that the splash screen is up faster by two seconds now. The other advantage which early splash screen offers is it supports something called Falcon boot mode. So Falcon boot mode in UBoot is a boot mode where UBoot proper stage is skipped and SPL directly loads your kernel. So with splash screen available at SPL the splash stays persistent when your operating system is loaded even when UBoot proper is not in the chain. Now we will go through the details regarding understanding the splash screen framework and see in contrast what changed with the early splash screen. So for splash screen you had to enumerate display controller and display panel related configuration parameters like video timing, frame buffer related information etc. in the device tree files. For early splash screen you don't need to add any new node you just need to add a property called BootPHPrem which basically tells the UBoot that these nodes are applicable at the SPL stage too. And we also had different compile time options which were supported as key conflicts to enable splash screen like you had command BMP to support bitmap commands video to enable video u-class video TI DSS is the platform specific display driver we have then splash screen and splash source to enable the various storage media used for splash and enable the splash screen BMP jzip to enable displaying compressed images in case you want to you are interested in having a very low bitmap file size and to get the display as fast as possible. You have different bitmap formats we support there are key conflicts for them. So for early splash screen there's nothing much changed there are parallel key conflicts defined for early splash screen too but only differences they are prefixed with the prefix SPL. The third thing that we used to do is like we had a board environment file which defined different UBoot environment variables for splash like splash file which tells which file you want to display as splash screen splash image which tells the address where your splash file needs to be loaded in LIDAR splash position which is nothing but your coordinates of your splash file and splash source which is the storage media that is used for splash in this case it is the ospy flash. So for early splash screen too we are using the same board.env file only difference is that in UBoot proper these are proper environment variables so you can basically change them runtime while at UBoot proper command line and you can set it to a different file or a different address and on the runtime but with early splash screen these environment variables are static and they go inside the binary so in case you want to change or update these variables in the splash SPL then you need to recompile your SPL again after updating this variables in the board file. We'll try to understand what is driver model in UBoot first so in UBoot there is a concept called driver model which basically provides an abstraction to user and it provides a platform independent API to consumer to talk to different hardware like u-class video is for talking with your display controller driver and the other advantage the driver model happens is provides is that like it provides instantiation based on device t platform data so your device gets enumerated and instantiated only if it is enabled in device tree so for example if you have multiple display panels or multiple display controllers you don't need to recompile the current UBoot again you can just enable those particular panel and display controller in your device tree and then and then only your U device for that particular display controller will get created so we have a U-class video which is a generic which provides generic APIs to consumer to talk to your video hardware then it has some callbacks which need to be implemented in your instantiation of this driver that is a U-class underscore video driver that is platform specific so it needs to implement the callbacks that are required for video U-class and this is the layer which talks with your display hardware now before going through the code flow we'll try to understand how the memory reservation and frame buffer allocation happens in UBoot so in UBoot when the UBoot is loaded from SPL a board in its sequence is called which reserves memory areas for different components like for example it reserves here the memory region for video frame buffer page table trace buffer and other stuff so this reservation is needed because if UBoot relocates we want to make sure that relocation happens only below this reserved areas like relocation should not touch any of the regions which are marked as reserved so the flow is like it starts reserving from the top of the ramp or the end of the ramp and it grows downwards so this board in its sequence calls a function called reserve video which reserves the memory required to display your frame buffer based on the format you selected and the size of your frame buffer this reserve video function intern calls video reserve function from the video U-class driver so now we will try to understand the code flow that was followed in splash screen and what changed with the early splash screen so for splash screen as we mentioned in earlier slide there's a routine called board in it up which is triggered when UBoot is loaded and this calls this triggers a calls to video reserve function directly based on the k-config that are selected this video reserve call triggers a call to U-class which basically binds your display driver when I see display driver is bound it means your frame buffer information which the display driver was configured based on your device tree it is exported to the video U-class so the corresponding memory required to display that frame buffer is reserved by the video reserve function now after this UBoot needs to relocate and after relocation it calls an API called splash display if you have enabled the splash screen k-config this splash display call triggers the something called video post probe which in turn triggers the probe of your display controller driver now this is the main function because in this probe function only your display is initialized display pipeline is also set and your logo also gets started getting displayed in this function so now we'll see what changed with the early splash screen so the only difference with respect to early splash screen is that the framework doesn't call this video reserve and splash display functions directly based on k-config so we had to call up this functions manually in our board specific file for example in board in it are we are calling something called SPL board in it which in turn calls the video reserve inside which we are calling the video reserve function and this is the rest of low is same like the display driver gets bound and the frame buffer information is reserved based on the display driver and the device tree set now after this we call again the splash display function manually the splash display function triggers the probe of our display driver and this is where again the display pipeline is set and your logo starts getting displayed now my colleague will walk through for the steps on how you can add splash screen for your own device good afternoon everyone now i'll walk you through the steps on how to add splash screen for a new device at you would proper stage first then we'll go through the steps to add early splash screen for your device so very first step comes here is to add your display controller driver as a u-class video u-class video here refers to the class of video drivers it provides the necessary functionalities which are required by your display controller or this section is very important for every driver this is in the friends to our display controller so similarly we'll add it for your display controller the first is the ids these are the compatible string which you attach with your device tree nodes so that the u-boot knows which uh device tree node is accessing which driver code next is the u-boot driver macro it declares your driver and it has the id it defines the class which your driver belongs to then there are three important methods which davis has already told but i'll explain it again bind probe and reboot bind enumerates the list of the drivers and adds the drivers in the list probe will initialize your driver and remove method is required when you are transitioning from u-boot to os so that the driver is in a clean state when it is handed over to linux and there is no kernel crash you'll have to add a device tree node after adding your driver code so that you initialize your register regions and the necessary parameters next step is to add the panel driver you can always add your own panel driver as u-class panel if you are using an old day panel you can always use simple panel dot c this is the driver code which is available already in u-boot it has certain operations like enable backlight set backlight and get display panel timings which are sufficient for enabling an old day panel you can use the following compatible string with the device tree nodes or you can add a new one it also has operations like probe of open firmware to platform these are the functions you will need to implement if you are adding your own driver code for panels moving ahead these are the examples for the display controller node you can see that i have added the register regions here the ports in similar fashion when you are adding your device tree nodes you will need to add the register regions ports and other related information here in case of panel we have added the panel timing parameters as you had seen the get display timing function there which reads this device tree nodes and sets up your panel next step is to add the build support for your video driver so first is you add you define the configs for your driver for your display controller we define a config called video tidss for panels there are configs already available config simple panel which you can use directly or you'll need to add those configs again so using those configs we make we add a make file defining the rules to compile those so here you can see object and the config ahead which ensures that the driver is being compiled so using these configs when you enable them in your board def config file the u-boot will read those configs and compile the necessary driver files and it gets initialized at u-boot if you if these are not defined then you will not have the driver initialized at u-boot next step is to enable the splash screen devarsha has already mentioned you about the configs splash screen which are necessary you define those in your board def config file next next is the splash locations this is very important because in this you provide the metadata metadata about your splash locations here we have added the metadata for ospy and sdcard we define the what kind of storage it is storage sf storage mmc and then we add certain flags defining what kind of memory it is like it is a raw memory or it is a file system depending on this splash storage you'll add other parameters like for open for ospy we are adding the offset and for mmc we are adding the device and the partition finally you'll add the necessary environment variables which already devarsha explained and those are very important because the splash display api will read those environment variables and enable your splash screen now i'll help you test splash screen at u-boot here are some tips and tricks which you can use you can always run the command dm tree and board info dm tree will give you log off all the drivers available at u-boot and if they are enabled and board info will give you if the frame buffer region is allocated and if the driver is active at the stage you can also test display if the drivers are active at u-boot you can always use the use the following commands to test if the splash screen is if the display is coming up fine so you use fat load mmc to load your image from your sdcard then you load it to a certain region in the memory then you run the command bmp display which takes the image from that memory region and displays it here are the outputs for the dm tree and board info here you can see that the video doesn't have a plus in front of it which means it's inactive and also the panel doesn't have a plus in front of it both are inactive here in this case it is inactive because we are enabling them at spl spl stage so we don't require splash screen at u-boot proper stage now let's walk through the steps to enable splash screen at spl stage which enables the release splash screen at spl stage as davos has mentioned there is no default call to reserve video memory so we in the board specific file we have added this function video setup which will reserve memory for you and you can go ahead with displaying the frame buffer and this is this section is very important because after now that you have the splash call at your board specific file you need to reserve a region to load your bmp image and you can't load it just anywhere in the memory map because spl further will load the u-boot and if this region overlaps with the u-boot region the spl might crash so you have to be very careful understand the memory map and define a region such that you use that region safely without crashing your u-boot and here we are reserving the region 0x802 followed by fire 0s and that's the safe location which we found next stage is to call the splash api there is no default splash display api called from your spl stage in the board specific file we have called the video setup and then the splash display which are necessary to enable the splash screen at spl stage and with this you are good to go and after you enable the splash related and bmp configs at spl stage you will get the splash screen at u-boot now let's talk about persistence splash screen and flicker free transition initially when we employed when we enable the splash screen feature what was happening was spl was removing the video driver u-boot was reinitializing it due to which the you the image used to vanish and then come back again so to prevent this from happening what we did was we used something called blobs u-boot provides this functionality called blobs in which you can store information from store and pass information from one stage of u-boot to another stage here we are passing from spl stage to u-boot proper stage what we do is when we reserve memory in spl stage we store the information like the frame buffer starting address the size and then pass it to u-boot when u-boot proper tries to reserve video memory it checks if the blob is available it does it doesn't initialize the memory region and you have the frame buffer reserved in u-boot displaying the continue continuing to display the same image here you can see that when video reserve is called we are checking if it's the first stage of u-boot and preparing the blobs and when reserve video is called it checks if the blob list finds the u-boot blob or video blob and then we use it to reserve reserve the memory now we have achieved flicker free transition between the stages of u-boot but we also have to keep continuing display the same image when linux comes up or before the linux initializes the dss controller again we did it in a very simple way what we did was we reserved a frame buffer region defining the start address and the size of the frame buffer region so linux took it as a reserve region and didn't reuse it when it had to initialize something or didn't didn't use it for some other purposes and ensuring that the display controller displayed the same image till the linux took over but there is an advanced and a dynamic way to do it in which u-boot can dynamically update the device tree which is passed to the linux in the device tree you attach the frame buffer node so that linux node linux knows which frame buffer region to be used and you don't have to reserve the region because that if in future if you don't want u-boot splash screen and you disable it still the region won't be accessible if you reserve the region in the first in the simple way or i would like to thank uh texas instruments and linux foundation for giving me this opportunity uh here are the some here are few references which you can use to write your u-boot driver code or understand how the splash screen is to be enabled at different stages of u-boot and you can check out the ti u-boot tree to enable splash screen before you move on to the qn decision i would like to uh show a demo video so now devash has powered on the board in this video you can see the locks coming up and the splash screen coming up very quickly because the earliest splash screen was enabled and you see the linux started to boot up but the image continues to stay on and it will stick till the linux kernel comes up uh that's it thank you