LetuxOS U-Boot

Issue 4: new command: lcm fb

Reported by Nikolaus Schaller, Jan 26, 2010

Should set framebuffer mode for DSS display (DVI or LCM) so that an 
arbitrary range of RAM is displayed.

It should be possible to combine this with a 'mmc init' and 'fat 
load' command to read a splash screen file from the SD card.

Instead of a splash screen it should also be possible to load a 
'boot menu' bitmap and combine with the 'tsc choose' command to 
select boot options.

Implementation is not yet clear since the DSS is initialized to 
provide a static color only and does not initialize DMA.

Older releases of the Beagle Board u-boot show a "Beagle" 
splash screen hard coded into u-boot. So we may be able to find out 
how they program the DSS.

Comment 1 by Nikolaus Schaller, Jan 26, 2010

Labels: Type:Enhancement Type:Defect

Comment 2 by Nikolaus Schaller, Jan 26, 2010

Here is sample code where the splash screen is added:

http://groups.google.com/group/beagleboard/browse_thread/thread/3ad9b
803a3418624

From there we can download u-boot_v1_beagle_logo.patch.bz2

This contains (ugly that there are no register definitions but just 
plain addresses!!!).

But it becomes clear that the FB base address is written to

0x48050480 and
0x48050484

+void dss_init(void)
+{
+	unsigned int i;
+	unsigned char pixel[3];
+	int offset = 0;
+
+	/* assuming a resolution of 1280x720 - draw logo into dss buffer 
*/
+
+	/* fill in the blank white bar at the top */
+	for(i = 0; i<(((720/2)-(beagle_height/2))*1280)*2; i+=2) {
+		*((unsigned short *)(0x80500000 + i + offset)) = 0xffff;
+	}
+
+	offset += i;
+
+	/* Add the image data */
+	for (i = 0; i < ((beagle_width*beagle_height)*2);) {
+		HEADER_PIXEL(header_data, pixel);
+		*((unsigned short *)(0x80500000 + i + offset)) =
+			((((pixel[0])&0xf8) << 8) |
+			(((pixel[1])&0xfc) << 3) |
+			(((pixel[2])&0xf8) >> 3));
+		i+=2;
+	}
+
+	offset += i;
+
+	/* fill in the blank white bar at the bottom */
+	for(i = 0; i<(720 - (offset/2/1280))*1280*2; i+=2) {
+		*((unsigned short *)(0x80500000 + i + offset)) = 0xffff;
+	}
+	
+	*((uint *) 0x48310034) = 0xfefffedf;
+	*((uint *) 0x48310094) = 0x01000120;
+	*((uint *) 0x48004D44) = 0x0001b00c;
+	*((uint *) 0x48004E40) = 0x00001006;
+	*((uint *) 0x48004D00) = 0x00370037;
+	*((uint *) 0x48050C00) = 0x00000002;
+	*((uint *) 0x48050C04) = 0x0000001B;
+	*((uint *) 0x48050C08) = 0x00000040;
+	*((uint *) 0x48050C0C) = 0x00000000;
+	*((uint *) 0x48050C10) = 0x00000000;
+	*((uint *) 0x48050C14) = 0x00008000;
+	*((uint *) 0x48050C18) = 0x00000000;
+	*((uint *) 0x48050C1C) = 0x00008359;
+	*((uint *) 0x48050C20) = 0x0000020C;
+	*((uint *) 0x48050C24) = 0x00000000;
+	*((uint *) 0x48050C28) = 0x043F2631;
+	*((uint *) 0x48050C2C) = 0x00000024;
+	*((uint *) 0x48050C30) = 0x00000130;
+	*((uint *) 0x48050C34) = 0x00000198;
+	*((uint *) 0x48050C38) = 0x000001C0;
+	*((uint *) 0x48050C3C) = 0x0000006A;
+	*((uint *) 0x48050C40) = 0x0000005C;
+	*((uint *) 0x48050C44) = 0x00000000;
+	*((uint *) 0x48050C48) = 0x00000001;
+	*((uint *) 0x48050C4C) = 0x0000003F;
+	*((uint *) 0x48050C50) = 0x21F07C1F;
+	*((uint *) 0x48050C54) = 0x00000000;
+	*((uint *) 0x48050C58) = 0x00000015;
+	*((uint *) 0x48050C5C) = 0x00001400;
+	*((uint *) 0x48050C60) = 0x00000000;
+	*((uint *) 0x48050C64) = 0x069300F4;
+	*((uint *) 0x48050C68) = 0x0016020C;
+	*((uint *) 0x48050C6C) = 0x00060107;
+	*((uint *) 0x48050C70) = 0x008D034E;
+	*((uint *) 0x48050C74) = 0x000F0359;
+	*((uint *) 0x48050C78) = 0x01A00000;
+	*((uint *) 0x48050C7C) = 0x020501A0;
+	*((uint *) 0x48050C80) = 0x01AC0024;
+	*((uint *) 0x48050C84) = 0x020D01AC;
+	*((uint *) 0x48050C88) = 0x00000006;
+	*((uint *) 0x48050C8C) = 0x00000000;
+	*((uint *) 0x48050C90) = 0x03480079;
+	*((uint *) 0x48050C94) = 0x02040024;
+	*((uint *) 0x48050C98) = 0x00000000;
+	*((uint *) 0x48050C9C) = 0x00000000;
+	*((uint *) 0x48050CA0) = 0x0001008A;
+	*((uint *) 0x48050CA4) = 0x01AC0106;
+	*((uint *) 0x48050CA8) = 0x01060006;
+	*((uint *) 0x48050CAC) = 0x00000000;
+	*((uint *) 0x48050CB0) = 0x00140001;
+	*((uint *) 0x48050CB4) = 0x00010001;
+	*((uint *) 0x48050CB8) = 0x00FF0000;
+	*((uint *) 0x48050CBC) = 0x00000000;
+	*((uint *) 0x48050CC0) = 0x00000000;
+	*((uint *) 0x48050CC4) = 0x0000000D;
+	*((uint *) 0x48050CC8) = 0x00000000;
+	*((uint *) 0x48050010) = 0x00000001;
+	*((uint *) 0x48050040) = 0x00000078;
+	*((uint *) 0x48050044) = 0x00000000;
+	*((uint *) 0x48050048) = 0x00000000;
+	*((uint *) 0x48050050) = 0x00000000;
+	*((uint *) 0x48050058) = 0x00000000;
+	*((uint *) 0x48050410) = 0x00002015;
+	*((uint *) 0x48050414) = 0x00000001;
+	*((uint *) 0x48050444) = 0x00000004;
+	*((uint *) 0x4805044c) = 0xFFFFFFFF;
+	*((uint *) 0x48050450) = 0x00000000;
+	*((uint *) 0x48050454) = 0x00000000;
+	*((uint *) 0x48050458) = 0x00000000;
+	*((uint *) 0x48050464) = 0x0ff03f31;
+	*((uint *) 0x48050468) = 0x01400504;
+	*((uint *) 0x4805046c) = 0x00007028;
+	*((uint *) 0x48050470) = 0x00010002;
+	*((uint *) 0x48050478) = 0x00ef027f;
+	*((uint *) 0x4805047c) = 0x02cf04ff;
+	*((uint *) 0x48050480) = 0x80500000;
+	*((uint *) 0x48050484) = 0x80500000;
+	*((uint *) 0x48050488) = 0x00000000;
+	*((uint *) 0x4805048c) = 0x02cf04ff;
+	*((uint *) 0x480504a0) = 0x0000008d;
+	*((uint *) 0x480504a4) = 0x03fc03bc;
+	*((uint *) 0x480504a8) = 0x00000400;
+	*((uint *) 0x480504ac) = 0x00000001;
+	*((uint *) 0x480504b0) = 0x00000001;
+	*((uint *) 0x480504b4) = 0x00000000;
+	*((uint *) 0x480504b8) = 0x807ff000;
+	udelay(1000);
+	*((uint *) 0x48050440) = 0x0001836b;
+	udelay(1000);
+	*((uint *) 0x48050440) = 0x0001836b;
+	udelay(1000);
+	*((uint *) 0x48050440) = 0x0001836b;
+	udelay(1000);
+}

Comment 3 by Nikolaus Schaller, Jan 26, 2010

Only this is relevant (DSS_ and DISPC_).

It appears that DISPC_GFX registers are used for the Framebuffer

+	*((uint *) 0x48050010) = 0x00000001;
+	*((uint *) 0x48050040) = 0x00000078;
+	*((uint *) 0x48050044) = 0x00000000;
+	*((uint *) 0x48050048) = 0x00000000;
+	*((uint *) 0x48050050) = 0x00000000;
+	*((uint *) 0x48050058) = 0x00000000;
+	*((uint *) 0x48050410) = 0x00002015;
+	*((uint *) 0x48050414) = 0x00000001;
+	*((uint *) 0x48050444) = 0x00000004;
+	*((uint *) 0x4805044c) = 0xFFFFFFFF;
+	*((uint *) 0x48050450) = 0x00000000;
+	*((uint *) 0x48050454) = 0x00000000;
+	*((uint *) 0x48050458) = 0x00000000;
+	*((uint *) 0x48050464) = 0x0ff03f31;
+	*((uint *) 0x48050468) = 0x01400504;
+	*((uint *) 0x4805046c) = 0x00007028;
+	*((uint *) 0x48050470) = 0x00010002;
+	*((uint *) 0x48050478) = 0x00ef027f;
+	*((uint *) 0x4805047c) = 0x02cf04ff;
+	*((uint *) 0x48050480) = 0x80500000;
+	*((uint *) 0x48050484) = 0x80500000;
+	*((uint *) 0x48050488) = 0x00000000;
+	*((uint *) 0x4805048c) = 0x02cf04ff;
+	*((uint *) 0x480504a0) = 0x0000008d;
+	*((uint *) 0x480504a4) = 0x03fc03bc;
+	*((uint *) 0x480504a8) = 0x00000400;
+	*((uint *) 0x480504ac) = 0x00000001;
+	*((uint *) 0x480504b0) = 0x00000001;
+	*((uint *) 0x480504b4) = 0x00000000;
+	*((uint *) 0x480504b8) = 0x807ff000;
+	udelay(1000);
+	*((uint *) 0x48050440) = 0x0001836b;
+	udelay(1000);
+	*((uint *) 0x48050440) = 0x0001836b;
+	udelay(1000);
+	*((uint *) 0x48050440) = 0x0001836b;
+	udelay(1000);
+}

Now, we just have to analyse which bits are been set differently to 
use GFX instead of DEFAULT_COLOR.

Note: GFX_SIZE is the same as SIZE_LCD.

Comment 4 by Nikolaus Schaller, Jan 26, 2010

Now as we know where to look for, it is described in

15.5.3.2.1 Graphics DMA Registers

Comment 5 by Nikolaus Schaller, Jan 27, 2010

Has been done and Tux splash screen can be loaded from MMC.

To use:

	lcm init
	lcm power 2
	lcm on
	mmc init 0
	fatload mmc 0 82000000 splash.rgb
	lcm fb 82000000

=> should be stored in a script...
Status: Fixed

Created: 14 years 4 months ago by Nikolaus Schaller

Updated: 14 years 4 months ago

Status: Fixed

Labels:
Priority:Medium
Type:Enhancement