xref: /rk3399_rockchip-uboot/drivers/video/cfb_console.c (revision 64e40d72eade798fdc4766af80702aeae0e726cb)
1352d2591SJean-Christophe PLAGNIOL-VILLARD /*
2352d2591SJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2002 ELTEC Elektronik AG
3352d2591SJean-Christophe PLAGNIOL-VILLARD  * Frank Gottschling <fgottschling@eltec.de>
4352d2591SJean-Christophe PLAGNIOL-VILLARD  *
5352d2591SJean-Christophe PLAGNIOL-VILLARD  * See file CREDITS for list of people who contributed to this
6352d2591SJean-Christophe PLAGNIOL-VILLARD  * project.
7352d2591SJean-Christophe PLAGNIOL-VILLARD  *
8352d2591SJean-Christophe PLAGNIOL-VILLARD  * This program is free software; you can redistribute it and/or
9352d2591SJean-Christophe PLAGNIOL-VILLARD  * modify it under the terms of the GNU General Public License as
10352d2591SJean-Christophe PLAGNIOL-VILLARD  * published by the Free Software Foundation; either version 2 of
11352d2591SJean-Christophe PLAGNIOL-VILLARD  * the License, or (at your option) any later version.
12352d2591SJean-Christophe PLAGNIOL-VILLARD  *
13352d2591SJean-Christophe PLAGNIOL-VILLARD  * This program is distributed in the hope that it will be useful,
14352d2591SJean-Christophe PLAGNIOL-VILLARD  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15352d2591SJean-Christophe PLAGNIOL-VILLARD  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
16352d2591SJean-Christophe PLAGNIOL-VILLARD  * GNU General Public License for more details.
17352d2591SJean-Christophe PLAGNIOL-VILLARD  *
18352d2591SJean-Christophe PLAGNIOL-VILLARD  * You should have received a copy of the GNU General Public License
19352d2591SJean-Christophe PLAGNIOL-VILLARD  * along with this program; if not, write to the Free Software
20352d2591SJean-Christophe PLAGNIOL-VILLARD  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21352d2591SJean-Christophe PLAGNIOL-VILLARD  * MA 02111-1307 USA
22352d2591SJean-Christophe PLAGNIOL-VILLARD  */
23352d2591SJean-Christophe PLAGNIOL-VILLARD 
24352d2591SJean-Christophe PLAGNIOL-VILLARD /*
25352d2591SJean-Christophe PLAGNIOL-VILLARD  * cfb_console.c
26352d2591SJean-Christophe PLAGNIOL-VILLARD  *
27352d2591SJean-Christophe PLAGNIOL-VILLARD  * Color Framebuffer Console driver for 8/15/16/24/32 bits per pixel.
28352d2591SJean-Christophe PLAGNIOL-VILLARD  *
29352d2591SJean-Christophe PLAGNIOL-VILLARD  * At the moment only the 8x16 font is tested and the font fore- and
30352d2591SJean-Christophe PLAGNIOL-VILLARD  * background color is limited to black/white/gray colors. The Linux
31352d2591SJean-Christophe PLAGNIOL-VILLARD  * logo can be placed in the upper left corner and additional board
32*64e40d72SWolfgang Denk  * information strings (that normally goes to serial port) can be drawn.
33352d2591SJean-Christophe PLAGNIOL-VILLARD  *
34352d2591SJean-Christophe PLAGNIOL-VILLARD  * The console driver can use the standard PC keyboard interface (i8042)
35352d2591SJean-Christophe PLAGNIOL-VILLARD  * for character input. Character output goes to a memory mapped video
36352d2591SJean-Christophe PLAGNIOL-VILLARD  * framebuffer with little or big-endian organisation.
37352d2591SJean-Christophe PLAGNIOL-VILLARD  * With environment setting 'console=serial' the console i/o can be
38352d2591SJean-Christophe PLAGNIOL-VILLARD  * forced to serial port.
39*64e40d72SWolfgang Denk  *
40*64e40d72SWolfgang Denk  * The driver uses graphic specific defines/parameters/functions:
41*64e40d72SWolfgang Denk  *
42*64e40d72SWolfgang Denk  * (for SMI LynxE graphic chip)
43*64e40d72SWolfgang Denk  *
44*64e40d72SWolfgang Denk  * CONFIG_VIDEO_SMI_LYNXEM    - use graphic driver for SMI 710,712,810
45*64e40d72SWolfgang Denk  * VIDEO_FB_LITTLE_ENDIAN     - framebuffer organisation default: big endian
46*64e40d72SWolfgang Denk  * VIDEO_HW_RECTFILL	      - graphic driver supports hardware rectangle fill
47*64e40d72SWolfgang Denk  * VIDEO_HW_BITBLT	      - graphic driver supports hardware bit blt
48*64e40d72SWolfgang Denk  *
49*64e40d72SWolfgang Denk  * Console Parameters are set by graphic drivers global struct:
50*64e40d72SWolfgang Denk  *
51*64e40d72SWolfgang Denk  * VIDEO_VISIBLE_COLS	      - x resolution
52*64e40d72SWolfgang Denk  * VIDEO_VISIBLE_ROWS	      - y resolution
53*64e40d72SWolfgang Denk  * VIDEO_PIXEL_SIZE	      - storage size in byte per pixel
54*64e40d72SWolfgang Denk  * VIDEO_DATA_FORMAT	      - graphical data format GDF
55*64e40d72SWolfgang Denk  * VIDEO_FB_ADRS	      - start of video memory
56*64e40d72SWolfgang Denk  *
57*64e40d72SWolfgang Denk  * CONFIG_I8042_KBD	      - AT Keyboard driver for i8042
58*64e40d72SWolfgang Denk  * VIDEO_KBD_INIT_FCT	      - init function for keyboard
59*64e40d72SWolfgang Denk  * VIDEO_TSTC_FCT	      - keyboard_tstc function
60*64e40d72SWolfgang Denk  * VIDEO_GETC_FCT	      - keyboard_getc function
61*64e40d72SWolfgang Denk  *
62*64e40d72SWolfgang Denk  * CONFIG_CONSOLE_CURSOR      - on/off drawing cursor is done with
63*64e40d72SWolfgang Denk  *				delay loop in VIDEO_TSTC_FCT (i8042)
64*64e40d72SWolfgang Denk  *
65*64e40d72SWolfgang Denk  * CONFIG_SYS_CONSOLE_BLINK_COUNT - value for delay loop - blink rate
66*64e40d72SWolfgang Denk  * CONFIG_CONSOLE_TIME	      - display time/date in upper right
67*64e40d72SWolfgang Denk  *				corner, needs CONFIG_CMD_DATE and
68*64e40d72SWolfgang Denk  *				CONFIG_CONSOLE_CURSOR
69*64e40d72SWolfgang Denk  * CONFIG_VIDEO_LOGO	      - display Linux Logo in upper left corner
70*64e40d72SWolfgang Denk  * CONFIG_VIDEO_BMP_LOGO      - use bmp_logo instead of linux_logo
71*64e40d72SWolfgang Denk  * CONFIG_CONSOLE_EXTRA_INFO  - display additional board information
72*64e40d72SWolfgang Denk  *				strings that normaly goes to serial
73*64e40d72SWolfgang Denk  *				port.  This define requires a board
74*64e40d72SWolfgang Denk  *				specific function:
75*64e40d72SWolfgang Denk  *				video_drawstring (VIDEO_INFO_X,
76*64e40d72SWolfgang Denk  *					VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
77*64e40d72SWolfgang Denk  *					info);
78*64e40d72SWolfgang Denk  *				that fills a info buffer at i=row.
79*64e40d72SWolfgang Denk  *				s.a: board/eltec/bab7xx.
80*64e40d72SWolfgang Denk  * CONFIG_VGA_AS_SINGLE_DEVICE - If set the framebuffer device will be
81*64e40d72SWolfgang Denk  *				initialized as an output only device.
82*64e40d72SWolfgang Denk  *				The Keyboard driver will not be
83*64e40d72SWolfgang Denk  *				set-up.  This may be used, if you have
84*64e40d72SWolfgang Denk  *				no or more than one Keyboard devices
85*64e40d72SWolfgang Denk  *				(USB Keyboard, AT Keyboard).
86*64e40d72SWolfgang Denk  *
87*64e40d72SWolfgang Denk  * CONFIG_VIDEO_SW_CURSOR:    - Draws a cursor after the last
88*64e40d72SWolfgang Denk  *				character. No blinking is provided.
89*64e40d72SWolfgang Denk  *				Uses the macros CURSOR_SET and
90*64e40d72SWolfgang Denk  *				CURSOR_OFF.
91*64e40d72SWolfgang Denk  *
92*64e40d72SWolfgang Denk  * CONFIG_VIDEO_HW_CURSOR:    - Uses the hardware cursor capability
93*64e40d72SWolfgang Denk  *				of the graphic chip. Uses the macro
94*64e40d72SWolfgang Denk  *				CURSOR_SET. ATTENTION: If booting an
95*64e40d72SWolfgang Denk  *				OS, the display driver must disable
96*64e40d72SWolfgang Denk  *				the hardware register of the graphic
97*64e40d72SWolfgang Denk  *				chip. Otherwise a blinking field is
98*64e40d72SWolfgang Denk  *				displayed.
99352d2591SJean-Christophe PLAGNIOL-VILLARD  */
100352d2591SJean-Christophe PLAGNIOL-VILLARD 
101352d2591SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
10209c2e90cSAndreas Bießmann #include <version.h>
103352d2591SJean-Christophe PLAGNIOL-VILLARD #include <malloc.h>
104352d2591SJean-Christophe PLAGNIOL-VILLARD 
105*64e40d72SWolfgang Denk /*
106*64e40d72SWolfgang Denk  * Console device defines with SMI graphic
107*64e40d72SWolfgang Denk  * Any other graphic must change this section
108*64e40d72SWolfgang Denk  */
109352d2591SJean-Christophe PLAGNIOL-VILLARD 
110352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_SMI_LYNXEM
111352d2591SJean-Christophe PLAGNIOL-VILLARD 
112352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
113352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_RECTFILL
114352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_BITBLT
115352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
116352d2591SJean-Christophe PLAGNIOL-VILLARD 
117*64e40d72SWolfgang Denk /*
118*64e40d72SWolfgang Denk  * Defines for the CT69000 driver
119*64e40d72SWolfgang Denk  */
120352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_CT69000
121352d2591SJean-Christophe PLAGNIOL-VILLARD 
122352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
123352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_RECTFILL
124352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_BITBLT
125352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
126352d2591SJean-Christophe PLAGNIOL-VILLARD 
127*64e40d72SWolfgang Denk /*
128*64e40d72SWolfgang Denk  * Defines for the SED13806 driver
129*64e40d72SWolfgang Denk  */
130352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_SED13806
131352d2591SJean-Christophe PLAGNIOL-VILLARD 
132352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_TOTAL5200
133352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
134352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
135352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_RECTFILL
136352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_BITBLT
137352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
138352d2591SJean-Christophe PLAGNIOL-VILLARD 
139*64e40d72SWolfgang Denk /*
140*64e40d72SWolfgang Denk  * Defines for the SED13806 driver
141*64e40d72SWolfgang Denk  */
142352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_SM501
143352d2591SJean-Christophe PLAGNIOL-VILLARD 
144352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_HH405
145352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
146352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
147352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
148352d2591SJean-Christophe PLAGNIOL-VILLARD 
149*64e40d72SWolfgang Denk /*
150*64e40d72SWolfgang Denk  * Defines for the MB862xx driver
151*64e40d72SWolfgang Denk  */
152bed53753SAnatolij Gustschin #ifdef CONFIG_VIDEO_MB862xx
153bed53753SAnatolij Gustschin 
154bed53753SAnatolij Gustschin #ifdef CONFIG_VIDEO_CORALP
155bed53753SAnatolij Gustschin #define VIDEO_FB_LITTLE_ENDIAN
156bed53753SAnatolij Gustschin #endif
1575d16ca87SAnatolij Gustschin #ifdef CONFIG_VIDEO_MB862xx_ACCEL
158bed53753SAnatolij Gustschin #define VIDEO_HW_RECTFILL
159bed53753SAnatolij Gustschin #define VIDEO_HW_BITBLT
160bed53753SAnatolij Gustschin #endif
1615d16ca87SAnatolij Gustschin #endif
162bed53753SAnatolij Gustschin 
163*64e40d72SWolfgang Denk /*
164*64e40d72SWolfgang Denk  * Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc.
165*64e40d72SWolfgang Denk  */
166352d2591SJean-Christophe PLAGNIOL-VILLARD #include <video_fb.h>
167352d2591SJean-Christophe PLAGNIOL-VILLARD 
168*64e40d72SWolfgang Denk /*
169*64e40d72SWolfgang Denk  * some Macros
170*64e40d72SWolfgang Denk  */
171352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_VISIBLE_COLS	(pGD->winSizeX)
172352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_VISIBLE_ROWS	(pGD->winSizeY)
173352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_PIXEL_SIZE	(pGD->gdfBytesPP)
174352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_DATA_FORMAT	(pGD->gdfIndex)
175352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_ADRS		(pGD->frameAdrs)
176352d2591SJean-Christophe PLAGNIOL-VILLARD 
177*64e40d72SWolfgang Denk /*
178*64e40d72SWolfgang Denk  * Console device defines with i8042 keyboard controller
179*64e40d72SWolfgang Denk  * Any other keyboard controller must change this section
180*64e40d72SWolfgang Denk  */
181352d2591SJean-Christophe PLAGNIOL-VILLARD 
182352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_I8042_KBD
183352d2591SJean-Christophe PLAGNIOL-VILLARD #include <i8042.h>
184352d2591SJean-Christophe PLAGNIOL-VILLARD 
185352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_KBD_INIT_FCT	i8042_kbd_init()
186352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_TSTC_FCT		i8042_tstc
187352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_GETC_FCT		i8042_getc
188352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
189352d2591SJean-Christophe PLAGNIOL-VILLARD 
190*64e40d72SWolfgang Denk /*
191*64e40d72SWolfgang Denk  * Console device
192*64e40d72SWolfgang Denk  */
193352d2591SJean-Christophe PLAGNIOL-VILLARD 
194352d2591SJean-Christophe PLAGNIOL-VILLARD #include <version.h>
195352d2591SJean-Christophe PLAGNIOL-VILLARD #include <linux/types.h>
19652cb4d4fSJean-Christophe PLAGNIOL-VILLARD #include <stdio_dev.h>
197352d2591SJean-Christophe PLAGNIOL-VILLARD #include <video_font.h>
198352d2591SJean-Christophe PLAGNIOL-VILLARD 
199352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CMD_DATE)
200352d2591SJean-Christophe PLAGNIOL-VILLARD #include <rtc.h>
201352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
202352d2591SJean-Christophe PLAGNIOL-VILLARD 
203352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
204352d2591SJean-Christophe PLAGNIOL-VILLARD #include <watchdog.h>
205352d2591SJean-Christophe PLAGNIOL-VILLARD #include <bmp_layout.h>
2061ca298ceSMatthias Weisser 
2071ca298ceSMatthias Weisser #ifdef CONFIG_SPLASH_SCREEN_ALIGN
2081ca298ceSMatthias Weisser #define BMP_ALIGN_CENTER	0x7FFF
2091ca298ceSMatthias Weisser #endif
2101ca298ceSMatthias Weisser 
211352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
212352d2591SJean-Christophe PLAGNIOL-VILLARD 
213*64e40d72SWolfgang Denk /*
214*64e40d72SWolfgang Denk  * Cursor definition:
215*64e40d72SWolfgang Denk  * CONFIG_CONSOLE_CURSOR:  Uses a timer function (see drivers/input/i8042.c)
216*64e40d72SWolfgang Denk  *			   to let the cursor blink. Uses the macros
217*64e40d72SWolfgang Denk  *			   CURSOR_OFF and CURSOR_ON.
218*64e40d72SWolfgang Denk  * CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No
219*64e40d72SWolfgang Denk  *			   blinking is provided. Uses the macros CURSOR_SET
220*64e40d72SWolfgang Denk  *			   and CURSOR_OFF.
221*64e40d72SWolfgang Denk  * CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the
222*64e40d72SWolfgang Denk  *			   graphic chip. Uses the macro CURSOR_SET.
223*64e40d72SWolfgang Denk  *			   ATTENTION: If booting an OS, the display driver
224*64e40d72SWolfgang Denk  *			   must disable the hardware register of the graphic
225*64e40d72SWolfgang Denk  *			   chip. Otherwise a blinking field is displayed
226*64e40d72SWolfgang Denk  */
227352d2591SJean-Christophe PLAGNIOL-VILLARD #if !defined(CONFIG_CONSOLE_CURSOR) && \
228352d2591SJean-Christophe PLAGNIOL-VILLARD     !defined(CONFIG_VIDEO_SW_CURSOR) && \
229352d2591SJean-Christophe PLAGNIOL-VILLARD     !defined(CONFIG_VIDEO_HW_CURSOR)
230352d2591SJean-Christophe PLAGNIOL-VILLARD /* no Cursor defined */
231352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_ON
232352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_OFF
233352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_SET
234352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
235352d2591SJean-Christophe PLAGNIOL-VILLARD 
236352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_CONSOLE_CURSOR
237352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CURSOR_ON
238*64e40d72SWolfgang Denk #error	only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \
239*64e40d72SWolfgang Denk 	or CONFIG_VIDEO_HW_CURSOR can be defined
240352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
241352d2591SJean-Christophe PLAGNIOL-VILLARD void console_cursor(int state);
242*64e40d72SWolfgang Denk 
24365618636STimur Tabi #define CURSOR_ON  console_cursor(1)
24465618636STimur Tabi #define CURSOR_OFF console_cursor(0)
245352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_SET
246352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_I8042_KBD
2477817cb20SMarcel Ziswiler #warning Cursor drawing on/off needs timer function s.a. drivers/input/i8042.c
248352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
249352d2591SJean-Christophe PLAGNIOL-VILLARD #else
250352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_CONSOLE_TIME
251352d2591SJean-Christophe PLAGNIOL-VILLARD #error	CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME
252352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
253352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_CONSOLE_CURSOR */
254352d2591SJean-Christophe PLAGNIOL-VILLARD 
255352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_SW_CURSOR
256352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CURSOR_ON
257*64e40d72SWolfgang Denk #error	only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \
258*64e40d72SWolfgang Denk 	or CONFIG_VIDEO_HW_CURSOR can be defined
259352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
260352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_ON
261352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\
26265618636STimur Tabi 				 console_row * VIDEO_FONT_HEIGHT, ' ')
26365618636STimur Tabi #define CURSOR_SET video_set_cursor()
264352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_SW_CURSOR */
265352d2591SJean-Christophe PLAGNIOL-VILLARD 
266352d2591SJean-Christophe PLAGNIOL-VILLARD 
267352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_HW_CURSOR
268352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CURSOR_ON
269*64e40d72SWolfgang Denk #error	only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \
270*64e40d72SWolfgang Denk 	or CONFIG_VIDEO_HW_CURSOR can be defined
271352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
272352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_ON
273352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_OFF
274352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \
27565618636STimur Tabi 		  (console_row * VIDEO_FONT_HEIGHT) + video_logo_height)
276352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_HW_CURSOR */
277352d2591SJean-Christophe PLAGNIOL-VILLARD 
278352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_LOGO
279352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_BMP_LOGO
280352d2591SJean-Christophe PLAGNIOL-VILLARD #include <bmp_logo.h>
281352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_WIDTH	BMP_LOGO_WIDTH
282352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_HEIGHT	BMP_LOGO_HEIGHT
283352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_LUT_OFFSET	BMP_LOGO_OFFSET
284352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_COLORS	BMP_LOGO_COLORS
285352d2591SJean-Christophe PLAGNIOL-VILLARD 
286352d2591SJean-Christophe PLAGNIOL-VILLARD #else  /* CONFIG_VIDEO_BMP_LOGO */
287352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_WIDTH	80
288352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_HEIGHT	80
289352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_COLORS	214
290352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_LUT_OFFSET	0x20
291352d2591SJean-Christophe PLAGNIOL-VILLARD #define __initdata
292352d2591SJean-Christophe PLAGNIOL-VILLARD #include <linux_logo.h>
293352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_WIDTH	LINUX_LOGO_WIDTH
294352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_HEIGHT	LINUX_LOGO_HEIGHT
295352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_LUT_OFFSET	LINUX_LOGO_LUT_OFFSET
296352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_COLORS	LINUX_LOGO_COLORS
297352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_BMP_LOGO */
298352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_INFO_X		(VIDEO_LOGO_WIDTH)
299352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_INFO_Y		(VIDEO_FONT_HEIGHT/2)
300352d2591SJean-Christophe PLAGNIOL-VILLARD #else  /* CONFIG_VIDEO_LOGO */
301352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_WIDTH	0
302352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_HEIGHT	0
303352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_LOGO */
304352d2591SJean-Christophe PLAGNIOL-VILLARD 
305352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_COLS		VIDEO_VISIBLE_COLS
306352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_ROWS		VIDEO_VISIBLE_ROWS
307352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_SIZE		(VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE)
308352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_PIX_BLOCKS	(VIDEO_SIZE >> 2)
309352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LINE_LEN		(VIDEO_COLS*VIDEO_PIXEL_SIZE)
310352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_BURST_LEN		(VIDEO_COLS/8)
311352d2591SJean-Christophe PLAGNIOL-VILLARD 
312352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_LOGO
313be129aa7SMatthias Weisser #define CONSOLE_ROWS		((VIDEO_ROWS - video_logo_height) / VIDEO_FONT_HEIGHT)
314352d2591SJean-Christophe PLAGNIOL-VILLARD #else
315352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROWS		(VIDEO_ROWS / VIDEO_FONT_HEIGHT)
316352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
317352d2591SJean-Christophe PLAGNIOL-VILLARD 
318352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_COLS		(VIDEO_COLS / VIDEO_FONT_WIDTH)
319352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_SIZE	(VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN)
320352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_FIRST	(video_console_address)
321352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_SECOND	(video_console_address + CONSOLE_ROW_SIZE)
322352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_LAST	(video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
323352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_SIZE		(CONSOLE_ROW_SIZE * CONSOLE_ROWS)
324352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_SCROLL_SIZE	(CONSOLE_SIZE - CONSOLE_ROW_SIZE)
325352d2591SJean-Christophe PLAGNIOL-VILLARD 
326352d2591SJean-Christophe PLAGNIOL-VILLARD /* Macros */
327352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	VIDEO_FB_LITTLE_ENDIAN
328*64e40d72SWolfgang Denk #define SWAP16(x)		((((x) & 0x00ff) << 8) | \
329*64e40d72SWolfgang Denk 				  ((x) >> 8) \
330*64e40d72SWolfgang Denk 				)
331*64e40d72SWolfgang Denk #define SWAP32(x)		((((x) & 0x000000ff) << 24) | \
332*64e40d72SWolfgang Denk 				 (((x) & 0x0000ff00) <<  8) | \
333*64e40d72SWolfgang Denk 				 (((x) & 0x00ff0000) >>  8) | \
334*64e40d72SWolfgang Denk 				 (((x) & 0xff000000) >> 24)   \
335*64e40d72SWolfgang Denk 				)
336*64e40d72SWolfgang Denk #define SHORTSWAP32(x)		((((x) & 0x000000ff) <<  8) | \
337*64e40d72SWolfgang Denk 				 (((x) & 0x0000ff00) >>  8) | \
338*64e40d72SWolfgang Denk 				 (((x) & 0x00ff0000) <<  8) | \
339*64e40d72SWolfgang Denk 				 (((x) & 0xff000000) >>  8)   \
340*64e40d72SWolfgang Denk 				)
341352d2591SJean-Christophe PLAGNIOL-VILLARD #else
342352d2591SJean-Christophe PLAGNIOL-VILLARD #define SWAP16(x)		(x)
343352d2591SJean-Christophe PLAGNIOL-VILLARD #define SWAP32(x)		(x)
344229b6dceSWolfgang Grandegger #if defined(VIDEO_FB_16BPP_WORD_SWAP)
345bed53753SAnatolij Gustschin #define SHORTSWAP32(x)		(((x) >> 16) | ((x) << 16))
346cc347801SAndrew Dyer #else
347cc347801SAndrew Dyer #define SHORTSWAP32(x)		(x)
348bed53753SAnatolij Gustschin #endif
349352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
350352d2591SJean-Christophe PLAGNIOL-VILLARD 
351352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
352352d2591SJean-Christophe PLAGNIOL-VILLARD #define PRINTD(x)		printf(x)
353352d2591SJean-Christophe PLAGNIOL-VILLARD #else
354352d2591SJean-Christophe PLAGNIOL-VILLARD #define PRINTD(x)
355352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
356352d2591SJean-Christophe PLAGNIOL-VILLARD 
357352d2591SJean-Christophe PLAGNIOL-VILLARD 
358352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_EXTRA_INFO
359*64e40d72SWolfgang Denk /*
360*64e40d72SWolfgang Denk  * setup a board string: type, speed, etc.
361*64e40d72SWolfgang Denk  *
362*64e40d72SWolfgang Denk  * line_number:	location to place info string beside logo
363*64e40d72SWolfgang Denk  * info:	buffer for info string
364*64e40d72SWolfgang Denk  */
365*64e40d72SWolfgang Denk extern void video_get_info_str(int line_number,	char *info);
366352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
367352d2591SJean-Christophe PLAGNIOL-VILLARD 
368352d2591SJean-Christophe PLAGNIOL-VILLARD /* Locals */
369352d2591SJean-Christophe PLAGNIOL-VILLARD static GraphicDevice *pGD;	/* Pointer to Graphic array */
370352d2591SJean-Christophe PLAGNIOL-VILLARD 
371352d2591SJean-Christophe PLAGNIOL-VILLARD static void *video_fb_address;	/* frame buffer address */
372352d2591SJean-Christophe PLAGNIOL-VILLARD static void *video_console_address;	/* console buffer start address */
373352d2591SJean-Christophe PLAGNIOL-VILLARD 
374be129aa7SMatthias Weisser static int video_logo_height = VIDEO_LOGO_HEIGHT;
375be129aa7SMatthias Weisser 
376352d2591SJean-Christophe PLAGNIOL-VILLARD static int console_col = 0;	/* cursor col */
377352d2591SJean-Christophe PLAGNIOL-VILLARD static int console_row = 0;	/* cursor row */
378352d2591SJean-Christophe PLAGNIOL-VILLARD 
379352d2591SJean-Christophe PLAGNIOL-VILLARD static u32 eorx, fgx, bgx;	/* color pats */
380352d2591SJean-Christophe PLAGNIOL-VILLARD 
381352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table8[] = {
382352d2591SJean-Christophe PLAGNIOL-VILLARD 	0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
383352d2591SJean-Christophe PLAGNIOL-VILLARD 	0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
384352d2591SJean-Christophe PLAGNIOL-VILLARD 	0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
385*64e40d72SWolfgang Denk 	0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
386*64e40d72SWolfgang Denk };
387352d2591SJean-Christophe PLAGNIOL-VILLARD 
388352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table15[] = {
389*64e40d72SWolfgang Denk 	0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff
390*64e40d72SWolfgang Denk };
391352d2591SJean-Christophe PLAGNIOL-VILLARD 
392352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table16[] = {
393*64e40d72SWolfgang Denk 	0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
394*64e40d72SWolfgang Denk };
395352d2591SJean-Christophe PLAGNIOL-VILLARD 
396352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table24[16][3] = {
397352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00000000},
398352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00ffffff},
399352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x0000ffff, 0xff000000},
400352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x0000ffff, 0xffffffff},
401352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x000000ff, 0xffff0000, 0x00000000},
402352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x000000ff, 0xffff0000, 0x00ffffff},
403352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x000000ff, 0xffffffff, 0xff000000},
404352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x000000ff, 0xffffffff, 0xffffffff},
405352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffff00, 0x00000000, 0x00000000},
406352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffff00, 0x00000000, 0x00ffffff},
407352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffff00, 0x0000ffff, 0xff000000},
408352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffff00, 0x0000ffff, 0xffffffff},
409352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffffff, 0xffff0000, 0x00000000},
410352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffffff, 0xffff0000, 0x00ffffff},
411352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffffff, 0xffffffff, 0xff000000},
412*64e40d72SWolfgang Denk 	{0xffffffff, 0xffffffff, 0xffffffff}
413*64e40d72SWolfgang Denk };
414352d2591SJean-Christophe PLAGNIOL-VILLARD 
415352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table32[16][4] = {
416352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00000000, 0x00000000},
417352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00000000, 0x00ffffff},
418352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00ffffff, 0x00000000},
419352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff},
420352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00ffffff, 0x00000000, 0x00000000},
421352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff},
422352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000},
423352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff},
424352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00000000, 0x00000000, 0x00000000},
425352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff},
426352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000},
427352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff},
428352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000},
429352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff},
430352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000},
431*64e40d72SWolfgang Denk 	{0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff}
432*64e40d72SWolfgang Denk };
433352d2591SJean-Christophe PLAGNIOL-VILLARD 
434352d2591SJean-Christophe PLAGNIOL-VILLARD 
435352d2591SJean-Christophe PLAGNIOL-VILLARD static void video_drawchars(int xx, int yy, unsigned char *s, int count)
436352d2591SJean-Christophe PLAGNIOL-VILLARD {
437352d2591SJean-Christophe PLAGNIOL-VILLARD 	u8 *cdat, *dest, *dest0;
438352d2591SJean-Christophe PLAGNIOL-VILLARD 	int rows, offset, c;
439352d2591SJean-Christophe PLAGNIOL-VILLARD 
440352d2591SJean-Christophe PLAGNIOL-VILLARD 	offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE;
441352d2591SJean-Christophe PLAGNIOL-VILLARD 	dest0 = video_fb_address + offset;
442352d2591SJean-Christophe PLAGNIOL-VILLARD 
443352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (VIDEO_DATA_FORMAT) {
444352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_INDEX:
445352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_332RGB:
446352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
447352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
448352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
449352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
450*64e40d72SWolfgang Denk 			     rows--; dest += VIDEO_LINE_LEN) {
451352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
452352d2591SJean-Christophe PLAGNIOL-VILLARD 
453*64e40d72SWolfgang Denk 				((u32 *) dest)[0] =
454*64e40d72SWolfgang Denk 					(video_font_draw_table8[bits >> 4] &
455*64e40d72SWolfgang Denk 					 eorx) ^ bgx;
456*64e40d72SWolfgang Denk 				((u32 *) dest)[1] =
457*64e40d72SWolfgang Denk 					(video_font_draw_table8[bits & 15] &
458*64e40d72SWolfgang Denk 					 eorx) ^ bgx;
459352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
460352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
461352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
462352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
463352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
464352d2591SJean-Christophe PLAGNIOL-VILLARD 
465352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_15BIT_555RGB:
466352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
467352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
468352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
469352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
470*64e40d72SWolfgang Denk 			     rows--; dest += VIDEO_LINE_LEN) {
471352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
472352d2591SJean-Christophe PLAGNIOL-VILLARD 
473*64e40d72SWolfgang Denk 				((u32 *) dest)[0] =
474*64e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table15
475*64e40d72SWolfgang Denk 						     [bits >> 6] & eorx) ^
476*64e40d72SWolfgang Denk 						    bgx);
477*64e40d72SWolfgang Denk 				((u32 *) dest)[1] =
478*64e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table15
479*64e40d72SWolfgang Denk 						     [bits >> 4 & 3] & eorx) ^
480*64e40d72SWolfgang Denk 						    bgx);
481*64e40d72SWolfgang Denk 				((u32 *) dest)[2] =
482*64e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table15
483*64e40d72SWolfgang Denk 						     [bits >> 2 & 3] & eorx) ^
484*64e40d72SWolfgang Denk 						    bgx);
485*64e40d72SWolfgang Denk 				((u32 *) dest)[3] =
486*64e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table15
487*64e40d72SWolfgang Denk 						     [bits & 3] & eorx) ^
488*64e40d72SWolfgang Denk 						    bgx);
489352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
490352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
491352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
492352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
493352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
494352d2591SJean-Christophe PLAGNIOL-VILLARD 
495352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_16BIT_565RGB:
496352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
497352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
498352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
499352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
500*64e40d72SWolfgang Denk 			     rows--; dest += VIDEO_LINE_LEN) {
501352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
502352d2591SJean-Christophe PLAGNIOL-VILLARD 
503*64e40d72SWolfgang Denk 				((u32 *) dest)[0] =
504*64e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table16
505*64e40d72SWolfgang Denk 						     [bits >> 6] & eorx) ^
506*64e40d72SWolfgang Denk 						    bgx);
507*64e40d72SWolfgang Denk 				((u32 *) dest)[1] =
508*64e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table16
509*64e40d72SWolfgang Denk 						     [bits >> 4 & 3] & eorx) ^
510*64e40d72SWolfgang Denk 						    bgx);
511*64e40d72SWolfgang Denk 				((u32 *) dest)[2] =
512*64e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table16
513*64e40d72SWolfgang Denk 						     [bits >> 2 & 3] & eorx) ^
514*64e40d72SWolfgang Denk 						    bgx);
515*64e40d72SWolfgang Denk 				((u32 *) dest)[3] =
516*64e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table16
517*64e40d72SWolfgang Denk 						     [bits & 3] & eorx) ^
518*64e40d72SWolfgang Denk 						    bgx);
519352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
520352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
521352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
522352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
523352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
524352d2591SJean-Christophe PLAGNIOL-VILLARD 
525352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_32BIT_X888RGB:
526352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
527352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
528352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
529352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
530*64e40d72SWolfgang Denk 			     rows--; dest += VIDEO_LINE_LEN) {
531352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
532352d2591SJean-Christophe PLAGNIOL-VILLARD 
533*64e40d72SWolfgang Denk 				((u32 *) dest)[0] =
534*64e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
535*64e40d72SWolfgang Denk 						[bits >> 4][0] & eorx) ^ bgx);
536*64e40d72SWolfgang Denk 				((u32 *) dest)[1] =
537*64e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
538*64e40d72SWolfgang Denk 						[bits >> 4][1] & eorx) ^ bgx);
539*64e40d72SWolfgang Denk 				((u32 *) dest)[2] =
540*64e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
541*64e40d72SWolfgang Denk 						[bits >> 4][2] & eorx) ^ bgx);
542*64e40d72SWolfgang Denk 				((u32 *) dest)[3] =
543*64e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
544*64e40d72SWolfgang Denk 						[bits >> 4][3] & eorx) ^ bgx);
545*64e40d72SWolfgang Denk 				((u32 *) dest)[4] =
546*64e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
547*64e40d72SWolfgang Denk 						[bits & 15][0] & eorx) ^ bgx);
548*64e40d72SWolfgang Denk 				((u32 *) dest)[5] =
549*64e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
550*64e40d72SWolfgang Denk 						[bits & 15][1] & eorx) ^ bgx);
551*64e40d72SWolfgang Denk 				((u32 *) dest)[6] =
552*64e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
553*64e40d72SWolfgang Denk 						[bits & 15][2] & eorx) ^ bgx);
554*64e40d72SWolfgang Denk 				((u32 *) dest)[7] =
555*64e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
556*64e40d72SWolfgang Denk 						[bits & 15][3] & eorx) ^ bgx);
557352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
558352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
559352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
560352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
561352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
562352d2591SJean-Christophe PLAGNIOL-VILLARD 
563352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_24BIT_888RGB:
564352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
565352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
566352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
567352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
568*64e40d72SWolfgang Denk 			     rows--; dest += VIDEO_LINE_LEN) {
569352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
570352d2591SJean-Christophe PLAGNIOL-VILLARD 
571*64e40d72SWolfgang Denk 				((u32 *) dest)[0] =
572*64e40d72SWolfgang Denk 					(video_font_draw_table24[bits >> 4][0]
573*64e40d72SWolfgang Denk 					 & eorx) ^ bgx;
574*64e40d72SWolfgang Denk 				((u32 *) dest)[1] =
575*64e40d72SWolfgang Denk 					(video_font_draw_table24[bits >> 4][1]
576*64e40d72SWolfgang Denk 					 & eorx) ^ bgx;
577*64e40d72SWolfgang Denk 				((u32 *) dest)[2] =
578*64e40d72SWolfgang Denk 					(video_font_draw_table24[bits >> 4][2]
579*64e40d72SWolfgang Denk 					 & eorx) ^ bgx;
580*64e40d72SWolfgang Denk 				((u32 *) dest)[3] =
581*64e40d72SWolfgang Denk 					(video_font_draw_table24[bits & 15][0]
582*64e40d72SWolfgang Denk 					 & eorx) ^ bgx;
583*64e40d72SWolfgang Denk 				((u32 *) dest)[4] =
584*64e40d72SWolfgang Denk 					(video_font_draw_table24[bits & 15][1]
585*64e40d72SWolfgang Denk 					 & eorx) ^ bgx;
586*64e40d72SWolfgang Denk 				((u32 *) dest)[5] =
587*64e40d72SWolfgang Denk 					(video_font_draw_table24[bits & 15][2]
588*64e40d72SWolfgang Denk 					 & eorx) ^ bgx;
589352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
590352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
591352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
592352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
593352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
594352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
595352d2591SJean-Christophe PLAGNIOL-VILLARD }
596352d2591SJean-Christophe PLAGNIOL-VILLARD 
597352d2591SJean-Christophe PLAGNIOL-VILLARD static inline void video_drawstring(int xx, int yy, unsigned char *s)
598352d2591SJean-Christophe PLAGNIOL-VILLARD {
599352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_drawchars(xx, yy, s, strlen((char *) s));
600352d2591SJean-Christophe PLAGNIOL-VILLARD }
601352d2591SJean-Christophe PLAGNIOL-VILLARD 
602352d2591SJean-Christophe PLAGNIOL-VILLARD static void video_putchar(int xx, int yy, unsigned char c)
603352d2591SJean-Christophe PLAGNIOL-VILLARD {
604be129aa7SMatthias Weisser 	video_drawchars(xx, yy + video_logo_height, &c, 1);
605352d2591SJean-Christophe PLAGNIOL-VILLARD }
606352d2591SJean-Christophe PLAGNIOL-VILLARD 
607352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
608352d2591SJean-Christophe PLAGNIOL-VILLARD static void video_set_cursor(void)
609352d2591SJean-Christophe PLAGNIOL-VILLARD {
610352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* swap drawing colors */
611352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx;
612352d2591SJean-Christophe PLAGNIOL-VILLARD 	fgx = bgx;
613352d2591SJean-Christophe PLAGNIOL-VILLARD 	bgx = eorx;
614352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx ^ bgx;
615352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* draw cursor */
616352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_putchar(console_col * VIDEO_FONT_WIDTH,
617*64e40d72SWolfgang Denk 		      console_row * VIDEO_FONT_HEIGHT, ' ');
618352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* restore drawing colors */
619352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx;
620352d2591SJean-Christophe PLAGNIOL-VILLARD 	fgx = bgx;
621352d2591SJean-Christophe PLAGNIOL-VILLARD 	bgx = eorx;
622352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx ^ bgx;
623352d2591SJean-Christophe PLAGNIOL-VILLARD }
624352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
625*64e40d72SWolfgang Denk 
626352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_CURSOR
627352d2591SJean-Christophe PLAGNIOL-VILLARD void console_cursor(int state)
628352d2591SJean-Christophe PLAGNIOL-VILLARD {
629352d2591SJean-Christophe PLAGNIOL-VILLARD 	static int last_state = 0;
630352d2591SJean-Christophe PLAGNIOL-VILLARD 
631352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_TIME
632352d2591SJean-Christophe PLAGNIOL-VILLARD 	struct rtc_time tm;
633352d2591SJean-Christophe PLAGNIOL-VILLARD 	char info[16];
634352d2591SJean-Christophe PLAGNIOL-VILLARD 
635352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* time update only if cursor is on (faster scroll) */
636352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (state) {
637352d2591SJean-Christophe PLAGNIOL-VILLARD 		rtc_get(&tm);
638352d2591SJean-Christophe PLAGNIOL-VILLARD 
639352d2591SJean-Christophe PLAGNIOL-VILLARD 		sprintf(info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min,
640352d2591SJean-Christophe PLAGNIOL-VILLARD 			tm.tm_sec);
641352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_drawstring(VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
642352d2591SJean-Christophe PLAGNIOL-VILLARD 				 VIDEO_INFO_Y, (uchar *) info);
643352d2591SJean-Christophe PLAGNIOL-VILLARD 
644352d2591SJean-Christophe PLAGNIOL-VILLARD 		sprintf(info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon,
645352d2591SJean-Christophe PLAGNIOL-VILLARD 			tm.tm_year);
646352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_drawstring(VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
647*64e40d72SWolfgang Denk 				 VIDEO_INFO_Y + 1 * VIDEO_FONT_HEIGHT,
648*64e40d72SWolfgang Denk 				 (uchar *) info);
649352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
650352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
651352d2591SJean-Christophe PLAGNIOL-VILLARD 
652352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (state && (last_state != state)) {
653352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_set_cursor();
654352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
655352d2591SJean-Christophe PLAGNIOL-VILLARD 
656352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (!state && (last_state != state)) {
657352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* clear cursor */
658352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_putchar(console_col * VIDEO_FONT_WIDTH,
659*64e40d72SWolfgang Denk 			      console_row * VIDEO_FONT_HEIGHT, ' ');
660352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
661352d2591SJean-Christophe PLAGNIOL-VILLARD 
662352d2591SJean-Christophe PLAGNIOL-VILLARD 	last_state = state;
663352d2591SJean-Christophe PLAGNIOL-VILLARD }
664352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
665352d2591SJean-Christophe PLAGNIOL-VILLARD 
666352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef VIDEO_HW_RECTFILL
667352d2591SJean-Christophe PLAGNIOL-VILLARD static void memsetl(int *p, int c, int v)
668352d2591SJean-Christophe PLAGNIOL-VILLARD {
669352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (c--)
670352d2591SJean-Christophe PLAGNIOL-VILLARD 		*(p++) = v;
671352d2591SJean-Christophe PLAGNIOL-VILLARD }
672352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
673352d2591SJean-Christophe PLAGNIOL-VILLARD 
674352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef VIDEO_HW_BITBLT
675352d2591SJean-Christophe PLAGNIOL-VILLARD static void memcpyl(int *d, int *s, int c)
676352d2591SJean-Christophe PLAGNIOL-VILLARD {
677352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (c--)
678352d2591SJean-Christophe PLAGNIOL-VILLARD 		*(d++) = *(s++);
679352d2591SJean-Christophe PLAGNIOL-VILLARD }
680352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
681352d2591SJean-Christophe PLAGNIOL-VILLARD 
682352d2591SJean-Christophe PLAGNIOL-VILLARD static void console_scrollup(void)
683352d2591SJean-Christophe PLAGNIOL-VILLARD {
684352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* copy up rows ignoring the first one */
685352d2591SJean-Christophe PLAGNIOL-VILLARD 
686352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_HW_BITBLT
687352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_hw_bitblt(VIDEO_PIXEL_SIZE,	/* bytes per pixel */
688352d2591SJean-Christophe PLAGNIOL-VILLARD 			0,			/* source pos x */
689*64e40d72SWolfgang Denk 			video_logo_height +
690*64e40d72SWolfgang Denk 				VIDEO_FONT_HEIGHT, /* source pos y */
691352d2591SJean-Christophe PLAGNIOL-VILLARD 			0,			/* dest pos x */
692be129aa7SMatthias Weisser 			video_logo_height,	/* dest pos y */
693352d2591SJean-Christophe PLAGNIOL-VILLARD 			VIDEO_VISIBLE_COLS,	/* frame width */
694*64e40d72SWolfgang Denk 			VIDEO_VISIBLE_ROWS
695*64e40d72SWolfgang Denk 			- video_logo_height
696*64e40d72SWolfgang Denk 			- VIDEO_FONT_HEIGHT	/* frame height */
697352d2591SJean-Christophe PLAGNIOL-VILLARD 		);
698352d2591SJean-Christophe PLAGNIOL-VILLARD #else
699352d2591SJean-Christophe PLAGNIOL-VILLARD 	memcpyl(CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND,
700352d2591SJean-Christophe PLAGNIOL-VILLARD 		CONSOLE_SCROLL_SIZE >> 2);
701352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
702352d2591SJean-Christophe PLAGNIOL-VILLARD 
703352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* clear the last one */
704352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_HW_RECTFILL
705352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_hw_rectfill(VIDEO_PIXEL_SIZE,	/* bytes per pixel */
706352d2591SJean-Christophe PLAGNIOL-VILLARD 			  0,			/* dest pos x */
707*64e40d72SWolfgang Denk 			  VIDEO_VISIBLE_ROWS
708*64e40d72SWolfgang Denk 			  - VIDEO_FONT_HEIGHT,	/* dest pos y */
709352d2591SJean-Christophe PLAGNIOL-VILLARD 			  VIDEO_VISIBLE_COLS,	/* frame width */
710352d2591SJean-Christophe PLAGNIOL-VILLARD 			  VIDEO_FONT_HEIGHT,	/* frame height */
711352d2591SJean-Christophe PLAGNIOL-VILLARD 			  CONSOLE_BG_COL	/* fill color */
712352d2591SJean-Christophe PLAGNIOL-VILLARD 		);
713352d2591SJean-Christophe PLAGNIOL-VILLARD #else
714352d2591SJean-Christophe PLAGNIOL-VILLARD 	memsetl(CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
715352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
716352d2591SJean-Christophe PLAGNIOL-VILLARD }
717352d2591SJean-Christophe PLAGNIOL-VILLARD 
718352d2591SJean-Christophe PLAGNIOL-VILLARD static void console_back(void)
719352d2591SJean-Christophe PLAGNIOL-VILLARD {
72065618636STimur Tabi 	CURSOR_OFF;
72165618636STimur Tabi 	console_col--;
722352d2591SJean-Christophe PLAGNIOL-VILLARD 
723352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (console_col < 0) {
724352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_col = CONSOLE_COLS - 1;
725352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_row--;
726352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (console_row < 0)
727352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_row = 0;
728352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
729352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_putchar(console_col * VIDEO_FONT_WIDTH,
730*64e40d72SWolfgang Denk 		      console_row * VIDEO_FONT_HEIGHT, ' ');
731352d2591SJean-Christophe PLAGNIOL-VILLARD }
732352d2591SJean-Christophe PLAGNIOL-VILLARD 
733352d2591SJean-Christophe PLAGNIOL-VILLARD static void console_newline(void)
734352d2591SJean-Christophe PLAGNIOL-VILLARD {
73520c450efSAnatolij Gustschin 	/* Check if last character in the line was just drawn. If so, cursor was
73620c450efSAnatolij Gustschin 	   overwriten and need not to be cleared. Cursor clearing without this
73720c450efSAnatolij Gustschin 	   check causes overwriting the 1st character of the line if line lenght
73820c450efSAnatolij Gustschin 	   is >= CONSOLE_COLS
73920c450efSAnatolij Gustschin 	 */
74020c450efSAnatolij Gustschin 	if (console_col < CONSOLE_COLS)
74165618636STimur Tabi 		CURSOR_OFF;
74220c450efSAnatolij Gustschin 	console_row++;
743352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_col = 0;
744352d2591SJean-Christophe PLAGNIOL-VILLARD 
745352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Check if we need to scroll the terminal */
746352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (console_row >= CONSOLE_ROWS) {
747352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* Scroll everything up */
748352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_scrollup();
749352d2591SJean-Christophe PLAGNIOL-VILLARD 
750352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* Decrement row number */
751352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_row--;
752352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
753352d2591SJean-Christophe PLAGNIOL-VILLARD }
754352d2591SJean-Christophe PLAGNIOL-VILLARD 
75520c450efSAnatolij Gustschin static void console_cr(void)
75620c450efSAnatolij Gustschin {
75765618636STimur Tabi 	CURSOR_OFF;
75865618636STimur Tabi 	console_col = 0;
75920c450efSAnatolij Gustschin }
76020c450efSAnatolij Gustschin 
761352d2591SJean-Christophe PLAGNIOL-VILLARD void video_putc(const char c)
762352d2591SJean-Christophe PLAGNIOL-VILLARD {
76320c450efSAnatolij Gustschin 	static int nl = 1;
76420c450efSAnatolij Gustschin 
765352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (c) {
76620c450efSAnatolij Gustschin 	case 13:		/* back to first column */
76720c450efSAnatolij Gustschin 		console_cr();
768352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
769352d2591SJean-Christophe PLAGNIOL-VILLARD 
770352d2591SJean-Christophe PLAGNIOL-VILLARD 	case '\n':		/* next line */
77120c450efSAnatolij Gustschin 		if (console_col || (!console_col && nl))
772352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_newline();
77320c450efSAnatolij Gustschin 		nl = 1;
774352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
775352d2591SJean-Christophe PLAGNIOL-VILLARD 
776352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 9:		/* tab 8 */
77765618636STimur Tabi 		CURSOR_OFF;
77865618636STimur Tabi 		console_col |= 0x0008;
779352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_col &= ~0x0007;
780352d2591SJean-Christophe PLAGNIOL-VILLARD 
781352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (console_col >= CONSOLE_COLS)
782352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_newline();
783352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
784352d2591SJean-Christophe PLAGNIOL-VILLARD 
785352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 8:		/* backspace */
786352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_back();
787352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
788352d2591SJean-Christophe PLAGNIOL-VILLARD 
789352d2591SJean-Christophe PLAGNIOL-VILLARD 	default:		/* draw the char */
790352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_putchar(console_col * VIDEO_FONT_WIDTH,
791*64e40d72SWolfgang Denk 			      console_row * VIDEO_FONT_HEIGHT, c);
792352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_col++;
793352d2591SJean-Christophe PLAGNIOL-VILLARD 
794352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* check for newline */
79520c450efSAnatolij Gustschin 		if (console_col >= CONSOLE_COLS) {
796352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_newline();
79720c450efSAnatolij Gustschin 			nl = 0;
79820c450efSAnatolij Gustschin 		}
799352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
80065618636STimur Tabi 	CURSOR_SET;
80165618636STimur Tabi }
802352d2591SJean-Christophe PLAGNIOL-VILLARD 
803352d2591SJean-Christophe PLAGNIOL-VILLARD void video_puts(const char *s)
804352d2591SJean-Christophe PLAGNIOL-VILLARD {
805352d2591SJean-Christophe PLAGNIOL-VILLARD 	int count = strlen(s);
806352d2591SJean-Christophe PLAGNIOL-VILLARD 
807352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (count--)
808352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_putc(*s++);
809352d2591SJean-Christophe PLAGNIOL-VILLARD }
810352d2591SJean-Christophe PLAGNIOL-VILLARD 
81110543820SAnatolij Gustschin /*
81210543820SAnatolij Gustschin  * Do not enforce drivers (or board code) to provide empty
81310543820SAnatolij Gustschin  * video_set_lut() if they do not support 8 bpp format.
81410543820SAnatolij Gustschin  * Implement weak default function instead.
81510543820SAnatolij Gustschin  */
81610543820SAnatolij Gustschin void __video_set_lut(unsigned int index, unsigned char r,
81710543820SAnatolij Gustschin 		     unsigned char g, unsigned char b)
81810543820SAnatolij Gustschin {
81910543820SAnatolij Gustschin }
820*64e40d72SWolfgang Denk 
82110543820SAnatolij Gustschin void video_set_lut(unsigned int, unsigned char, unsigned char, unsigned char)
82210543820SAnatolij Gustschin 	__attribute__ ((weak, alias("__video_set_lut")));
82310543820SAnatolij Gustschin 
824352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
825352d2591SJean-Christophe PLAGNIOL-VILLARD 
826352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_8BIT_332RGB(r,g,b)	{			\
827352d2591SJean-Christophe PLAGNIOL-VILLARD 	*fb = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6);	\
828352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb ++;						\
829352d2591SJean-Christophe PLAGNIOL-VILLARD }
830352d2591SJean-Christophe PLAGNIOL-VILLARD 
831352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_15BIT_555RGB(r,g,b) {			\
832*64e40d72SWolfgang Denk 	*(unsigned short *)fb =				\
833*64e40d72SWolfgang Denk 		SWAP16((unsigned short)(((r>>3)<<10) |	\
834*64e40d72SWolfgang Denk 					((g>>3)<<5)  |	\
835*64e40d72SWolfgang Denk 					 (b>>3)));	\
836352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 2;					\
837352d2591SJean-Christophe PLAGNIOL-VILLARD }
838352d2591SJean-Christophe PLAGNIOL-VILLARD 
839352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_16BIT_565RGB(r,g,b) {			\
840*64e40d72SWolfgang Denk 	*(unsigned short *)fb =				\
841*64e40d72SWolfgang Denk 		SWAP16((unsigned short)((((r)>>3)<<11)| \
842*64e40d72SWolfgang Denk 					(((g)>>2)<<5) | \
843*64e40d72SWolfgang Denk 					 ((b)>>3)));	\
844352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 2;					\
845352d2591SJean-Christophe PLAGNIOL-VILLARD }
846352d2591SJean-Christophe PLAGNIOL-VILLARD 
847352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_32BIT_X888RGB(r,g,b) {			\
848*64e40d72SWolfgang Denk 	*(unsigned long *)fb =				\
849*64e40d72SWolfgang Denk 		SWAP32((unsigned long)(((r<<16) |	\
850*64e40d72SWolfgang Denk 					(g<<8)  |	\
851*64e40d72SWolfgang Denk 					 b)));		\
852352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 4;					\
853352d2591SJean-Christophe PLAGNIOL-VILLARD }
854352d2591SJean-Christophe PLAGNIOL-VILLARD 
855352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_FB_LITTLE_ENDIAN
856352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_24BIT_888RGB(r,g,b) {			\
857352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[0] = b;					\
858352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[1] = g;					\
859352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[2] = r;					\
860352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 3;					\
861352d2591SJean-Christophe PLAGNIOL-VILLARD }
862352d2591SJean-Christophe PLAGNIOL-VILLARD #else
863352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_24BIT_888RGB(r,g,b) {			\
864352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[0] = r;					\
865352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[1] = g;					\
866352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[2] = b;					\
867352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 3;					\
868352d2591SJean-Christophe PLAGNIOL-VILLARD }
869352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
870352d2591SJean-Christophe PLAGNIOL-VILLARD 
871e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
872*64e40d72SWolfgang Denk static inline void fill_555rgb_pswap(uchar *fb, int x, u8 r, u8 g, u8 b)
873e84d568fSAnatolij Gustschin {
874e84d568fSAnatolij Gustschin 	ushort *dst = (ushort *) fb;
875e84d568fSAnatolij Gustschin 	ushort color = (ushort) (((r >> 3) << 10) |
876e84d568fSAnatolij Gustschin 				 ((g >> 3) <<  5) |
877e84d568fSAnatolij Gustschin 				  (b >> 3));
878e84d568fSAnatolij Gustschin 	if (x & 1)
879e84d568fSAnatolij Gustschin 		*(--dst) = color;
880e84d568fSAnatolij Gustschin 	else
881e84d568fSAnatolij Gustschin 		*(++dst) = color;
882e84d568fSAnatolij Gustschin }
883e84d568fSAnatolij Gustschin #endif
884352d2591SJean-Christophe PLAGNIOL-VILLARD 
885352d2591SJean-Christophe PLAGNIOL-VILLARD /*
886d5011762SAnatolij Gustschin  * RLE8 bitmap support
887d5011762SAnatolij Gustschin  */
888d5011762SAnatolij Gustschin 
889d5011762SAnatolij Gustschin #ifdef CONFIG_VIDEO_BMP_RLE8
890d5011762SAnatolij Gustschin /* Pre-calculated color table entry */
891d5011762SAnatolij Gustschin struct palette {
892d5011762SAnatolij Gustschin 	union {
893d5011762SAnatolij Gustschin 		unsigned short w;	/* word */
894d5011762SAnatolij Gustschin 		unsigned int dw;	/* double word */
895d5011762SAnatolij Gustschin 	} ce;				/* color entry */
896d5011762SAnatolij Gustschin };
897d5011762SAnatolij Gustschin 
898d5011762SAnatolij Gustschin /*
899d5011762SAnatolij Gustschin  * Helper to draw encoded/unencoded run.
900d5011762SAnatolij Gustschin  */
901d5011762SAnatolij Gustschin static void draw_bitmap(uchar **fb, uchar *bm, struct palette *p,
902d5011762SAnatolij Gustschin 			int cnt, int enc)
903d5011762SAnatolij Gustschin {
904d5011762SAnatolij Gustschin 	ulong addr = (ulong) *fb;
905d5011762SAnatolij Gustschin 	int *off;
906d5011762SAnatolij Gustschin 	int enc_off = 1;
907d5011762SAnatolij Gustschin 	int i;
908d5011762SAnatolij Gustschin 
909d5011762SAnatolij Gustschin 	/*
910d5011762SAnatolij Gustschin 	 * Setup offset of the color index in the bitmap.
911d5011762SAnatolij Gustschin 	 * Color index of encoded run is at offset 1.
912d5011762SAnatolij Gustschin 	 */
913d5011762SAnatolij Gustschin 	off = enc ? &enc_off : &i;
914d5011762SAnatolij Gustschin 
915d5011762SAnatolij Gustschin 	switch (VIDEO_DATA_FORMAT) {
916d5011762SAnatolij Gustschin 	case GDF__8BIT_INDEX:
917d5011762SAnatolij Gustschin 		for (i = 0; i < cnt; i++)
918d5011762SAnatolij Gustschin 			*(unsigned char *) addr++ = bm[*off];
919d5011762SAnatolij Gustschin 		break;
920d5011762SAnatolij Gustschin 	case GDF_15BIT_555RGB:
921d5011762SAnatolij Gustschin 	case GDF_16BIT_565RGB:
922d5011762SAnatolij Gustschin 		/* differences handled while pre-calculating palette */
923d5011762SAnatolij Gustschin 		for (i = 0; i < cnt; i++) {
924d5011762SAnatolij Gustschin 			*(unsigned short *) addr = p[bm[*off]].ce.w;
925d5011762SAnatolij Gustschin 			addr += 2;
926d5011762SAnatolij Gustschin 		}
927d5011762SAnatolij Gustschin 		break;
928d5011762SAnatolij Gustschin 	case GDF_32BIT_X888RGB:
929d5011762SAnatolij Gustschin 		for (i = 0; i < cnt; i++) {
930d5011762SAnatolij Gustschin 			*(unsigned long *) addr = p[bm[*off]].ce.dw;
931d5011762SAnatolij Gustschin 			addr += 4;
932d5011762SAnatolij Gustschin 		}
933d5011762SAnatolij Gustschin 		break;
934d5011762SAnatolij Gustschin 	}
935d5011762SAnatolij Gustschin 	*fb = (uchar *) addr;	/* return modified address */
936d5011762SAnatolij Gustschin }
937d5011762SAnatolij Gustschin 
938d5011762SAnatolij Gustschin static int display_rle8_bitmap(bmp_image_t *img, int xoff, int yoff,
939d5011762SAnatolij Gustschin 			       int width, int height)
940d5011762SAnatolij Gustschin {
941d5011762SAnatolij Gustschin 	unsigned char *bm;
942d5011762SAnatolij Gustschin 	unsigned char *fbp;
943d5011762SAnatolij Gustschin 	unsigned int cnt, runlen;
944d5011762SAnatolij Gustschin 	int decode = 1;
945d5011762SAnatolij Gustschin 	int x, y, bpp, i, ncolors;
946d5011762SAnatolij Gustschin 	struct palette p[256];
947d5011762SAnatolij Gustschin 	bmp_color_table_entry_t cte;
948d5011762SAnatolij Gustschin 	int green_shift, red_off;
94974446b63SAnatolij Gustschin 	int limit = VIDEO_COLS * VIDEO_ROWS;
95074446b63SAnatolij Gustschin 	int pixels = 0;
951d5011762SAnatolij Gustschin 
952d5011762SAnatolij Gustschin 	x = 0;
953d5011762SAnatolij Gustschin 	y = __le32_to_cpu(img->header.height) - 1;
954d5011762SAnatolij Gustschin 	ncolors = __le32_to_cpu(img->header.colors_used);
955d5011762SAnatolij Gustschin 	bpp = VIDEO_PIXEL_SIZE;
956d5011762SAnatolij Gustschin 	fbp = (unsigned char *) ((unsigned int) video_fb_address +
957d5011762SAnatolij Gustschin 				 (((y + yoff) * VIDEO_COLS) + xoff) * bpp);
958d5011762SAnatolij Gustschin 
959d5011762SAnatolij Gustschin 	bm = (uchar *) img + __le32_to_cpu(img->header.data_offset);
960d5011762SAnatolij Gustschin 
961d5011762SAnatolij Gustschin 	/* pre-calculate and setup palette */
962d5011762SAnatolij Gustschin 	switch (VIDEO_DATA_FORMAT) {
963d5011762SAnatolij Gustschin 	case GDF__8BIT_INDEX:
964d5011762SAnatolij Gustschin 		for (i = 0; i < ncolors; i++) {
965d5011762SAnatolij Gustschin 			cte = img->color_table[i];
966d5011762SAnatolij Gustschin 			video_set_lut(i, cte.red, cte.green, cte.blue);
967d5011762SAnatolij Gustschin 		}
968d5011762SAnatolij Gustschin 		break;
969d5011762SAnatolij Gustschin 	case GDF_15BIT_555RGB:
970d5011762SAnatolij Gustschin 	case GDF_16BIT_565RGB:
971d5011762SAnatolij Gustschin 		if (VIDEO_DATA_FORMAT == GDF_15BIT_555RGB) {
972d5011762SAnatolij Gustschin 			green_shift = 3;
973d5011762SAnatolij Gustschin 			red_off = 10;
974d5011762SAnatolij Gustschin 		} else {
975d5011762SAnatolij Gustschin 			green_shift = 2;
976d5011762SAnatolij Gustschin 			red_off = 11;
977d5011762SAnatolij Gustschin 		}
978d5011762SAnatolij Gustschin 		for (i = 0; i < ncolors; i++) {
979d5011762SAnatolij Gustschin 			cte = img->color_table[i];
980d5011762SAnatolij Gustschin 			p[i].ce.w = SWAP16((unsigned short)
981d5011762SAnatolij Gustschin 					   (((cte.red >> 3) << red_off) |
982d5011762SAnatolij Gustschin 					    ((cte.green >> green_shift) << 5) |
983d5011762SAnatolij Gustschin 					    cte.blue >> 3));
984d5011762SAnatolij Gustschin 		}
985d5011762SAnatolij Gustschin 		break;
986d5011762SAnatolij Gustschin 	case GDF_32BIT_X888RGB:
987d5011762SAnatolij Gustschin 		for (i = 0; i < ncolors; i++) {
988d5011762SAnatolij Gustschin 			cte = img->color_table[i];
989*64e40d72SWolfgang Denk 			p[i].ce.dw = SWAP32((cte.red << 16) |
990*64e40d72SWolfgang Denk 					    (cte.green << 8) |
991d5011762SAnatolij Gustschin 					     cte.blue);
992d5011762SAnatolij Gustschin 		}
993d5011762SAnatolij Gustschin 		break;
994d5011762SAnatolij Gustschin 	default:
995d5011762SAnatolij Gustschin 		printf("RLE Bitmap unsupported in video mode 0x%x\n",
996d5011762SAnatolij Gustschin 		       VIDEO_DATA_FORMAT);
997d5011762SAnatolij Gustschin 		return -1;
998d5011762SAnatolij Gustschin 	}
999d5011762SAnatolij Gustschin 
1000d5011762SAnatolij Gustschin 	while (decode) {
1001d5011762SAnatolij Gustschin 		switch (bm[0]) {
1002d5011762SAnatolij Gustschin 		case 0:
1003d5011762SAnatolij Gustschin 			switch (bm[1]) {
1004d5011762SAnatolij Gustschin 			case 0:
1005d5011762SAnatolij Gustschin 				/* scan line end marker */
1006d5011762SAnatolij Gustschin 				bm += 2;
1007d5011762SAnatolij Gustschin 				x = 0;
1008d5011762SAnatolij Gustschin 				y--;
1009d5011762SAnatolij Gustschin 				fbp = (unsigned char *)
1010d5011762SAnatolij Gustschin 					((unsigned int) video_fb_address +
1011d5011762SAnatolij Gustschin 					 (((y + yoff) * VIDEO_COLS) +
1012d5011762SAnatolij Gustschin 					  xoff) * bpp);
1013d5011762SAnatolij Gustschin 				continue;
1014d5011762SAnatolij Gustschin 			case 1:
1015d5011762SAnatolij Gustschin 				/* end of bitmap data marker */
1016d5011762SAnatolij Gustschin 				decode = 0;
1017d5011762SAnatolij Gustschin 				break;
1018d5011762SAnatolij Gustschin 			case 2:
1019d5011762SAnatolij Gustschin 				/* run offset marker */
1020d5011762SAnatolij Gustschin 				x += bm[2];
1021d5011762SAnatolij Gustschin 				y -= bm[3];
1022d5011762SAnatolij Gustschin 				fbp = (unsigned char *)
1023d5011762SAnatolij Gustschin 					((unsigned int) video_fb_address +
1024d5011762SAnatolij Gustschin 					 (((y + yoff) * VIDEO_COLS) +
1025d5011762SAnatolij Gustschin 					  x + xoff) * bpp);
1026d5011762SAnatolij Gustschin 				bm += 4;
1027d5011762SAnatolij Gustschin 				break;
1028d5011762SAnatolij Gustschin 			default:
1029d5011762SAnatolij Gustschin 				/* unencoded run */
1030d5011762SAnatolij Gustschin 				cnt = bm[1];
1031d5011762SAnatolij Gustschin 				runlen = cnt;
103274446b63SAnatolij Gustschin 				pixels += cnt;
103374446b63SAnatolij Gustschin 				if (pixels > limit)
103474446b63SAnatolij Gustschin 					goto error;
103574446b63SAnatolij Gustschin 
1036d5011762SAnatolij Gustschin 				bm += 2;
1037d5011762SAnatolij Gustschin 				if (y < height) {
1038d5011762SAnatolij Gustschin 					if (x >= width) {
1039d5011762SAnatolij Gustschin 						x += runlen;
1040d5011762SAnatolij Gustschin 						goto next_run;
1041d5011762SAnatolij Gustschin 					}
1042d5011762SAnatolij Gustschin 					if (x + runlen > width)
1043d5011762SAnatolij Gustschin 						cnt = width - x;
1044d5011762SAnatolij Gustschin 					draw_bitmap(&fbp, bm, p, cnt, 0);
1045d5011762SAnatolij Gustschin 					x += runlen;
1046d5011762SAnatolij Gustschin 				}
1047d5011762SAnatolij Gustschin next_run:
1048d5011762SAnatolij Gustschin 				bm += runlen;
1049d5011762SAnatolij Gustschin 				if (runlen & 1)
1050d5011762SAnatolij Gustschin 					bm++;	/* 0 padding if length is odd */
1051d5011762SAnatolij Gustschin 			}
1052d5011762SAnatolij Gustschin 			break;
1053d5011762SAnatolij Gustschin 		default:
1054d5011762SAnatolij Gustschin 			/* encoded run */
1055d5011762SAnatolij Gustschin 			cnt = bm[0];
1056d5011762SAnatolij Gustschin 			runlen = cnt;
105774446b63SAnatolij Gustschin 			pixels += cnt;
105874446b63SAnatolij Gustschin 			if (pixels > limit)
105974446b63SAnatolij Gustschin 				goto error;
106074446b63SAnatolij Gustschin 
106174446b63SAnatolij Gustschin 			if (y < height) {     /* only draw into visible area */
1062d5011762SAnatolij Gustschin 				if (x >= width) {
1063d5011762SAnatolij Gustschin 					x += runlen;
1064d5011762SAnatolij Gustschin 					bm += 2;
1065d5011762SAnatolij Gustschin 					continue;
1066d5011762SAnatolij Gustschin 				}
1067d5011762SAnatolij Gustschin 				if (x + runlen > width)
1068d5011762SAnatolij Gustschin 					cnt = width - x;
1069d5011762SAnatolij Gustschin 				draw_bitmap(&fbp, bm, p, cnt, 1);
1070d5011762SAnatolij Gustschin 				x += runlen;
1071d5011762SAnatolij Gustschin 			}
1072d5011762SAnatolij Gustschin 			bm += 2;
1073d5011762SAnatolij Gustschin 			break;
1074d5011762SAnatolij Gustschin 		}
1075d5011762SAnatolij Gustschin 	}
1076d5011762SAnatolij Gustschin 	return 0;
107774446b63SAnatolij Gustschin error:
107874446b63SAnatolij Gustschin 	printf("Error: Too much encoded pixel data, validate your bitmap\n");
107974446b63SAnatolij Gustschin 	return -1;
1080d5011762SAnatolij Gustschin }
1081d5011762SAnatolij Gustschin #endif
1082d5011762SAnatolij Gustschin 
1083d5011762SAnatolij Gustschin /*
1084352d2591SJean-Christophe PLAGNIOL-VILLARD  * Display the BMP file located at address bmp_image.
1085352d2591SJean-Christophe PLAGNIOL-VILLARD  */
1086352d2591SJean-Christophe PLAGNIOL-VILLARD int video_display_bitmap(ulong bmp_image, int x, int y)
1087352d2591SJean-Christophe PLAGNIOL-VILLARD {
1088352d2591SJean-Christophe PLAGNIOL-VILLARD 	ushort xcount, ycount;
1089352d2591SJean-Christophe PLAGNIOL-VILLARD 	uchar *fb;
1090352d2591SJean-Christophe PLAGNIOL-VILLARD 	bmp_image_t *bmp = (bmp_image_t *) bmp_image;
1091352d2591SJean-Christophe PLAGNIOL-VILLARD 	uchar *bmap;
1092352d2591SJean-Christophe PLAGNIOL-VILLARD 	ushort padded_line;
1093352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned long width, height, bpp;
1094352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned colors;
1095352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned long compression;
1096352d2591SJean-Christophe PLAGNIOL-VILLARD 	bmp_color_table_entry_t cte;
1097*64e40d72SWolfgang Denk 
1098352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_GZIP
1099352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char *dst = NULL;
1100352d2591SJean-Christophe PLAGNIOL-VILLARD 	ulong len;
1101352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1102352d2591SJean-Christophe PLAGNIOL-VILLARD 
1103352d2591SJean-Christophe PLAGNIOL-VILLARD 	WATCHDOG_RESET();
1104352d2591SJean-Christophe PLAGNIOL-VILLARD 
1105352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (!((bmp->header.signature[0] == 'B') &&
1106352d2591SJean-Christophe PLAGNIOL-VILLARD 	      (bmp->header.signature[1] == 'M'))) {
1107352d2591SJean-Christophe PLAGNIOL-VILLARD 
1108352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_GZIP
1109352d2591SJean-Christophe PLAGNIOL-VILLARD 		/*
1110352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * Could be a gzipped bmp image, try to decrompress...
1111352d2591SJean-Christophe PLAGNIOL-VILLARD 		 */
11126d0f6bcfSJean-Christophe PLAGNIOL-VILLARD 		len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
11136d0f6bcfSJean-Christophe PLAGNIOL-VILLARD 		dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
1114352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (dst == NULL) {
1115352d2591SJean-Christophe PLAGNIOL-VILLARD 			printf("Error: malloc in gunzip failed!\n");
1116*64e40d72SWolfgang Denk 			return 1;
1117352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1118*64e40d72SWolfgang Denk 		if (gunzip(dst, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE,
1119*64e40d72SWolfgang Denk 			   (uchar *) bmp_image,
1120*64e40d72SWolfgang Denk 			   &len) != 0) {
1121*64e40d72SWolfgang Denk 			printf("Error: no valid bmp or bmp.gz image at %lx\n",
1122*64e40d72SWolfgang Denk 			       bmp_image);
1123352d2591SJean-Christophe PLAGNIOL-VILLARD 			free(dst);
1124352d2591SJean-Christophe PLAGNIOL-VILLARD 			return 1;
1125352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
11266d0f6bcfSJean-Christophe PLAGNIOL-VILLARD 		if (len == CONFIG_SYS_VIDEO_LOGO_MAX_SIZE) {
1127*64e40d72SWolfgang Denk 			printf("Image could be truncated "
1128*64e40d72SWolfgang Denk 				"(increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n");
1129352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1130352d2591SJean-Christophe PLAGNIOL-VILLARD 
1131352d2591SJean-Christophe PLAGNIOL-VILLARD 		/*
1132352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * Set addr to decompressed image
1133352d2591SJean-Christophe PLAGNIOL-VILLARD 		 */
1134352d2591SJean-Christophe PLAGNIOL-VILLARD 		bmp = (bmp_image_t *) dst;
1135352d2591SJean-Christophe PLAGNIOL-VILLARD 
1136352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (!((bmp->header.signature[0] == 'B') &&
1137352d2591SJean-Christophe PLAGNIOL-VILLARD 		      (bmp->header.signature[1] == 'M'))) {
1138*64e40d72SWolfgang Denk 			printf("Error: no valid bmp.gz image at %lx\n",
1139*64e40d72SWolfgang Denk 			       bmp_image);
1140a49e0d17SMatthias Fuchs 			free(dst);
1141352d2591SJean-Christophe PLAGNIOL-VILLARD 			return 1;
1142352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1143352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1144352d2591SJean-Christophe PLAGNIOL-VILLARD 		printf("Error: no valid bmp image at %lx\n", bmp_image);
1145352d2591SJean-Christophe PLAGNIOL-VILLARD 		return 1;
1146352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_BMP_GZIP */
1147352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1148352d2591SJean-Christophe PLAGNIOL-VILLARD 
1149352d2591SJean-Christophe PLAGNIOL-VILLARD 	width = le32_to_cpu(bmp->header.width);
1150352d2591SJean-Christophe PLAGNIOL-VILLARD 	height = le32_to_cpu(bmp->header.height);
1151352d2591SJean-Christophe PLAGNIOL-VILLARD 	bpp = le16_to_cpu(bmp->header.bit_count);
1152352d2591SJean-Christophe PLAGNIOL-VILLARD 	colors = le32_to_cpu(bmp->header.colors_used);
1153352d2591SJean-Christophe PLAGNIOL-VILLARD 	compression = le32_to_cpu(bmp->header.compression);
1154352d2591SJean-Christophe PLAGNIOL-VILLARD 
1155352d2591SJean-Christophe PLAGNIOL-VILLARD 	debug("Display-bmp: %d x %d  with %d colors\n",
1156352d2591SJean-Christophe PLAGNIOL-VILLARD 	      width, height, colors);
1157352d2591SJean-Christophe PLAGNIOL-VILLARD 
1158d5011762SAnatolij Gustschin 	if (compression != BMP_BI_RGB
1159d5011762SAnatolij Gustschin #ifdef CONFIG_VIDEO_BMP_RLE8
1160d5011762SAnatolij Gustschin 	    && compression != BMP_BI_RLE8
1161d5011762SAnatolij Gustschin #endif
1162d5011762SAnatolij Gustschin 		) {
1163352d2591SJean-Christophe PLAGNIOL-VILLARD 		printf("Error: compression type %ld not supported\n",
1164352d2591SJean-Christophe PLAGNIOL-VILLARD 		       compression);
1165a49e0d17SMatthias Fuchs #ifdef CONFIG_VIDEO_BMP_GZIP
1166a49e0d17SMatthias Fuchs 		if (dst)
1167a49e0d17SMatthias Fuchs 			free(dst);
1168a49e0d17SMatthias Fuchs #endif
1169352d2591SJean-Christophe PLAGNIOL-VILLARD 		return 1;
1170352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1171352d2591SJean-Christophe PLAGNIOL-VILLARD 
1172352d2591SJean-Christophe PLAGNIOL-VILLARD 	padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3;
1173352d2591SJean-Christophe PLAGNIOL-VILLARD 
11741ca298ceSMatthias Weisser #ifdef CONFIG_SPLASH_SCREEN_ALIGN
11751ca298ceSMatthias Weisser 	if (x == BMP_ALIGN_CENTER)
11761ca298ceSMatthias Weisser 		x = max(0, (VIDEO_VISIBLE_COLS - width) / 2);
11771ca298ceSMatthias Weisser 	else if (x < 0)
11781ca298ceSMatthias Weisser 		x = max(0, VIDEO_VISIBLE_COLS - width + x + 1);
11791ca298ceSMatthias Weisser 
11801ca298ceSMatthias Weisser 	if (y == BMP_ALIGN_CENTER)
11811ca298ceSMatthias Weisser 		y = max(0, (VIDEO_VISIBLE_ROWS - height) / 2);
11821ca298ceSMatthias Weisser 	else if (y < 0)
11831ca298ceSMatthias Weisser 		y = max(0, VIDEO_VISIBLE_ROWS - height + y + 1);
11841ca298ceSMatthias Weisser #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
11851ca298ceSMatthias Weisser 
1186352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((x + width) > VIDEO_VISIBLE_COLS)
1187352d2591SJean-Christophe PLAGNIOL-VILLARD 		width = VIDEO_VISIBLE_COLS - x;
1188352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((y + height) > VIDEO_VISIBLE_ROWS)
1189352d2591SJean-Christophe PLAGNIOL-VILLARD 		height = VIDEO_VISIBLE_ROWS - y;
1190352d2591SJean-Christophe PLAGNIOL-VILLARD 
1191352d2591SJean-Christophe PLAGNIOL-VILLARD 	bmap = (uchar *) bmp + le32_to_cpu(bmp->header.data_offset);
1192352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb = (uchar *) (video_fb_address +
1193352d2591SJean-Christophe PLAGNIOL-VILLARD 			((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) +
1194352d2591SJean-Christophe PLAGNIOL-VILLARD 			x * VIDEO_PIXEL_SIZE);
1195352d2591SJean-Christophe PLAGNIOL-VILLARD 
1196d5011762SAnatolij Gustschin #ifdef CONFIG_VIDEO_BMP_RLE8
1197d5011762SAnatolij Gustschin 	if (compression == BMP_BI_RLE8) {
1198*64e40d72SWolfgang Denk 		return display_rle8_bitmap(bmp, x, y, width, height);
1199d5011762SAnatolij Gustschin 	}
1200d5011762SAnatolij Gustschin #endif
1201d5011762SAnatolij Gustschin 
120268f6618bSTimur Tabi 	/* We handle only 4, 8, or 24 bpp bitmaps */
1203352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (le16_to_cpu(bmp->header.bit_count)) {
120468f6618bSTimur Tabi 	case 4:
120568f6618bSTimur Tabi 		padded_line -= width / 2;
120668f6618bSTimur Tabi 		ycount = height;
120768f6618bSTimur Tabi 
120868f6618bSTimur Tabi 		switch (VIDEO_DATA_FORMAT) {
120968f6618bSTimur Tabi 		case GDF_32BIT_X888RGB:
121068f6618bSTimur Tabi 			while (ycount--) {
121168f6618bSTimur Tabi 				WATCHDOG_RESET();
121268f6618bSTimur Tabi 				/*
121368f6618bSTimur Tabi 				 * Don't assume that 'width' is an
121468f6618bSTimur Tabi 				 * even number
121568f6618bSTimur Tabi 				 */
121668f6618bSTimur Tabi 				for (xcount = 0; xcount < width; xcount++) {
121768f6618bSTimur Tabi 					uchar idx;
121868f6618bSTimur Tabi 
121968f6618bSTimur Tabi 					if (xcount & 1) {
122068f6618bSTimur Tabi 						idx = *bmap & 0xF;
122168f6618bSTimur Tabi 						bmap++;
122268f6618bSTimur Tabi 					} else
122368f6618bSTimur Tabi 						idx = *bmap >> 4;
122468f6618bSTimur Tabi 					cte = bmp->color_table[idx];
122568f6618bSTimur Tabi 					FILL_32BIT_X888RGB(cte.red, cte.green,
122668f6618bSTimur Tabi 							   cte.blue);
122768f6618bSTimur Tabi 				}
122868f6618bSTimur Tabi 				bmap += padded_line;
122968f6618bSTimur Tabi 				fb -= (VIDEO_VISIBLE_COLS + width) *
123068f6618bSTimur Tabi 					VIDEO_PIXEL_SIZE;
123168f6618bSTimur Tabi 			}
123268f6618bSTimur Tabi 			break;
123368f6618bSTimur Tabi 		default:
123468f6618bSTimur Tabi 			puts("4bpp bitmap unsupported with current "
123568f6618bSTimur Tabi 			     "video mode\n");
123668f6618bSTimur Tabi 			break;
123768f6618bSTimur Tabi 		}
123868f6618bSTimur Tabi 		break;
123968f6618bSTimur Tabi 
1240352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 8:
1241352d2591SJean-Christophe PLAGNIOL-VILLARD 		padded_line -= width;
1242352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
1243352d2591SJean-Christophe PLAGNIOL-VILLARD 			/* Copy colormap */
1244352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (xcount = 0; xcount < colors; ++xcount) {
1245352d2591SJean-Christophe PLAGNIOL-VILLARD 				cte = bmp->color_table[xcount];
1246*64e40d72SWolfgang Denk 				video_set_lut(xcount, cte.red, cte.green,
1247*64e40d72SWolfgang Denk 					      cte.blue);
1248352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1249352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1250352d2591SJean-Christophe PLAGNIOL-VILLARD 		ycount = height;
1251352d2591SJean-Christophe PLAGNIOL-VILLARD 		switch (VIDEO_DATA_FORMAT) {
1252352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF__8BIT_INDEX:
1253352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1254352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1255352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1256352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1257352d2591SJean-Christophe PLAGNIOL-VILLARD 					*fb++ = *bmap++;
1258352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1259352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1260*64e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
1261*64e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1262352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1263352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1264352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF__8BIT_332RGB:
1265352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1266352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1267352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1268352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1269352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
1270*64e40d72SWolfgang Denk 					FILL_8BIT_332RGB(cte.red, cte.green,
1271*64e40d72SWolfgang Denk 							 cte.blue);
1272352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1273352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1274*64e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
1275*64e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1276352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1277352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1278352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_15BIT_555RGB:
1279352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1280e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1281e84d568fSAnatolij Gustschin 				int xpos = x;
1282e84d568fSAnatolij Gustschin #endif
1283352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1284352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1285352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1286352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
1287cc347801SAndrew Dyer #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1288e84d568fSAnatolij Gustschin 					fill_555rgb_pswap(fb, xpos++, cte.red,
1289*64e40d72SWolfgang Denk 							  cte.green,
1290*64e40d72SWolfgang Denk 							  cte.blue);
1291e84d568fSAnatolij Gustschin 					fb += 2;
1292cc347801SAndrew Dyer #else
1293*64e40d72SWolfgang Denk 					FILL_15BIT_555RGB(cte.red, cte.green,
1294*64e40d72SWolfgang Denk 							  cte.blue);
1295e84d568fSAnatolij Gustschin #endif
1296352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1297352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1298*64e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
1299*64e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1300352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1301352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1302352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_16BIT_565RGB:
1303352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1304352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1305352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1306352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1307352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
1308*64e40d72SWolfgang Denk 					FILL_16BIT_565RGB(cte.red, cte.green,
1309*64e40d72SWolfgang Denk 							  cte.blue);
1310352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1311352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1312*64e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
1313*64e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1314352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1315352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1316352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_32BIT_X888RGB:
1317352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1318352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1319352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1320352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1321352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
1322*64e40d72SWolfgang Denk 					FILL_32BIT_X888RGB(cte.red, cte.green,
1323*64e40d72SWolfgang Denk 							   cte.blue);
1324352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1325352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1326*64e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
1327*64e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1328352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1329352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1330352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_24BIT_888RGB:
1331352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1332352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1333352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1334352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1335352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
1336*64e40d72SWolfgang Denk 					FILL_24BIT_888RGB(cte.red, cte.green,
1337*64e40d72SWolfgang Denk 							  cte.blue);
1338352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1339352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1340*64e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
1341*64e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1342352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1343352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1344352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1345352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1346352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 24:
1347352d2591SJean-Christophe PLAGNIOL-VILLARD 		padded_line -= 3 * width;
1348352d2591SJean-Christophe PLAGNIOL-VILLARD 		ycount = height;
1349352d2591SJean-Christophe PLAGNIOL-VILLARD 		switch (VIDEO_DATA_FORMAT) {
1350352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF__8BIT_332RGB:
1351352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1352352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1353352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1354352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1355*64e40d72SWolfgang Denk 					FILL_8BIT_332RGB(bmap[2], bmap[1],
1356*64e40d72SWolfgang Denk 							 bmap[0]);
1357352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1358352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1359352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1360*64e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
1361*64e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1362352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1363352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1364352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_15BIT_555RGB:
1365352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1366e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1367e84d568fSAnatolij Gustschin 				int xpos = x;
1368e84d568fSAnatolij Gustschin #endif
1369352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1370352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1371352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1372cc347801SAndrew Dyer #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1373e84d568fSAnatolij Gustschin 					fill_555rgb_pswap(fb, xpos++, bmap[2],
1374e84d568fSAnatolij Gustschin 							  bmap[1], bmap[0]);
1375e84d568fSAnatolij Gustschin 					fb += 2;
1376cc347801SAndrew Dyer #else
1377*64e40d72SWolfgang Denk 					FILL_15BIT_555RGB(bmap[2], bmap[1],
1378*64e40d72SWolfgang Denk 							  bmap[0]);
1379e84d568fSAnatolij Gustschin #endif
1380352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1381352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1382352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1383*64e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
1384*64e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1385352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1386352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1387352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_16BIT_565RGB:
1388352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1389352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1390352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1391352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1392*64e40d72SWolfgang Denk 					FILL_16BIT_565RGB(bmap[2], bmap[1],
1393*64e40d72SWolfgang Denk 							  bmap[0]);
1394352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1395352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1396352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1397*64e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
1398*64e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1399352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1400352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1401352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_32BIT_X888RGB:
1402352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1403352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1404352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1405352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1406*64e40d72SWolfgang Denk 					FILL_32BIT_X888RGB(bmap[2], bmap[1],
1407*64e40d72SWolfgang Denk 							   bmap[0]);
1408352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1409352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1410352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1411*64e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
1412*64e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1413352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1414352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1415352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_24BIT_888RGB:
1416352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1417352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1418352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1419352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1420*64e40d72SWolfgang Denk 					FILL_24BIT_888RGB(bmap[2], bmap[1],
1421*64e40d72SWolfgang Denk 							  bmap[0]);
1422352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1423352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1424352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1425*64e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
1426*64e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1427352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1428352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1429352d2591SJean-Christophe PLAGNIOL-VILLARD 		default:
1430*64e40d72SWolfgang Denk 			printf("Error: 24 bits/pixel bitmap incompatible "
1431*64e40d72SWolfgang Denk 				"with current video mode\n");
1432352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1433352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1434352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1435352d2591SJean-Christophe PLAGNIOL-VILLARD 	default:
1436352d2591SJean-Christophe PLAGNIOL-VILLARD 		printf("Error: %d bit/pixel bitmaps not supported by U-Boot\n",
1437352d2591SJean-Christophe PLAGNIOL-VILLARD 			le16_to_cpu(bmp->header.bit_count));
1438352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1439352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1440352d2591SJean-Christophe PLAGNIOL-VILLARD 
1441352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_GZIP
1442352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (dst) {
1443352d2591SJean-Christophe PLAGNIOL-VILLARD 		free(dst);
1444352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1445352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1446352d2591SJean-Christophe PLAGNIOL-VILLARD 
1447352d2591SJean-Christophe PLAGNIOL-VILLARD 	return (0);
1448352d2591SJean-Christophe PLAGNIOL-VILLARD }
1449352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1450352d2591SJean-Christophe PLAGNIOL-VILLARD 
1451352d2591SJean-Christophe PLAGNIOL-VILLARD 
1452352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_LOGO
1453352d2591SJean-Christophe PLAGNIOL-VILLARD void logo_plot(void *screen, int width, int x, int y)
1454352d2591SJean-Christophe PLAGNIOL-VILLARD {
1455352d2591SJean-Christophe PLAGNIOL-VILLARD 
1456352d2591SJean-Christophe PLAGNIOL-VILLARD 	int xcount, i;
1457352d2591SJean-Christophe PLAGNIOL-VILLARD 	int skip = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE;
1458be129aa7SMatthias Weisser 	int ycount = video_logo_height;
1459352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char r, g, b, *logo_red, *logo_blue, *logo_green;
1460352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char *source;
1461d9015f6aSAnatolij Gustschin 	unsigned char *dest = (unsigned char *) screen +
1462*64e40d72SWolfgang Denk 		((y * width * VIDEO_PIXEL_SIZE) + x * VIDEO_PIXEL_SIZE);
1463352d2591SJean-Christophe PLAGNIOL-VILLARD 
1464352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_LOGO
1465352d2591SJean-Christophe PLAGNIOL-VILLARD 	source = bmp_logo_bitmap;
1466352d2591SJean-Christophe PLAGNIOL-VILLARD 
1467352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Allocate temporary space for computing colormap */
1468352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_red = malloc(BMP_LOGO_COLORS);
1469352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_green = malloc(BMP_LOGO_COLORS);
1470352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_blue = malloc(BMP_LOGO_COLORS);
1471352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Compute color map */
1472352d2591SJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
1473352d2591SJean-Christophe PLAGNIOL-VILLARD 		logo_red[i] = (bmp_logo_palette[i] & 0x0f00) >> 4;
1474352d2591SJean-Christophe PLAGNIOL-VILLARD 		logo_green[i] = (bmp_logo_palette[i] & 0x00f0);
1475352d2591SJean-Christophe PLAGNIOL-VILLARD 		logo_blue[i] = (bmp_logo_palette[i] & 0x000f) << 4;
1476352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1477352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1478352d2591SJean-Christophe PLAGNIOL-VILLARD 	source = linux_logo;
1479352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_red = linux_logo_red;
1480352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_green = linux_logo_green;
1481352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_blue = linux_logo_blue;
1482352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1483352d2591SJean-Christophe PLAGNIOL-VILLARD 
1484352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
1485352d2591SJean-Christophe PLAGNIOL-VILLARD 		for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
1486352d2591SJean-Christophe PLAGNIOL-VILLARD 			video_set_lut(i + VIDEO_LOGO_LUT_OFFSET,
1487*64e40d72SWolfgang Denk 				      logo_red[i], logo_green[i],
1488*64e40d72SWolfgang Denk 				      logo_blue[i]);
1489352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1490352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1491352d2591SJean-Christophe PLAGNIOL-VILLARD 
1492352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (ycount--) {
1493e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1494e84d568fSAnatolij Gustschin 		int xpos = x;
1495e84d568fSAnatolij Gustschin #endif
1496352d2591SJean-Christophe PLAGNIOL-VILLARD 		xcount = VIDEO_LOGO_WIDTH;
1497352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (xcount--) {
1498352d2591SJean-Christophe PLAGNIOL-VILLARD 			r = logo_red[*source - VIDEO_LOGO_LUT_OFFSET];
1499352d2591SJean-Christophe PLAGNIOL-VILLARD 			g = logo_green[*source - VIDEO_LOGO_LUT_OFFSET];
1500352d2591SJean-Christophe PLAGNIOL-VILLARD 			b = logo_blue[*source - VIDEO_LOGO_LUT_OFFSET];
1501352d2591SJean-Christophe PLAGNIOL-VILLARD 
1502352d2591SJean-Christophe PLAGNIOL-VILLARD 			switch (VIDEO_DATA_FORMAT) {
1503352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF__8BIT_INDEX:
1504352d2591SJean-Christophe PLAGNIOL-VILLARD 				*dest = *source;
1505352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1506352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF__8BIT_332RGB:
1507*64e40d72SWolfgang Denk 				*dest = ((r >> 5) << 5) |
1508*64e40d72SWolfgang Denk 					((g >> 5) << 2) |
1509*64e40d72SWolfgang Denk 					 (b >> 6);
1510352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1511352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_15BIT_555RGB:
1512cc347801SAndrew Dyer #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1513cc347801SAndrew Dyer 				fill_555rgb_pswap(dest, xpos++, r, g, b);
1514cc347801SAndrew Dyer #else
1515352d2591SJean-Christophe PLAGNIOL-VILLARD 				*(unsigned short *) dest =
1516*64e40d72SWolfgang Denk 					SWAP16((unsigned short) (
1517*64e40d72SWolfgang Denk 							((r >> 3) << 10) |
1518*64e40d72SWolfgang Denk 							((g >> 3) <<  5) |
1519*64e40d72SWolfgang Denk 							 (b >> 3)));
1520bed53753SAnatolij Gustschin #endif
1521352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1522352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_16BIT_565RGB:
1523352d2591SJean-Christophe PLAGNIOL-VILLARD 				*(unsigned short *) dest =
1524*64e40d72SWolfgang Denk 					SWAP16((unsigned short) (
1525*64e40d72SWolfgang Denk 							((r >> 3) << 11) |
1526*64e40d72SWolfgang Denk 							((g >> 2) <<  5) |
1527*64e40d72SWolfgang Denk 							 (b >> 3)));
1528352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1529352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_32BIT_X888RGB:
1530352d2591SJean-Christophe PLAGNIOL-VILLARD 				*(unsigned long *) dest =
1531*64e40d72SWolfgang Denk 					SWAP32((unsigned long) (
1532*64e40d72SWolfgang Denk 							(r << 16) |
1533*64e40d72SWolfgang Denk 							(g <<  8) |
1534*64e40d72SWolfgang Denk 							 b));
1535352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1536352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_24BIT_888RGB:
1537352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_FB_LITTLE_ENDIAN
1538352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[0] = b;
1539352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[1] = g;
1540352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[2] = r;
1541352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1542352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[0] = r;
1543352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[1] = g;
1544352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[2] = b;
1545352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1546352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1547352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1548352d2591SJean-Christophe PLAGNIOL-VILLARD 			source++;
1549352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest += VIDEO_PIXEL_SIZE;
1550352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1551352d2591SJean-Christophe PLAGNIOL-VILLARD 		dest += skip;
1552352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1553352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_LOGO
1554352d2591SJean-Christophe PLAGNIOL-VILLARD 	free(logo_red);
1555352d2591SJean-Christophe PLAGNIOL-VILLARD 	free(logo_green);
1556352d2591SJean-Christophe PLAGNIOL-VILLARD 	free(logo_blue);
1557352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1558352d2591SJean-Christophe PLAGNIOL-VILLARD }
1559352d2591SJean-Christophe PLAGNIOL-VILLARD 
1560352d2591SJean-Christophe PLAGNIOL-VILLARD static void *video_logo(void)
1561352d2591SJean-Christophe PLAGNIOL-VILLARD {
1562352d2591SJean-Christophe PLAGNIOL-VILLARD 	char info[128];
15633dcbe628SAnatolij Gustschin 	int space, len, y_off = 0;
1564352d2591SJean-Christophe PLAGNIOL-VILLARD 
1565352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SPLASH_SCREEN
1566352d2591SJean-Christophe PLAGNIOL-VILLARD 	char *s;
1567352d2591SJean-Christophe PLAGNIOL-VILLARD 	ulong addr;
1568352d2591SJean-Christophe PLAGNIOL-VILLARD 
1569352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((s = getenv("splashimage")) != NULL) {
15701ca298ceSMatthias Weisser 		int x = 0, y = 0;
1571352d2591SJean-Christophe PLAGNIOL-VILLARD 
15721ca298ceSMatthias Weisser 		addr = simple_strtoul(s, NULL, 16);
15731ca298ceSMatthias Weisser #ifdef CONFIG_SPLASH_SCREEN_ALIGN
15741ca298ceSMatthias Weisser 		if ((s = getenv("splashpos")) != NULL) {
15751ca298ceSMatthias Weisser 			if (s[0] == 'm')
15761ca298ceSMatthias Weisser 				x = BMP_ALIGN_CENTER;
15771ca298ceSMatthias Weisser 			else
15781ca298ceSMatthias Weisser 				x = simple_strtol(s, NULL, 0);
15791ca298ceSMatthias Weisser 
15801ca298ceSMatthias Weisser 			if ((s = strchr(s + 1, ',')) != NULL) {
15811ca298ceSMatthias Weisser 				if (s[1] == 'm')
15821ca298ceSMatthias Weisser 					y = BMP_ALIGN_CENTER;
15831ca298ceSMatthias Weisser 				else
15841ca298ceSMatthias Weisser 					y = simple_strtol(s + 1, NULL, 0);
15851ca298ceSMatthias Weisser 			}
15861ca298ceSMatthias Weisser 		}
15871ca298ceSMatthias Weisser #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
15881ca298ceSMatthias Weisser 
15891ca298ceSMatthias Weisser 		if (video_display_bitmap(addr, x, y) == 0) {
1590be129aa7SMatthias Weisser 			video_logo_height = 0;
1591352d2591SJean-Christophe PLAGNIOL-VILLARD 			return ((void *) (video_fb_address));
1592352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1593352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1594352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_SPLASH_SCREEN */
1595352d2591SJean-Christophe PLAGNIOL-VILLARD 
1596352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_plot(video_fb_address, VIDEO_COLS, 0, 0);
1597352d2591SJean-Christophe PLAGNIOL-VILLARD 
1598ce0f709bSAndreas Bießmann 	sprintf(info, " %s", version_string);
15993dcbe628SAnatolij Gustschin 
16003dcbe628SAnatolij Gustschin 	space = (VIDEO_LINE_LEN / 2 - VIDEO_INFO_X) / VIDEO_FONT_WIDTH;
16013dcbe628SAnatolij Gustschin 	len = strlen(info);
16023dcbe628SAnatolij Gustschin 
16033dcbe628SAnatolij Gustschin 	if (len > space) {
16043dcbe628SAnatolij Gustschin 		video_drawchars(VIDEO_INFO_X, VIDEO_INFO_Y,
16053dcbe628SAnatolij Gustschin 				(uchar *) info, space);
16063dcbe628SAnatolij Gustschin 		video_drawchars(VIDEO_INFO_X + VIDEO_FONT_WIDTH,
16073dcbe628SAnatolij Gustschin 				VIDEO_INFO_Y + VIDEO_FONT_HEIGHT,
16083dcbe628SAnatolij Gustschin 				(uchar *) info + space, len - space);
16093dcbe628SAnatolij Gustschin 		y_off = 1;
16103dcbe628SAnatolij Gustschin 	} else
1611352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_drawstring(VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *) info);
1612352d2591SJean-Christophe PLAGNIOL-VILLARD 
1613352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_EXTRA_INFO
1614352d2591SJean-Christophe PLAGNIOL-VILLARD 	{
1615*64e40d72SWolfgang Denk 		int i, n =
1616*64e40d72SWolfgang Denk 			((video_logo_height -
1617*64e40d72SWolfgang Denk 			  VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT);
1618352d2591SJean-Christophe PLAGNIOL-VILLARD 
1619352d2591SJean-Christophe PLAGNIOL-VILLARD 		for (i = 1; i < n; i++) {
1620352d2591SJean-Christophe PLAGNIOL-VILLARD 			video_get_info_str(i, info);
16213dcbe628SAnatolij Gustschin 			if (!*info)
16223dcbe628SAnatolij Gustschin 				continue;
16233dcbe628SAnatolij Gustschin 
16243dcbe628SAnatolij Gustschin 			len = strlen(info);
16253dcbe628SAnatolij Gustschin 			if (len > space) {
16263dcbe628SAnatolij Gustschin 				video_drawchars(VIDEO_INFO_X,
16273dcbe628SAnatolij Gustschin 						VIDEO_INFO_Y +
1628*64e40d72SWolfgang Denk 						(i + y_off) *
1629*64e40d72SWolfgang Denk 							VIDEO_FONT_HEIGHT,
16303dcbe628SAnatolij Gustschin 						(uchar *) info, space);
16313dcbe628SAnatolij Gustschin 				y_off++;
1632*64e40d72SWolfgang Denk 				video_drawchars(VIDEO_INFO_X +
1633*64e40d72SWolfgang Denk 						VIDEO_FONT_WIDTH,
16343dcbe628SAnatolij Gustschin 						VIDEO_INFO_Y +
1635*64e40d72SWolfgang Denk 							(i + y_off) *
1636*64e40d72SWolfgang Denk 							VIDEO_FONT_HEIGHT,
16373dcbe628SAnatolij Gustschin 						(uchar *) info + space,
16383dcbe628SAnatolij Gustschin 						len - space);
16393dcbe628SAnatolij Gustschin 			} else {
1640352d2591SJean-Christophe PLAGNIOL-VILLARD 				video_drawstring(VIDEO_INFO_X,
16413dcbe628SAnatolij Gustschin 						 VIDEO_INFO_Y +
1642*64e40d72SWolfgang Denk 						 (i + y_off) *
1643*64e40d72SWolfgang Denk 							VIDEO_FONT_HEIGHT,
1644352d2591SJean-Christophe PLAGNIOL-VILLARD 						 (uchar *) info);
1645352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1646352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
16473dcbe628SAnatolij Gustschin 	}
1648352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1649352d2591SJean-Christophe PLAGNIOL-VILLARD 
1650be129aa7SMatthias Weisser 	return (video_fb_address + video_logo_height * VIDEO_LINE_LEN);
1651352d2591SJean-Christophe PLAGNIOL-VILLARD }
1652352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1653352d2591SJean-Christophe PLAGNIOL-VILLARD 
1654352d2591SJean-Christophe PLAGNIOL-VILLARD static int video_init(void)
1655352d2591SJean-Christophe PLAGNIOL-VILLARD {
1656352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char color8;
1657352d2591SJean-Christophe PLAGNIOL-VILLARD 
1658352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((pGD = video_hw_init()) == NULL)
1659352d2591SJean-Christophe PLAGNIOL-VILLARD 		return -1;
1660352d2591SJean-Christophe PLAGNIOL-VILLARD 
1661352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_fb_address = (void *) VIDEO_FB_ADRS;
1662352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_HW_CURSOR
1663352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_init_hw_cursor(VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
1664352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1665352d2591SJean-Christophe PLAGNIOL-VILLARD 
1666352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Init drawing pats */
1667352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (VIDEO_DATA_FORMAT) {
1668352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_INDEX:
1669*64e40d72SWolfgang Denk 		video_set_lut(0x01, CONSOLE_FG_COL, CONSOLE_FG_COL,
1670*64e40d72SWolfgang Denk 			      CONSOLE_FG_COL);
1671*64e40d72SWolfgang Denk 		video_set_lut(0x00, CONSOLE_BG_COL, CONSOLE_BG_COL,
1672*64e40d72SWolfgang Denk 			      CONSOLE_BG_COL);
1673352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = 0x01010101;
1674352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = 0x00000000;
1675352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1676352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_332RGB:
1677352d2591SJean-Christophe PLAGNIOL-VILLARD 		color8 = ((CONSOLE_FG_COL & 0xe0) |
1678*64e40d72SWolfgang Denk 			  ((CONSOLE_FG_COL >> 3) & 0x1c) |
1679*64e40d72SWolfgang Denk 			  CONSOLE_FG_COL >> 6);
1680*64e40d72SWolfgang Denk 		fgx = (color8 << 24) | (color8 << 16) | (color8 << 8) |
1681*64e40d72SWolfgang Denk 			color8;
1682352d2591SJean-Christophe PLAGNIOL-VILLARD 		color8 = ((CONSOLE_BG_COL & 0xe0) |
1683*64e40d72SWolfgang Denk 			  ((CONSOLE_BG_COL >> 3) & 0x1c) |
1684*64e40d72SWolfgang Denk 			  CONSOLE_BG_COL >> 6);
1685*64e40d72SWolfgang Denk 		bgx = (color8 << 24) | (color8 << 16) | (color8 << 8) |
1686*64e40d72SWolfgang Denk 			color8;
1687352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1688352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_15BIT_555RGB:
1689352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = (((CONSOLE_FG_COL >> 3) << 26) |
1690*64e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) << 21) |
1691*64e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) << 16) |
1692*64e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) << 10) |
1693*64e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) <<  5) |
1694352d2591SJean-Christophe PLAGNIOL-VILLARD 			(CONSOLE_FG_COL >> 3));
1695352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = (((CONSOLE_BG_COL >> 3) << 26) |
1696*64e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) << 21) |
1697*64e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) << 16) |
1698*64e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) << 10) |
1699*64e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) <<  5) |
1700352d2591SJean-Christophe PLAGNIOL-VILLARD 			(CONSOLE_BG_COL >> 3));
1701352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1702352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_16BIT_565RGB:
1703352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = (((CONSOLE_FG_COL >> 3) << 27) |
1704*64e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 2) << 21) |
1705*64e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) << 16) |
1706*64e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) << 11) |
1707*64e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 2) <<  5) |
1708352d2591SJean-Christophe PLAGNIOL-VILLARD 			(CONSOLE_FG_COL >> 3));
1709352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = (((CONSOLE_BG_COL >> 3) << 27) |
1710*64e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 2) << 21) |
1711*64e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) << 16) |
1712*64e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) << 11) |
1713*64e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 2) <<  5) |
1714352d2591SJean-Christophe PLAGNIOL-VILLARD 			(CONSOLE_BG_COL >> 3));
1715352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1716352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_32BIT_X888RGB:
1717*64e40d72SWolfgang Denk 		fgx =	(CONSOLE_FG_COL << 16) |
1718*64e40d72SWolfgang Denk 			(CONSOLE_FG_COL <<  8) |
1719*64e40d72SWolfgang Denk 			 CONSOLE_FG_COL;
1720*64e40d72SWolfgang Denk 		bgx =	(CONSOLE_BG_COL << 16) |
1721*64e40d72SWolfgang Denk 			(CONSOLE_BG_COL <<  8) |
1722*64e40d72SWolfgang Denk 			 CONSOLE_BG_COL;
1723352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1724352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_24BIT_888RGB:
1725*64e40d72SWolfgang Denk 		fgx =	(CONSOLE_FG_COL << 24) |
1726*64e40d72SWolfgang Denk 			(CONSOLE_FG_COL << 16) |
1727*64e40d72SWolfgang Denk 			(CONSOLE_FG_COL <<  8) |
1728*64e40d72SWolfgang Denk 			 CONSOLE_FG_COL;
1729*64e40d72SWolfgang Denk 		bgx =	(CONSOLE_BG_COL << 24) |
1730*64e40d72SWolfgang Denk 			(CONSOLE_BG_COL << 16) |
1731*64e40d72SWolfgang Denk 			(CONSOLE_BG_COL <<  8) |
1732*64e40d72SWolfgang Denk 			 CONSOLE_BG_COL;
1733352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1734352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1735352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx ^ bgx;
1736352d2591SJean-Christophe PLAGNIOL-VILLARD 
1737352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_LOGO
1738352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Plot the logo and get start point of console */
1739352d2591SJean-Christophe PLAGNIOL-VILLARD 	PRINTD("Video: Drawing the logo ...\n");
1740352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_console_address = video_logo();
1741352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1742352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_console_address = video_fb_address;
1743352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1744352d2591SJean-Christophe PLAGNIOL-VILLARD 
1745352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Initialize the console */
1746352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_col = 0;
1747352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_row = 0;
1748352d2591SJean-Christophe PLAGNIOL-VILLARD 
1749352d2591SJean-Christophe PLAGNIOL-VILLARD 	return 0;
1750352d2591SJean-Christophe PLAGNIOL-VILLARD }
1751352d2591SJean-Christophe PLAGNIOL-VILLARD 
17526cc7ba9eSWolfgang Denk /*
17536cc7ba9eSWolfgang Denk  * Implement a weak default function for boards that optionally
17546cc7ba9eSWolfgang Denk  * need to skip the video initialization.
17556cc7ba9eSWolfgang Denk  */
17566cc7ba9eSWolfgang Denk int __board_video_skip(void)
17576cc7ba9eSWolfgang Denk {
17586cc7ba9eSWolfgang Denk 	/* As default, don't skip test */
17596cc7ba9eSWolfgang Denk 	return 0;
17606cc7ba9eSWolfgang Denk }
1761*64e40d72SWolfgang Denk 
1762*64e40d72SWolfgang Denk int board_video_skip(void)
1763*64e40d72SWolfgang Denk 	__attribute__ ((weak, alias("__board_video_skip")));
17646cc7ba9eSWolfgang Denk 
1765352d2591SJean-Christophe PLAGNIOL-VILLARD int drv_video_init(void)
1766352d2591SJean-Christophe PLAGNIOL-VILLARD {
1767352d2591SJean-Christophe PLAGNIOL-VILLARD 	int skip_dev_init;
176852cb4d4fSJean-Christophe PLAGNIOL-VILLARD 	struct stdio_dev console_dev;
1769352d2591SJean-Christophe PLAGNIOL-VILLARD 
17706cc7ba9eSWolfgang Denk 	/* Check if video initialization should be skipped */
17716cc7ba9eSWolfgang Denk 	if (board_video_skip())
17726cc7ba9eSWolfgang Denk 		return 0;
17736cc7ba9eSWolfgang Denk 
1774352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Init video chip - returns with framebuffer cleared */
1775f62f6469SWolfgang Denk 	skip_dev_init = (video_init() == -1);
1776352d2591SJean-Christophe PLAGNIOL-VILLARD 
1777f62f6469SWolfgang Denk #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
1778f62f6469SWolfgang Denk 	PRINTD("KBD: Keyboard init ...\n");
1779f62f6469SWolfgang Denk 	skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
1780f62f6469SWolfgang Denk #endif
1781f62f6469SWolfgang Denk 
1782f62f6469SWolfgang Denk 	if (skip_dev_init)
1783f62f6469SWolfgang Denk 		return 0;
1784f62f6469SWolfgang Denk 
1785352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Init vga device */
1786352d2591SJean-Christophe PLAGNIOL-VILLARD 	memset(&console_dev, 0, sizeof(console_dev));
1787352d2591SJean-Christophe PLAGNIOL-VILLARD 	strcpy(console_dev.name, "vga");
1788352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.ext = DEV_EXT_VIDEO;	/* Video extensions */
1789352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
1790352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.putc = video_putc;	/* 'putc' function */
1791352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.puts = video_puts;	/* 'puts' function */
1792352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.tstc = NULL;	/* 'tstc' function */
1793352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.getc = NULL;	/* 'getc' function */
1794352d2591SJean-Christophe PLAGNIOL-VILLARD 
1795f62f6469SWolfgang Denk #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
1796f62f6469SWolfgang Denk 	/* Also init console device */
1797f62f6469SWolfgang Denk 	console_dev.flags |= DEV_FLAGS_INPUT;
1798352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.tstc = VIDEO_TSTC_FCT;	/* 'tstc' function */
1799352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.getc = VIDEO_GETC_FCT;	/* 'getc' function */
1800352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
1801f62f6469SWolfgang Denk 
180252cb4d4fSJean-Christophe PLAGNIOL-VILLARD 	if (stdio_register(&console_dev) != 0)
1803352d2591SJean-Christophe PLAGNIOL-VILLARD 		return 0;
1804f62f6469SWolfgang Denk 
1805f62f6469SWolfgang Denk 	/* Return success */
1806f62f6469SWolfgang Denk 	return 1;
1807352d2591SJean-Christophe PLAGNIOL-VILLARD }
1808