xref: /rk3399_rockchip-uboot/drivers/video/cfb_console.c (revision d3983ee85325d2be730830ebcf82585ee7cd2ecb)
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
3264e40d72SWolfgang 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.
3964e40d72SWolfgang Denk  *
4064e40d72SWolfgang Denk  * The driver uses graphic specific defines/parameters/functions:
4164e40d72SWolfgang Denk  *
4264e40d72SWolfgang Denk  * (for SMI LynxE graphic chip)
4364e40d72SWolfgang Denk  *
4464e40d72SWolfgang Denk  * CONFIG_VIDEO_SMI_LYNXEM    - use graphic driver for SMI 710,712,810
4564e40d72SWolfgang Denk  * VIDEO_FB_LITTLE_ENDIAN     - framebuffer organisation default: big endian
4664e40d72SWolfgang Denk  * VIDEO_HW_RECTFILL	      - graphic driver supports hardware rectangle fill
4764e40d72SWolfgang Denk  * VIDEO_HW_BITBLT	      - graphic driver supports hardware bit blt
4864e40d72SWolfgang Denk  *
4964e40d72SWolfgang Denk  * Console Parameters are set by graphic drivers global struct:
5064e40d72SWolfgang Denk  *
5164e40d72SWolfgang Denk  * VIDEO_VISIBLE_COLS	      - x resolution
5264e40d72SWolfgang Denk  * VIDEO_VISIBLE_ROWS	      - y resolution
5364e40d72SWolfgang Denk  * VIDEO_PIXEL_SIZE	      - storage size in byte per pixel
5464e40d72SWolfgang Denk  * VIDEO_DATA_FORMAT	      - graphical data format GDF
5564e40d72SWolfgang Denk  * VIDEO_FB_ADRS	      - start of video memory
5664e40d72SWolfgang Denk  *
5764e40d72SWolfgang Denk  * CONFIG_I8042_KBD	      - AT Keyboard driver for i8042
5864e40d72SWolfgang Denk  * VIDEO_KBD_INIT_FCT	      - init function for keyboard
5964e40d72SWolfgang Denk  * VIDEO_TSTC_FCT	      - keyboard_tstc function
6064e40d72SWolfgang Denk  * VIDEO_GETC_FCT	      - keyboard_getc function
6164e40d72SWolfgang Denk  *
6264e40d72SWolfgang Denk  * CONFIG_CONSOLE_CURSOR      - on/off drawing cursor is done with
6364e40d72SWolfgang Denk  *				delay loop in VIDEO_TSTC_FCT (i8042)
6464e40d72SWolfgang Denk  *
6564e40d72SWolfgang Denk  * CONFIG_SYS_CONSOLE_BLINK_COUNT - value for delay loop - blink rate
6664e40d72SWolfgang Denk  * CONFIG_CONSOLE_TIME	      - display time/date in upper right
6764e40d72SWolfgang Denk  *				corner, needs CONFIG_CMD_DATE and
6864e40d72SWolfgang Denk  *				CONFIG_CONSOLE_CURSOR
6964e40d72SWolfgang Denk  * CONFIG_VIDEO_LOGO	      - display Linux Logo in upper left corner
7064e40d72SWolfgang Denk  * CONFIG_VIDEO_BMP_LOGO      - use bmp_logo instead of linux_logo
7164e40d72SWolfgang Denk  * CONFIG_CONSOLE_EXTRA_INFO  - display additional board information
7264e40d72SWolfgang Denk  *				strings that normaly goes to serial
7364e40d72SWolfgang Denk  *				port.  This define requires a board
7464e40d72SWolfgang Denk  *				specific function:
7564e40d72SWolfgang Denk  *				video_drawstring (VIDEO_INFO_X,
7664e40d72SWolfgang Denk  *					VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
7764e40d72SWolfgang Denk  *					info);
7864e40d72SWolfgang Denk  *				that fills a info buffer at i=row.
7964e40d72SWolfgang Denk  *				s.a: board/eltec/bab7xx.
8064e40d72SWolfgang Denk  * CONFIG_VGA_AS_SINGLE_DEVICE - If set the framebuffer device will be
8164e40d72SWolfgang Denk  *				initialized as an output only device.
8264e40d72SWolfgang Denk  *				The Keyboard driver will not be
8364e40d72SWolfgang Denk  *				set-up.  This may be used, if you have
8464e40d72SWolfgang Denk  *				no or more than one Keyboard devices
8564e40d72SWolfgang Denk  *				(USB Keyboard, AT Keyboard).
8664e40d72SWolfgang Denk  *
8764e40d72SWolfgang Denk  * CONFIG_VIDEO_SW_CURSOR:    - Draws a cursor after the last
8864e40d72SWolfgang Denk  *				character. No blinking is provided.
8964e40d72SWolfgang Denk  *				Uses the macros CURSOR_SET and
9064e40d72SWolfgang Denk  *				CURSOR_OFF.
9164e40d72SWolfgang Denk  *
9264e40d72SWolfgang Denk  * CONFIG_VIDEO_HW_CURSOR:    - Uses the hardware cursor capability
9364e40d72SWolfgang Denk  *				of the graphic chip. Uses the macro
9464e40d72SWolfgang Denk  *				CURSOR_SET. ATTENTION: If booting an
9564e40d72SWolfgang Denk  *				OS, the display driver must disable
9664e40d72SWolfgang Denk  *				the hardware register of the graphic
9764e40d72SWolfgang Denk  *				chip. Otherwise a blinking field is
9864e40d72SWolfgang 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>
104a9a62af1SWolfgang Denk #include <linux/compiler.h>
105352d2591SJean-Christophe PLAGNIOL-VILLARD 
10664e40d72SWolfgang Denk /*
10764e40d72SWolfgang Denk  * Console device defines with SMI graphic
10864e40d72SWolfgang Denk  * Any other graphic must change this section
10964e40d72SWolfgang Denk  */
110352d2591SJean-Christophe PLAGNIOL-VILLARD 
111352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_SMI_LYNXEM
112352d2591SJean-Christophe PLAGNIOL-VILLARD 
113352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
114352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_RECTFILL
115352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_BITBLT
116352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
117352d2591SJean-Christophe PLAGNIOL-VILLARD 
11864e40d72SWolfgang Denk /*
11964e40d72SWolfgang Denk  * Defines for the CT69000 driver
12064e40d72SWolfgang Denk  */
121352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_CT69000
122352d2591SJean-Christophe PLAGNIOL-VILLARD 
123352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
124352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_RECTFILL
125352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_BITBLT
126352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
127352d2591SJean-Christophe PLAGNIOL-VILLARD 
12864e40d72SWolfgang Denk /*
12964e40d72SWolfgang Denk  * Defines for the SED13806 driver
13064e40d72SWolfgang Denk  */
131352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_SED13806
132352d2591SJean-Christophe PLAGNIOL-VILLARD 
133352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_TOTAL5200
134352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
135352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
136352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_RECTFILL
137352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_BITBLT
138352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
139352d2591SJean-Christophe PLAGNIOL-VILLARD 
14064e40d72SWolfgang Denk /*
14164e40d72SWolfgang Denk  * Defines for the SED13806 driver
14264e40d72SWolfgang Denk  */
143352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_SM501
144352d2591SJean-Christophe PLAGNIOL-VILLARD 
145352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_HH405
146352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
147352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
148352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
149352d2591SJean-Christophe PLAGNIOL-VILLARD 
15064e40d72SWolfgang Denk /*
15164e40d72SWolfgang Denk  * Defines for the MB862xx driver
15264e40d72SWolfgang Denk  */
153bed53753SAnatolij Gustschin #ifdef CONFIG_VIDEO_MB862xx
154bed53753SAnatolij Gustschin 
155bed53753SAnatolij Gustschin #ifdef CONFIG_VIDEO_CORALP
156bed53753SAnatolij Gustschin #define VIDEO_FB_LITTLE_ENDIAN
157bed53753SAnatolij Gustschin #endif
1585d16ca87SAnatolij Gustschin #ifdef CONFIG_VIDEO_MB862xx_ACCEL
159bed53753SAnatolij Gustschin #define VIDEO_HW_RECTFILL
160bed53753SAnatolij Gustschin #define VIDEO_HW_BITBLT
161bed53753SAnatolij Gustschin #endif
1625d16ca87SAnatolij Gustschin #endif
163bed53753SAnatolij Gustschin 
16464e40d72SWolfgang Denk /*
16562a22dcaSHelmut Raiger  * Defines for the i.MX31 driver (mx3fb.c)
16662a22dcaSHelmut Raiger  */
16762a22dcaSHelmut Raiger #ifdef CONFIG_VIDEO_MX3
16862a22dcaSHelmut Raiger #define VIDEO_FB_16BPP_WORD_SWAP
16962a22dcaSHelmut Raiger #endif
17062a22dcaSHelmut Raiger 
17162a22dcaSHelmut Raiger /*
17264e40d72SWolfgang Denk  * Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc.
17364e40d72SWolfgang Denk  */
174352d2591SJean-Christophe PLAGNIOL-VILLARD #include <video_fb.h>
175352d2591SJean-Christophe PLAGNIOL-VILLARD 
17664e40d72SWolfgang Denk /*
17764e40d72SWolfgang Denk  * some Macros
17864e40d72SWolfgang Denk  */
179352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_VISIBLE_COLS	(pGD->winSizeX)
180352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_VISIBLE_ROWS	(pGD->winSizeY)
181352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_PIXEL_SIZE	(pGD->gdfBytesPP)
182352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_DATA_FORMAT	(pGD->gdfIndex)
183352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_ADRS		(pGD->frameAdrs)
184352d2591SJean-Christophe PLAGNIOL-VILLARD 
18564e40d72SWolfgang Denk /*
18664e40d72SWolfgang Denk  * Console device defines with i8042 keyboard controller
18764e40d72SWolfgang Denk  * Any other keyboard controller must change this section
18864e40d72SWolfgang Denk  */
189352d2591SJean-Christophe PLAGNIOL-VILLARD 
190352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_I8042_KBD
191352d2591SJean-Christophe PLAGNIOL-VILLARD #include <i8042.h>
192352d2591SJean-Christophe PLAGNIOL-VILLARD 
193352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_KBD_INIT_FCT	i8042_kbd_init()
194352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_TSTC_FCT		i8042_tstc
195352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_GETC_FCT		i8042_getc
196352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
197352d2591SJean-Christophe PLAGNIOL-VILLARD 
19864e40d72SWolfgang Denk /*
19964e40d72SWolfgang Denk  * Console device
20064e40d72SWolfgang Denk  */
201352d2591SJean-Christophe PLAGNIOL-VILLARD 
202352d2591SJean-Christophe PLAGNIOL-VILLARD #include <version.h>
203352d2591SJean-Christophe PLAGNIOL-VILLARD #include <linux/types.h>
20452cb4d4fSJean-Christophe PLAGNIOL-VILLARD #include <stdio_dev.h>
205352d2591SJean-Christophe PLAGNIOL-VILLARD #include <video_font.h>
206*d3983ee8SChe-Liang Chiou #include <video_font_data.h>
207352d2591SJean-Christophe PLAGNIOL-VILLARD 
208352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CMD_DATE)
209352d2591SJean-Christophe PLAGNIOL-VILLARD #include <rtc.h>
210352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
211352d2591SJean-Christophe PLAGNIOL-VILLARD 
212352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
213352d2591SJean-Christophe PLAGNIOL-VILLARD #include <watchdog.h>
214352d2591SJean-Christophe PLAGNIOL-VILLARD #include <bmp_layout.h>
2151ca298ceSMatthias Weisser 
2161ca298ceSMatthias Weisser #ifdef CONFIG_SPLASH_SCREEN_ALIGN
2171ca298ceSMatthias Weisser #define BMP_ALIGN_CENTER	0x7FFF
2181ca298ceSMatthias Weisser #endif
2191ca298ceSMatthias Weisser 
220352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
221352d2591SJean-Christophe PLAGNIOL-VILLARD 
22264e40d72SWolfgang Denk /*
22364e40d72SWolfgang Denk  * Cursor definition:
22464e40d72SWolfgang Denk  * CONFIG_CONSOLE_CURSOR:  Uses a timer function (see drivers/input/i8042.c)
22564e40d72SWolfgang Denk  *			   to let the cursor blink. Uses the macros
22664e40d72SWolfgang Denk  *			   CURSOR_OFF and CURSOR_ON.
22764e40d72SWolfgang Denk  * CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No
22864e40d72SWolfgang Denk  *			   blinking is provided. Uses the macros CURSOR_SET
22964e40d72SWolfgang Denk  *			   and CURSOR_OFF.
23064e40d72SWolfgang Denk  * CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the
23164e40d72SWolfgang Denk  *			   graphic chip. Uses the macro CURSOR_SET.
23264e40d72SWolfgang Denk  *			   ATTENTION: If booting an OS, the display driver
23364e40d72SWolfgang Denk  *			   must disable the hardware register of the graphic
23464e40d72SWolfgang Denk  *			   chip. Otherwise a blinking field is displayed
23564e40d72SWolfgang Denk  */
236352d2591SJean-Christophe PLAGNIOL-VILLARD #if !defined(CONFIG_CONSOLE_CURSOR) && \
237352d2591SJean-Christophe PLAGNIOL-VILLARD     !defined(CONFIG_VIDEO_SW_CURSOR) && \
238352d2591SJean-Christophe PLAGNIOL-VILLARD     !defined(CONFIG_VIDEO_HW_CURSOR)
239352d2591SJean-Christophe PLAGNIOL-VILLARD /* no Cursor defined */
240352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_ON
241352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_OFF
242352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_SET
243352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
244352d2591SJean-Christophe PLAGNIOL-VILLARD 
245352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_CONSOLE_CURSOR
246352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CURSOR_ON
24764e40d72SWolfgang Denk #error	only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \
24864e40d72SWolfgang Denk 	or CONFIG_VIDEO_HW_CURSOR can be defined
249352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
250352d2591SJean-Christophe PLAGNIOL-VILLARD void console_cursor(int state);
25164e40d72SWolfgang Denk 
25265618636STimur Tabi #define CURSOR_ON  console_cursor(1)
25365618636STimur Tabi #define CURSOR_OFF console_cursor(0)
254352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_SET
255352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_I8042_KBD
2567817cb20SMarcel Ziswiler #warning Cursor drawing on/off needs timer function s.a. drivers/input/i8042.c
257352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
258352d2591SJean-Christophe PLAGNIOL-VILLARD #else
259352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_CONSOLE_TIME
260352d2591SJean-Christophe PLAGNIOL-VILLARD #error	CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME
261352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
262352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_CONSOLE_CURSOR */
263352d2591SJean-Christophe PLAGNIOL-VILLARD 
264352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_SW_CURSOR
265352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CURSOR_ON
26664e40d72SWolfgang Denk #error	only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \
26764e40d72SWolfgang Denk 	or CONFIG_VIDEO_HW_CURSOR can be defined
268352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
269352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_ON
270352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\
27165618636STimur Tabi 				 console_row * VIDEO_FONT_HEIGHT, ' ')
27265618636STimur Tabi #define CURSOR_SET video_set_cursor()
273352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_SW_CURSOR */
274352d2591SJean-Christophe PLAGNIOL-VILLARD 
275352d2591SJean-Christophe PLAGNIOL-VILLARD 
276352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_HW_CURSOR
277352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CURSOR_ON
27864e40d72SWolfgang Denk #error	only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \
27964e40d72SWolfgang Denk 	or CONFIG_VIDEO_HW_CURSOR can be defined
280352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
281352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_ON
282352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_OFF
283352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \
28465618636STimur Tabi 		  (console_row * VIDEO_FONT_HEIGHT) + video_logo_height)
285352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_HW_CURSOR */
286352d2591SJean-Christophe PLAGNIOL-VILLARD 
287352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_LOGO
288352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_BMP_LOGO
289352d2591SJean-Christophe PLAGNIOL-VILLARD #include <bmp_logo.h>
290c270730fSChe-Liang Chiou #include <bmp_logo_data.h>
291352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_WIDTH	BMP_LOGO_WIDTH
292352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_HEIGHT	BMP_LOGO_HEIGHT
293352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_LUT_OFFSET	BMP_LOGO_OFFSET
294352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_COLORS	BMP_LOGO_COLORS
295352d2591SJean-Christophe PLAGNIOL-VILLARD 
296352d2591SJean-Christophe PLAGNIOL-VILLARD #else  /* CONFIG_VIDEO_BMP_LOGO */
297352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_WIDTH	80
298352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_HEIGHT	80
299352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_COLORS	214
300352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_LUT_OFFSET	0x20
301352d2591SJean-Christophe PLAGNIOL-VILLARD #define __initdata
302352d2591SJean-Christophe PLAGNIOL-VILLARD #include <linux_logo.h>
303352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_WIDTH	LINUX_LOGO_WIDTH
304352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_HEIGHT	LINUX_LOGO_HEIGHT
305352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_LUT_OFFSET	LINUX_LOGO_LUT_OFFSET
306352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_COLORS	LINUX_LOGO_COLORS
307352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_BMP_LOGO */
308352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_INFO_X		(VIDEO_LOGO_WIDTH)
309352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_INFO_Y		(VIDEO_FONT_HEIGHT/2)
310352d2591SJean-Christophe PLAGNIOL-VILLARD #else  /* CONFIG_VIDEO_LOGO */
311352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_WIDTH	0
312352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_HEIGHT	0
313352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_LOGO */
314352d2591SJean-Christophe PLAGNIOL-VILLARD 
315352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_COLS		VIDEO_VISIBLE_COLS
316352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_ROWS		VIDEO_VISIBLE_ROWS
317352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_SIZE		(VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE)
318352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_PIX_BLOCKS	(VIDEO_SIZE >> 2)
319352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LINE_LEN		(VIDEO_COLS*VIDEO_PIXEL_SIZE)
320352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_BURST_LEN		(VIDEO_COLS/8)
321352d2591SJean-Christophe PLAGNIOL-VILLARD 
322352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_LOGO
323be129aa7SMatthias Weisser #define CONSOLE_ROWS		((VIDEO_ROWS - video_logo_height) / VIDEO_FONT_HEIGHT)
324352d2591SJean-Christophe PLAGNIOL-VILLARD #else
325352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROWS		(VIDEO_ROWS / VIDEO_FONT_HEIGHT)
326352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
327352d2591SJean-Christophe PLAGNIOL-VILLARD 
328352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_COLS		(VIDEO_COLS / VIDEO_FONT_WIDTH)
329352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_SIZE	(VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN)
330352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_FIRST	(video_console_address)
331352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_SECOND	(video_console_address + CONSOLE_ROW_SIZE)
332352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_LAST	(video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
333352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_SIZE		(CONSOLE_ROW_SIZE * CONSOLE_ROWS)
334352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_SCROLL_SIZE	(CONSOLE_SIZE - CONSOLE_ROW_SIZE)
335352d2591SJean-Christophe PLAGNIOL-VILLARD 
336352d2591SJean-Christophe PLAGNIOL-VILLARD /* Macros */
337352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	VIDEO_FB_LITTLE_ENDIAN
33864e40d72SWolfgang Denk #define SWAP16(x)		((((x) & 0x00ff) << 8) | \
33964e40d72SWolfgang Denk 				  ((x) >> 8) \
34064e40d72SWolfgang Denk 				)
34164e40d72SWolfgang Denk #define SWAP32(x)		((((x) & 0x000000ff) << 24) | \
34264e40d72SWolfgang Denk 				 (((x) & 0x0000ff00) <<  8) | \
34364e40d72SWolfgang Denk 				 (((x) & 0x00ff0000) >>  8) | \
34464e40d72SWolfgang Denk 				 (((x) & 0xff000000) >> 24)   \
34564e40d72SWolfgang Denk 				)
34664e40d72SWolfgang Denk #define SHORTSWAP32(x)		((((x) & 0x000000ff) <<  8) | \
34764e40d72SWolfgang Denk 				 (((x) & 0x0000ff00) >>  8) | \
34864e40d72SWolfgang Denk 				 (((x) & 0x00ff0000) <<  8) | \
34964e40d72SWolfgang Denk 				 (((x) & 0xff000000) >>  8)   \
35064e40d72SWolfgang Denk 				)
351352d2591SJean-Christophe PLAGNIOL-VILLARD #else
352352d2591SJean-Christophe PLAGNIOL-VILLARD #define SWAP16(x)		(x)
353352d2591SJean-Christophe PLAGNIOL-VILLARD #define SWAP32(x)		(x)
354229b6dceSWolfgang Grandegger #if defined(VIDEO_FB_16BPP_WORD_SWAP)
355bed53753SAnatolij Gustschin #define SHORTSWAP32(x)		(((x) >> 16) | ((x) << 16))
356cc347801SAndrew Dyer #else
357cc347801SAndrew Dyer #define SHORTSWAP32(x)		(x)
358bed53753SAnatolij Gustschin #endif
359352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
360352d2591SJean-Christophe PLAGNIOL-VILLARD 
361352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_EXTRA_INFO
36264e40d72SWolfgang Denk /*
36364e40d72SWolfgang Denk  * setup a board string: type, speed, etc.
36464e40d72SWolfgang Denk  *
36564e40d72SWolfgang Denk  * line_number:	location to place info string beside logo
36664e40d72SWolfgang Denk  * info:	buffer for info string
36764e40d72SWolfgang Denk  */
36864e40d72SWolfgang Denk extern void video_get_info_str(int line_number,	char *info);
369352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
370352d2591SJean-Christophe PLAGNIOL-VILLARD 
371352d2591SJean-Christophe PLAGNIOL-VILLARD /* Locals */
372352d2591SJean-Christophe PLAGNIOL-VILLARD static GraphicDevice *pGD;	/* Pointer to Graphic array */
373352d2591SJean-Christophe PLAGNIOL-VILLARD 
374352d2591SJean-Christophe PLAGNIOL-VILLARD static void *video_fb_address;	/* frame buffer address */
375352d2591SJean-Christophe PLAGNIOL-VILLARD static void *video_console_address;	/* console buffer start address */
376352d2591SJean-Christophe PLAGNIOL-VILLARD 
377be129aa7SMatthias Weisser static int video_logo_height = VIDEO_LOGO_HEIGHT;
378be129aa7SMatthias Weisser 
37957912939SWolfgang Denk static int console_col;		/* cursor col */
38057912939SWolfgang Denk static int console_row;		/* cursor row */
381352d2591SJean-Christophe PLAGNIOL-VILLARD 
382352d2591SJean-Christophe PLAGNIOL-VILLARD static u32 eorx, fgx, bgx;	/* color pats */
383352d2591SJean-Christophe PLAGNIOL-VILLARD 
384352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table8[] = {
385352d2591SJean-Christophe PLAGNIOL-VILLARD 	0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
386352d2591SJean-Christophe PLAGNIOL-VILLARD 	0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
387352d2591SJean-Christophe PLAGNIOL-VILLARD 	0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
38864e40d72SWolfgang Denk 	0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
38964e40d72SWolfgang Denk };
390352d2591SJean-Christophe PLAGNIOL-VILLARD 
391352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table15[] = {
39264e40d72SWolfgang Denk 	0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff
39364e40d72SWolfgang Denk };
394352d2591SJean-Christophe PLAGNIOL-VILLARD 
395352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table16[] = {
39664e40d72SWolfgang Denk 	0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
39764e40d72SWolfgang Denk };
398352d2591SJean-Christophe PLAGNIOL-VILLARD 
399352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table24[16][3] = {
400352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00000000},
401352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00ffffff},
402352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x0000ffff, 0xff000000},
403352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x0000ffff, 0xffffffff},
404352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x000000ff, 0xffff0000, 0x00000000},
405352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x000000ff, 0xffff0000, 0x00ffffff},
406352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x000000ff, 0xffffffff, 0xff000000},
407352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x000000ff, 0xffffffff, 0xffffffff},
408352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffff00, 0x00000000, 0x00000000},
409352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffff00, 0x00000000, 0x00ffffff},
410352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffff00, 0x0000ffff, 0xff000000},
411352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffff00, 0x0000ffff, 0xffffffff},
412352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffffff, 0xffff0000, 0x00000000},
413352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffffff, 0xffff0000, 0x00ffffff},
414352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0xffffffff, 0xffffffff, 0xff000000},
41564e40d72SWolfgang Denk 	{0xffffffff, 0xffffffff, 0xffffffff}
41664e40d72SWolfgang Denk };
417352d2591SJean-Christophe PLAGNIOL-VILLARD 
418352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table32[16][4] = {
419352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00000000, 0x00000000},
420352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00000000, 0x00ffffff},
421352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00ffffff, 0x00000000},
422352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff},
423352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00ffffff, 0x00000000, 0x00000000},
424352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff},
425352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000},
426352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff},
427352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00000000, 0x00000000, 0x00000000},
428352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff},
429352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000},
430352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff},
431352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000},
432352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff},
433352d2591SJean-Christophe PLAGNIOL-VILLARD 	{0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000},
43464e40d72SWolfgang Denk 	{0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff}
43564e40d72SWolfgang Denk };
436352d2591SJean-Christophe PLAGNIOL-VILLARD 
437352d2591SJean-Christophe PLAGNIOL-VILLARD 
438352d2591SJean-Christophe PLAGNIOL-VILLARD static void video_drawchars(int xx, int yy, unsigned char *s, int count)
439352d2591SJean-Christophe PLAGNIOL-VILLARD {
440352d2591SJean-Christophe PLAGNIOL-VILLARD 	u8 *cdat, *dest, *dest0;
441352d2591SJean-Christophe PLAGNIOL-VILLARD 	int rows, offset, c;
442352d2591SJean-Christophe PLAGNIOL-VILLARD 
443352d2591SJean-Christophe PLAGNIOL-VILLARD 	offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE;
444352d2591SJean-Christophe PLAGNIOL-VILLARD 	dest0 = video_fb_address + offset;
445352d2591SJean-Christophe PLAGNIOL-VILLARD 
446352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (VIDEO_DATA_FORMAT) {
447352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_INDEX:
448352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_332RGB:
449352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
450352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
451352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
452352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
45364e40d72SWolfgang Denk 			     rows--; dest += VIDEO_LINE_LEN) {
454352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
455352d2591SJean-Christophe PLAGNIOL-VILLARD 
45664e40d72SWolfgang Denk 				((u32 *) dest)[0] =
45764e40d72SWolfgang Denk 					(video_font_draw_table8[bits >> 4] &
45864e40d72SWolfgang Denk 					 eorx) ^ bgx;
45964e40d72SWolfgang Denk 				((u32 *) dest)[1] =
46064e40d72SWolfgang Denk 					(video_font_draw_table8[bits & 15] &
46164e40d72SWolfgang Denk 					 eorx) ^ bgx;
462352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
463352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
464352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
465352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
466352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
467352d2591SJean-Christophe PLAGNIOL-VILLARD 
468352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_15BIT_555RGB:
469352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
470352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
471352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
472352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
47364e40d72SWolfgang Denk 			     rows--; dest += VIDEO_LINE_LEN) {
474352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
475352d2591SJean-Christophe PLAGNIOL-VILLARD 
47664e40d72SWolfgang Denk 				((u32 *) dest)[0] =
47764e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table15
47864e40d72SWolfgang Denk 						     [bits >> 6] & eorx) ^
47964e40d72SWolfgang Denk 						    bgx);
48064e40d72SWolfgang Denk 				((u32 *) dest)[1] =
48164e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table15
48264e40d72SWolfgang Denk 						     [bits >> 4 & 3] & eorx) ^
48364e40d72SWolfgang Denk 						    bgx);
48464e40d72SWolfgang Denk 				((u32 *) dest)[2] =
48564e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table15
48664e40d72SWolfgang Denk 						     [bits >> 2 & 3] & eorx) ^
48764e40d72SWolfgang Denk 						    bgx);
48864e40d72SWolfgang Denk 				((u32 *) dest)[3] =
48964e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table15
49064e40d72SWolfgang Denk 						     [bits & 3] & eorx) ^
49164e40d72SWolfgang Denk 						    bgx);
492352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
493352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
494352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
495352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
496352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
497352d2591SJean-Christophe PLAGNIOL-VILLARD 
498352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_16BIT_565RGB:
499352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
500352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
501352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
502352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
50364e40d72SWolfgang Denk 			     rows--; dest += VIDEO_LINE_LEN) {
504352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
505352d2591SJean-Christophe PLAGNIOL-VILLARD 
50664e40d72SWolfgang Denk 				((u32 *) dest)[0] =
50764e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table16
50864e40d72SWolfgang Denk 						     [bits >> 6] & eorx) ^
50964e40d72SWolfgang Denk 						    bgx);
51064e40d72SWolfgang Denk 				((u32 *) dest)[1] =
51164e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table16
51264e40d72SWolfgang Denk 						     [bits >> 4 & 3] & eorx) ^
51364e40d72SWolfgang Denk 						    bgx);
51464e40d72SWolfgang Denk 				((u32 *) dest)[2] =
51564e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table16
51664e40d72SWolfgang Denk 						     [bits >> 2 & 3] & eorx) ^
51764e40d72SWolfgang Denk 						    bgx);
51864e40d72SWolfgang Denk 				((u32 *) dest)[3] =
51964e40d72SWolfgang Denk 					SHORTSWAP32((video_font_draw_table16
52064e40d72SWolfgang Denk 						     [bits & 3] & eorx) ^
52164e40d72SWolfgang Denk 						    bgx);
522352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
523352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
524352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
525352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
526352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
527352d2591SJean-Christophe PLAGNIOL-VILLARD 
528352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_32BIT_X888RGB:
529352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
530352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
531352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
532352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
53364e40d72SWolfgang Denk 			     rows--; dest += VIDEO_LINE_LEN) {
534352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
535352d2591SJean-Christophe PLAGNIOL-VILLARD 
53664e40d72SWolfgang Denk 				((u32 *) dest)[0] =
53764e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
53864e40d72SWolfgang Denk 						[bits >> 4][0] & eorx) ^ bgx);
53964e40d72SWolfgang Denk 				((u32 *) dest)[1] =
54064e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
54164e40d72SWolfgang Denk 						[bits >> 4][1] & eorx) ^ bgx);
54264e40d72SWolfgang Denk 				((u32 *) dest)[2] =
54364e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
54464e40d72SWolfgang Denk 						[bits >> 4][2] & eorx) ^ bgx);
54564e40d72SWolfgang Denk 				((u32 *) dest)[3] =
54664e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
54764e40d72SWolfgang Denk 						[bits >> 4][3] & eorx) ^ bgx);
54864e40d72SWolfgang Denk 				((u32 *) dest)[4] =
54964e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
55064e40d72SWolfgang Denk 						[bits & 15][0] & eorx) ^ bgx);
55164e40d72SWolfgang Denk 				((u32 *) dest)[5] =
55264e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
55364e40d72SWolfgang Denk 						[bits & 15][1] & eorx) ^ bgx);
55464e40d72SWolfgang Denk 				((u32 *) dest)[6] =
55564e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
55664e40d72SWolfgang Denk 						[bits & 15][2] & eorx) ^ bgx);
55764e40d72SWolfgang Denk 				((u32 *) dest)[7] =
55864e40d72SWolfgang Denk 					SWAP32((video_font_draw_table32
55964e40d72SWolfgang Denk 						[bits & 15][3] & eorx) ^ bgx);
560352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
561352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
562352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
563352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
564352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
565352d2591SJean-Christophe PLAGNIOL-VILLARD 
566352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_24BIT_888RGB:
567352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
568352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
569352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
570352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
57164e40d72SWolfgang Denk 			     rows--; dest += VIDEO_LINE_LEN) {
572352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
573352d2591SJean-Christophe PLAGNIOL-VILLARD 
57464e40d72SWolfgang Denk 				((u32 *) dest)[0] =
57564e40d72SWolfgang Denk 					(video_font_draw_table24[bits >> 4][0]
57664e40d72SWolfgang Denk 					 & eorx) ^ bgx;
57764e40d72SWolfgang Denk 				((u32 *) dest)[1] =
57864e40d72SWolfgang Denk 					(video_font_draw_table24[bits >> 4][1]
57964e40d72SWolfgang Denk 					 & eorx) ^ bgx;
58064e40d72SWolfgang Denk 				((u32 *) dest)[2] =
58164e40d72SWolfgang Denk 					(video_font_draw_table24[bits >> 4][2]
58264e40d72SWolfgang Denk 					 & eorx) ^ bgx;
58364e40d72SWolfgang Denk 				((u32 *) dest)[3] =
58464e40d72SWolfgang Denk 					(video_font_draw_table24[bits & 15][0]
58564e40d72SWolfgang Denk 					 & eorx) ^ bgx;
58664e40d72SWolfgang Denk 				((u32 *) dest)[4] =
58764e40d72SWolfgang Denk 					(video_font_draw_table24[bits & 15][1]
58864e40d72SWolfgang Denk 					 & eorx) ^ bgx;
58964e40d72SWolfgang Denk 				((u32 *) dest)[5] =
59064e40d72SWolfgang Denk 					(video_font_draw_table24[bits & 15][2]
59164e40d72SWolfgang Denk 					 & eorx) ^ bgx;
592352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
593352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
594352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
595352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
596352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
597352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
598352d2591SJean-Christophe PLAGNIOL-VILLARD }
599352d2591SJean-Christophe PLAGNIOL-VILLARD 
600352d2591SJean-Christophe PLAGNIOL-VILLARD static inline void video_drawstring(int xx, int yy, unsigned char *s)
601352d2591SJean-Christophe PLAGNIOL-VILLARD {
602352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_drawchars(xx, yy, s, strlen((char *) s));
603352d2591SJean-Christophe PLAGNIOL-VILLARD }
604352d2591SJean-Christophe PLAGNIOL-VILLARD 
605352d2591SJean-Christophe PLAGNIOL-VILLARD static void video_putchar(int xx, int yy, unsigned char c)
606352d2591SJean-Christophe PLAGNIOL-VILLARD {
607be129aa7SMatthias Weisser 	video_drawchars(xx, yy + video_logo_height, &c, 1);
608352d2591SJean-Christophe PLAGNIOL-VILLARD }
609352d2591SJean-Christophe PLAGNIOL-VILLARD 
610352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
611352d2591SJean-Christophe PLAGNIOL-VILLARD static void video_set_cursor(void)
612352d2591SJean-Christophe PLAGNIOL-VILLARD {
613352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* swap drawing colors */
614352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx;
615352d2591SJean-Christophe PLAGNIOL-VILLARD 	fgx = bgx;
616352d2591SJean-Christophe PLAGNIOL-VILLARD 	bgx = eorx;
617352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx ^ bgx;
618352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* draw cursor */
619352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_putchar(console_col * VIDEO_FONT_WIDTH,
62064e40d72SWolfgang Denk 		      console_row * VIDEO_FONT_HEIGHT, ' ');
621352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* restore drawing colors */
622352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx;
623352d2591SJean-Christophe PLAGNIOL-VILLARD 	fgx = bgx;
624352d2591SJean-Christophe PLAGNIOL-VILLARD 	bgx = eorx;
625352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx ^ bgx;
626352d2591SJean-Christophe PLAGNIOL-VILLARD }
627352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
62864e40d72SWolfgang Denk 
629352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_CURSOR
630352d2591SJean-Christophe PLAGNIOL-VILLARD void console_cursor(int state)
631352d2591SJean-Christophe PLAGNIOL-VILLARD {
632352d2591SJean-Christophe PLAGNIOL-VILLARD 	static int last_state = 0;
633352d2591SJean-Christophe PLAGNIOL-VILLARD 
634352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_TIME
635352d2591SJean-Christophe PLAGNIOL-VILLARD 	struct rtc_time tm;
636352d2591SJean-Christophe PLAGNIOL-VILLARD 	char info[16];
637352d2591SJean-Christophe PLAGNIOL-VILLARD 
638352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* time update only if cursor is on (faster scroll) */
639352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (state) {
640352d2591SJean-Christophe PLAGNIOL-VILLARD 		rtc_get(&tm);
641352d2591SJean-Christophe PLAGNIOL-VILLARD 
642352d2591SJean-Christophe PLAGNIOL-VILLARD 		sprintf(info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min,
643352d2591SJean-Christophe PLAGNIOL-VILLARD 			tm.tm_sec);
644352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_drawstring(VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
645352d2591SJean-Christophe PLAGNIOL-VILLARD 				 VIDEO_INFO_Y, (uchar *) info);
646352d2591SJean-Christophe PLAGNIOL-VILLARD 
647352d2591SJean-Christophe PLAGNIOL-VILLARD 		sprintf(info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon,
648352d2591SJean-Christophe PLAGNIOL-VILLARD 			tm.tm_year);
649352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_drawstring(VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
65064e40d72SWolfgang Denk 				 VIDEO_INFO_Y + 1 * VIDEO_FONT_HEIGHT,
65164e40d72SWolfgang Denk 				 (uchar *) info);
652352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
653352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
654352d2591SJean-Christophe PLAGNIOL-VILLARD 
655352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (state && (last_state != state)) {
656352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_set_cursor();
657352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
658352d2591SJean-Christophe PLAGNIOL-VILLARD 
659352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (!state && (last_state != state)) {
660352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* clear cursor */
661352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_putchar(console_col * VIDEO_FONT_WIDTH,
66264e40d72SWolfgang Denk 			      console_row * VIDEO_FONT_HEIGHT, ' ');
663352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
664352d2591SJean-Christophe PLAGNIOL-VILLARD 
665352d2591SJean-Christophe PLAGNIOL-VILLARD 	last_state = state;
666352d2591SJean-Christophe PLAGNIOL-VILLARD }
667352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
668352d2591SJean-Christophe PLAGNIOL-VILLARD 
669352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef VIDEO_HW_RECTFILL
670352d2591SJean-Christophe PLAGNIOL-VILLARD static void memsetl(int *p, int c, int v)
671352d2591SJean-Christophe PLAGNIOL-VILLARD {
672352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (c--)
673352d2591SJean-Christophe PLAGNIOL-VILLARD 		*(p++) = v;
674352d2591SJean-Christophe PLAGNIOL-VILLARD }
675352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
676352d2591SJean-Christophe PLAGNIOL-VILLARD 
677352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef VIDEO_HW_BITBLT
678352d2591SJean-Christophe PLAGNIOL-VILLARD static void memcpyl(int *d, int *s, int c)
679352d2591SJean-Christophe PLAGNIOL-VILLARD {
680352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (c--)
681352d2591SJean-Christophe PLAGNIOL-VILLARD 		*(d++) = *(s++);
682352d2591SJean-Christophe PLAGNIOL-VILLARD }
683352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
684352d2591SJean-Christophe PLAGNIOL-VILLARD 
685352d2591SJean-Christophe PLAGNIOL-VILLARD static void console_scrollup(void)
686352d2591SJean-Christophe PLAGNIOL-VILLARD {
687352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* copy up rows ignoring the first one */
688352d2591SJean-Christophe PLAGNIOL-VILLARD 
689352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_HW_BITBLT
690352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_hw_bitblt(VIDEO_PIXEL_SIZE,	/* bytes per pixel */
691352d2591SJean-Christophe PLAGNIOL-VILLARD 			0,			/* source pos x */
69264e40d72SWolfgang Denk 			video_logo_height +
69364e40d72SWolfgang Denk 				VIDEO_FONT_HEIGHT, /* source pos y */
694352d2591SJean-Christophe PLAGNIOL-VILLARD 			0,			/* dest pos x */
695be129aa7SMatthias Weisser 			video_logo_height,	/* dest pos y */
696352d2591SJean-Christophe PLAGNIOL-VILLARD 			VIDEO_VISIBLE_COLS,	/* frame width */
69764e40d72SWolfgang Denk 			VIDEO_VISIBLE_ROWS
69864e40d72SWolfgang Denk 			- video_logo_height
69964e40d72SWolfgang Denk 			- VIDEO_FONT_HEIGHT	/* frame height */
700352d2591SJean-Christophe PLAGNIOL-VILLARD 		);
701352d2591SJean-Christophe PLAGNIOL-VILLARD #else
702352d2591SJean-Christophe PLAGNIOL-VILLARD 	memcpyl(CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND,
703352d2591SJean-Christophe PLAGNIOL-VILLARD 		CONSOLE_SCROLL_SIZE >> 2);
704352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
705352d2591SJean-Christophe PLAGNIOL-VILLARD 
706352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* clear the last one */
707352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_HW_RECTFILL
708352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_hw_rectfill(VIDEO_PIXEL_SIZE,	/* bytes per pixel */
709352d2591SJean-Christophe PLAGNIOL-VILLARD 			  0,			/* dest pos x */
71064e40d72SWolfgang Denk 			  VIDEO_VISIBLE_ROWS
71164e40d72SWolfgang Denk 			  - VIDEO_FONT_HEIGHT,	/* dest pos y */
712352d2591SJean-Christophe PLAGNIOL-VILLARD 			  VIDEO_VISIBLE_COLS,	/* frame width */
713352d2591SJean-Christophe PLAGNIOL-VILLARD 			  VIDEO_FONT_HEIGHT,	/* frame height */
714352d2591SJean-Christophe PLAGNIOL-VILLARD 			  CONSOLE_BG_COL	/* fill color */
715352d2591SJean-Christophe PLAGNIOL-VILLARD 		);
716352d2591SJean-Christophe PLAGNIOL-VILLARD #else
717352d2591SJean-Christophe PLAGNIOL-VILLARD 	memsetl(CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
718352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
719352d2591SJean-Christophe PLAGNIOL-VILLARD }
720352d2591SJean-Christophe PLAGNIOL-VILLARD 
721352d2591SJean-Christophe PLAGNIOL-VILLARD static void console_back(void)
722352d2591SJean-Christophe PLAGNIOL-VILLARD {
72365618636STimur Tabi 	CURSOR_OFF;
72465618636STimur Tabi 	console_col--;
725352d2591SJean-Christophe PLAGNIOL-VILLARD 
726352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (console_col < 0) {
727352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_col = CONSOLE_COLS - 1;
728352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_row--;
729352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (console_row < 0)
730352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_row = 0;
731352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
732352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_putchar(console_col * VIDEO_FONT_WIDTH,
73364e40d72SWolfgang Denk 		      console_row * VIDEO_FONT_HEIGHT, ' ');
734352d2591SJean-Christophe PLAGNIOL-VILLARD }
735352d2591SJean-Christophe PLAGNIOL-VILLARD 
736352d2591SJean-Christophe PLAGNIOL-VILLARD static void console_newline(void)
737352d2591SJean-Christophe PLAGNIOL-VILLARD {
73820c450efSAnatolij Gustschin 	/* Check if last character in the line was just drawn. If so, cursor was
73920c450efSAnatolij Gustschin 	   overwriten and need not to be cleared. Cursor clearing without this
74020c450efSAnatolij Gustschin 	   check causes overwriting the 1st character of the line if line lenght
74120c450efSAnatolij Gustschin 	   is >= CONSOLE_COLS
74220c450efSAnatolij Gustschin 	 */
74320c450efSAnatolij Gustschin 	if (console_col < CONSOLE_COLS)
74465618636STimur Tabi 		CURSOR_OFF;
74520c450efSAnatolij Gustschin 	console_row++;
746352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_col = 0;
747352d2591SJean-Christophe PLAGNIOL-VILLARD 
748352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Check if we need to scroll the terminal */
749352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (console_row >= CONSOLE_ROWS) {
750352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* Scroll everything up */
751352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_scrollup();
752352d2591SJean-Christophe PLAGNIOL-VILLARD 
753352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* Decrement row number */
754352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_row--;
755352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
756352d2591SJean-Christophe PLAGNIOL-VILLARD }
757352d2591SJean-Christophe PLAGNIOL-VILLARD 
75820c450efSAnatolij Gustschin static void console_cr(void)
75920c450efSAnatolij Gustschin {
76065618636STimur Tabi 	CURSOR_OFF;
76165618636STimur Tabi 	console_col = 0;
76220c450efSAnatolij Gustschin }
76320c450efSAnatolij Gustschin 
764352d2591SJean-Christophe PLAGNIOL-VILLARD void video_putc(const char c)
765352d2591SJean-Christophe PLAGNIOL-VILLARD {
76620c450efSAnatolij Gustschin 	static int nl = 1;
76720c450efSAnatolij Gustschin 
768352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (c) {
76920c450efSAnatolij Gustschin 	case 13:		/* back to first column */
77020c450efSAnatolij Gustschin 		console_cr();
771352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
772352d2591SJean-Christophe PLAGNIOL-VILLARD 
773352d2591SJean-Christophe PLAGNIOL-VILLARD 	case '\n':		/* next line */
77420c450efSAnatolij Gustschin 		if (console_col || (!console_col && nl))
775352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_newline();
77620c450efSAnatolij Gustschin 		nl = 1;
777352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
778352d2591SJean-Christophe PLAGNIOL-VILLARD 
779352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 9:		/* tab 8 */
78065618636STimur Tabi 		CURSOR_OFF;
78165618636STimur Tabi 		console_col |= 0x0008;
782352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_col &= ~0x0007;
783352d2591SJean-Christophe PLAGNIOL-VILLARD 
784352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (console_col >= CONSOLE_COLS)
785352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_newline();
786352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
787352d2591SJean-Christophe PLAGNIOL-VILLARD 
788352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 8:		/* backspace */
789352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_back();
790352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
791352d2591SJean-Christophe PLAGNIOL-VILLARD 
792352d2591SJean-Christophe PLAGNIOL-VILLARD 	default:		/* draw the char */
793352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_putchar(console_col * VIDEO_FONT_WIDTH,
79464e40d72SWolfgang Denk 			      console_row * VIDEO_FONT_HEIGHT, c);
795352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_col++;
796352d2591SJean-Christophe PLAGNIOL-VILLARD 
797352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* check for newline */
79820c450efSAnatolij Gustschin 		if (console_col >= CONSOLE_COLS) {
799352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_newline();
80020c450efSAnatolij Gustschin 			nl = 0;
80120c450efSAnatolij Gustschin 		}
802352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
80365618636STimur Tabi 	CURSOR_SET;
80465618636STimur Tabi }
805352d2591SJean-Christophe PLAGNIOL-VILLARD 
806352d2591SJean-Christophe PLAGNIOL-VILLARD void video_puts(const char *s)
807352d2591SJean-Christophe PLAGNIOL-VILLARD {
808352d2591SJean-Christophe PLAGNIOL-VILLARD 	int count = strlen(s);
809352d2591SJean-Christophe PLAGNIOL-VILLARD 
810352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (count--)
811352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_putc(*s++);
812352d2591SJean-Christophe PLAGNIOL-VILLARD }
813352d2591SJean-Christophe PLAGNIOL-VILLARD 
81410543820SAnatolij Gustschin /*
81510543820SAnatolij Gustschin  * Do not enforce drivers (or board code) to provide empty
81610543820SAnatolij Gustschin  * video_set_lut() if they do not support 8 bpp format.
81710543820SAnatolij Gustschin  * Implement weak default function instead.
81810543820SAnatolij Gustschin  */
81910543820SAnatolij Gustschin void __video_set_lut(unsigned int index, unsigned char r,
82010543820SAnatolij Gustschin 		     unsigned char g, unsigned char b)
82110543820SAnatolij Gustschin {
82210543820SAnatolij Gustschin }
82364e40d72SWolfgang Denk 
82410543820SAnatolij Gustschin void video_set_lut(unsigned int, unsigned char, unsigned char, unsigned char)
82510543820SAnatolij Gustschin 	__attribute__ ((weak, alias("__video_set_lut")));
82610543820SAnatolij Gustschin 
827352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
828352d2591SJean-Christophe PLAGNIOL-VILLARD 
829352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_8BIT_332RGB(r,g,b)	{			\
830352d2591SJean-Christophe PLAGNIOL-VILLARD 	*fb = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6);	\
831352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb ++;						\
832352d2591SJean-Christophe PLAGNIOL-VILLARD }
833352d2591SJean-Christophe PLAGNIOL-VILLARD 
834352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_15BIT_555RGB(r,g,b) {			\
83564e40d72SWolfgang Denk 	*(unsigned short *)fb =				\
83664e40d72SWolfgang Denk 		SWAP16((unsigned short)(((r>>3)<<10) |	\
83764e40d72SWolfgang Denk 					((g>>3)<<5)  |	\
83864e40d72SWolfgang Denk 					 (b>>3)));	\
839352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 2;					\
840352d2591SJean-Christophe PLAGNIOL-VILLARD }
841352d2591SJean-Christophe PLAGNIOL-VILLARD 
842352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_16BIT_565RGB(r,g,b) {			\
84364e40d72SWolfgang Denk 	*(unsigned short *)fb =				\
84464e40d72SWolfgang Denk 		SWAP16((unsigned short)((((r)>>3)<<11)| \
84564e40d72SWolfgang Denk 					(((g)>>2)<<5) | \
84664e40d72SWolfgang Denk 					 ((b)>>3)));	\
847352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 2;					\
848352d2591SJean-Christophe PLAGNIOL-VILLARD }
849352d2591SJean-Christophe PLAGNIOL-VILLARD 
850352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_32BIT_X888RGB(r,g,b) {			\
85164e40d72SWolfgang Denk 	*(unsigned long *)fb =				\
85264e40d72SWolfgang Denk 		SWAP32((unsigned long)(((r<<16) |	\
85364e40d72SWolfgang Denk 					(g<<8)  |	\
85464e40d72SWolfgang Denk 					 b)));		\
855352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 4;					\
856352d2591SJean-Christophe PLAGNIOL-VILLARD }
857352d2591SJean-Christophe PLAGNIOL-VILLARD 
858352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_FB_LITTLE_ENDIAN
859352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_24BIT_888RGB(r,g,b) {			\
860352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[0] = b;					\
861352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[1] = g;					\
862352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[2] = r;					\
863352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 3;					\
864352d2591SJean-Christophe PLAGNIOL-VILLARD }
865352d2591SJean-Christophe PLAGNIOL-VILLARD #else
866352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_24BIT_888RGB(r,g,b) {			\
867352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[0] = r;					\
868352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[1] = g;					\
869352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[2] = b;					\
870352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 3;					\
871352d2591SJean-Christophe PLAGNIOL-VILLARD }
872352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
873352d2591SJean-Christophe PLAGNIOL-VILLARD 
874e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
87564e40d72SWolfgang Denk static inline void fill_555rgb_pswap(uchar *fb, int x, u8 r, u8 g, u8 b)
876e84d568fSAnatolij Gustschin {
877e84d568fSAnatolij Gustschin 	ushort *dst = (ushort *) fb;
878e84d568fSAnatolij Gustschin 	ushort color = (ushort) (((r >> 3) << 10) |
879e84d568fSAnatolij Gustschin 				 ((g >> 3) <<  5) |
880e84d568fSAnatolij Gustschin 				  (b >> 3));
881e84d568fSAnatolij Gustschin 	if (x & 1)
882e84d568fSAnatolij Gustschin 		*(--dst) = color;
883e84d568fSAnatolij Gustschin 	else
884e84d568fSAnatolij Gustschin 		*(++dst) = color;
885e84d568fSAnatolij Gustschin }
886e84d568fSAnatolij Gustschin #endif
887352d2591SJean-Christophe PLAGNIOL-VILLARD 
888352d2591SJean-Christophe PLAGNIOL-VILLARD /*
889d5011762SAnatolij Gustschin  * RLE8 bitmap support
890d5011762SAnatolij Gustschin  */
891d5011762SAnatolij Gustschin 
892d5011762SAnatolij Gustschin #ifdef CONFIG_VIDEO_BMP_RLE8
893d5011762SAnatolij Gustschin /* Pre-calculated color table entry */
894d5011762SAnatolij Gustschin struct palette {
895d5011762SAnatolij Gustschin 	union {
896d5011762SAnatolij Gustschin 		unsigned short w;	/* word */
897d5011762SAnatolij Gustschin 		unsigned int dw;	/* double word */
898d5011762SAnatolij Gustschin 	} ce;				/* color entry */
899d5011762SAnatolij Gustschin };
900d5011762SAnatolij Gustschin 
901d5011762SAnatolij Gustschin /*
902d5011762SAnatolij Gustschin  * Helper to draw encoded/unencoded run.
903d5011762SAnatolij Gustschin  */
904d5011762SAnatolij Gustschin static void draw_bitmap(uchar **fb, uchar *bm, struct palette *p,
905d5011762SAnatolij Gustschin 			int cnt, int enc)
906d5011762SAnatolij Gustschin {
907d5011762SAnatolij Gustschin 	ulong addr = (ulong) *fb;
908d5011762SAnatolij Gustschin 	int *off;
909d5011762SAnatolij Gustschin 	int enc_off = 1;
910d5011762SAnatolij Gustschin 	int i;
911d5011762SAnatolij Gustschin 
912d5011762SAnatolij Gustschin 	/*
913d5011762SAnatolij Gustschin 	 * Setup offset of the color index in the bitmap.
914d5011762SAnatolij Gustschin 	 * Color index of encoded run is at offset 1.
915d5011762SAnatolij Gustschin 	 */
916d5011762SAnatolij Gustschin 	off = enc ? &enc_off : &i;
917d5011762SAnatolij Gustschin 
918d5011762SAnatolij Gustschin 	switch (VIDEO_DATA_FORMAT) {
919d5011762SAnatolij Gustschin 	case GDF__8BIT_INDEX:
920d5011762SAnatolij Gustschin 		for (i = 0; i < cnt; i++)
921d5011762SAnatolij Gustschin 			*(unsigned char *) addr++ = bm[*off];
922d5011762SAnatolij Gustschin 		break;
923d5011762SAnatolij Gustschin 	case GDF_15BIT_555RGB:
924d5011762SAnatolij Gustschin 	case GDF_16BIT_565RGB:
925d5011762SAnatolij Gustschin 		/* differences handled while pre-calculating palette */
926d5011762SAnatolij Gustschin 		for (i = 0; i < cnt; i++) {
927d5011762SAnatolij Gustschin 			*(unsigned short *) addr = p[bm[*off]].ce.w;
928d5011762SAnatolij Gustschin 			addr += 2;
929d5011762SAnatolij Gustschin 		}
930d5011762SAnatolij Gustschin 		break;
931d5011762SAnatolij Gustschin 	case GDF_32BIT_X888RGB:
932d5011762SAnatolij Gustschin 		for (i = 0; i < cnt; i++) {
933d5011762SAnatolij Gustschin 			*(unsigned long *) addr = p[bm[*off]].ce.dw;
934d5011762SAnatolij Gustschin 			addr += 4;
935d5011762SAnatolij Gustschin 		}
936d5011762SAnatolij Gustschin 		break;
937d5011762SAnatolij Gustschin 	}
938d5011762SAnatolij Gustschin 	*fb = (uchar *) addr;	/* return modified address */
939d5011762SAnatolij Gustschin }
940d5011762SAnatolij Gustschin 
941d5011762SAnatolij Gustschin static int display_rle8_bitmap(bmp_image_t *img, int xoff, int yoff,
942d5011762SAnatolij Gustschin 			       int width, int height)
943d5011762SAnatolij Gustschin {
944d5011762SAnatolij Gustschin 	unsigned char *bm;
945d5011762SAnatolij Gustschin 	unsigned char *fbp;
946d5011762SAnatolij Gustschin 	unsigned int cnt, runlen;
947d5011762SAnatolij Gustschin 	int decode = 1;
948d5011762SAnatolij Gustschin 	int x, y, bpp, i, ncolors;
949d5011762SAnatolij Gustschin 	struct palette p[256];
950d5011762SAnatolij Gustschin 	bmp_color_table_entry_t cte;
951d5011762SAnatolij Gustschin 	int green_shift, red_off;
95274446b63SAnatolij Gustschin 	int limit = VIDEO_COLS * VIDEO_ROWS;
95374446b63SAnatolij Gustschin 	int pixels = 0;
954d5011762SAnatolij Gustschin 
955d5011762SAnatolij Gustschin 	x = 0;
956d5011762SAnatolij Gustschin 	y = __le32_to_cpu(img->header.height) - 1;
957d5011762SAnatolij Gustschin 	ncolors = __le32_to_cpu(img->header.colors_used);
958d5011762SAnatolij Gustschin 	bpp = VIDEO_PIXEL_SIZE;
959d5011762SAnatolij Gustschin 	fbp = (unsigned char *) ((unsigned int) video_fb_address +
960d5011762SAnatolij Gustschin 				 (((y + yoff) * VIDEO_COLS) + xoff) * bpp);
961d5011762SAnatolij Gustschin 
962d5011762SAnatolij Gustschin 	bm = (uchar *) img + __le32_to_cpu(img->header.data_offset);
963d5011762SAnatolij Gustschin 
964d5011762SAnatolij Gustschin 	/* pre-calculate and setup palette */
965d5011762SAnatolij Gustschin 	switch (VIDEO_DATA_FORMAT) {
966d5011762SAnatolij Gustschin 	case GDF__8BIT_INDEX:
967d5011762SAnatolij Gustschin 		for (i = 0; i < ncolors; i++) {
968d5011762SAnatolij Gustschin 			cte = img->color_table[i];
969d5011762SAnatolij Gustschin 			video_set_lut(i, cte.red, cte.green, cte.blue);
970d5011762SAnatolij Gustschin 		}
971d5011762SAnatolij Gustschin 		break;
972d5011762SAnatolij Gustschin 	case GDF_15BIT_555RGB:
973d5011762SAnatolij Gustschin 	case GDF_16BIT_565RGB:
974d5011762SAnatolij Gustschin 		if (VIDEO_DATA_FORMAT == GDF_15BIT_555RGB) {
975d5011762SAnatolij Gustschin 			green_shift = 3;
976d5011762SAnatolij Gustschin 			red_off = 10;
977d5011762SAnatolij Gustschin 		} else {
978d5011762SAnatolij Gustschin 			green_shift = 2;
979d5011762SAnatolij Gustschin 			red_off = 11;
980d5011762SAnatolij Gustschin 		}
981d5011762SAnatolij Gustschin 		for (i = 0; i < ncolors; i++) {
982d5011762SAnatolij Gustschin 			cte = img->color_table[i];
983d5011762SAnatolij Gustschin 			p[i].ce.w = SWAP16((unsigned short)
984d5011762SAnatolij Gustschin 					   (((cte.red >> 3) << red_off) |
985d5011762SAnatolij Gustschin 					    ((cte.green >> green_shift) << 5) |
986d5011762SAnatolij Gustschin 					    cte.blue >> 3));
987d5011762SAnatolij Gustschin 		}
988d5011762SAnatolij Gustschin 		break;
989d5011762SAnatolij Gustschin 	case GDF_32BIT_X888RGB:
990d5011762SAnatolij Gustschin 		for (i = 0; i < ncolors; i++) {
991d5011762SAnatolij Gustschin 			cte = img->color_table[i];
99264e40d72SWolfgang Denk 			p[i].ce.dw = SWAP32((cte.red << 16) |
99364e40d72SWolfgang Denk 					    (cte.green << 8) |
994d5011762SAnatolij Gustschin 					     cte.blue);
995d5011762SAnatolij Gustschin 		}
996d5011762SAnatolij Gustschin 		break;
997d5011762SAnatolij Gustschin 	default:
998d5011762SAnatolij Gustschin 		printf("RLE Bitmap unsupported in video mode 0x%x\n",
999d5011762SAnatolij Gustschin 		       VIDEO_DATA_FORMAT);
1000d5011762SAnatolij Gustschin 		return -1;
1001d5011762SAnatolij Gustschin 	}
1002d5011762SAnatolij Gustschin 
1003d5011762SAnatolij Gustschin 	while (decode) {
1004d5011762SAnatolij Gustschin 		switch (bm[0]) {
1005d5011762SAnatolij Gustschin 		case 0:
1006d5011762SAnatolij Gustschin 			switch (bm[1]) {
1007d5011762SAnatolij Gustschin 			case 0:
1008d5011762SAnatolij Gustschin 				/* scan line end marker */
1009d5011762SAnatolij Gustschin 				bm += 2;
1010d5011762SAnatolij Gustschin 				x = 0;
1011d5011762SAnatolij Gustschin 				y--;
1012d5011762SAnatolij Gustschin 				fbp = (unsigned char *)
1013d5011762SAnatolij Gustschin 					((unsigned int) video_fb_address +
1014d5011762SAnatolij Gustschin 					 (((y + yoff) * VIDEO_COLS) +
1015d5011762SAnatolij Gustschin 					  xoff) * bpp);
1016d5011762SAnatolij Gustschin 				continue;
1017d5011762SAnatolij Gustschin 			case 1:
1018d5011762SAnatolij Gustschin 				/* end of bitmap data marker */
1019d5011762SAnatolij Gustschin 				decode = 0;
1020d5011762SAnatolij Gustschin 				break;
1021d5011762SAnatolij Gustschin 			case 2:
1022d5011762SAnatolij Gustschin 				/* run offset marker */
1023d5011762SAnatolij Gustschin 				x += bm[2];
1024d5011762SAnatolij Gustschin 				y -= bm[3];
1025d5011762SAnatolij Gustschin 				fbp = (unsigned char *)
1026d5011762SAnatolij Gustschin 					((unsigned int) video_fb_address +
1027d5011762SAnatolij Gustschin 					 (((y + yoff) * VIDEO_COLS) +
1028d5011762SAnatolij Gustschin 					  x + xoff) * bpp);
1029d5011762SAnatolij Gustschin 				bm += 4;
1030d5011762SAnatolij Gustschin 				break;
1031d5011762SAnatolij Gustschin 			default:
1032d5011762SAnatolij Gustschin 				/* unencoded run */
1033d5011762SAnatolij Gustschin 				cnt = bm[1];
1034d5011762SAnatolij Gustschin 				runlen = cnt;
103574446b63SAnatolij Gustschin 				pixels += cnt;
103674446b63SAnatolij Gustschin 				if (pixels > limit)
103774446b63SAnatolij Gustschin 					goto error;
103874446b63SAnatolij Gustschin 
1039d5011762SAnatolij Gustschin 				bm += 2;
1040d5011762SAnatolij Gustschin 				if (y < height) {
1041d5011762SAnatolij Gustschin 					if (x >= width) {
1042d5011762SAnatolij Gustschin 						x += runlen;
1043d5011762SAnatolij Gustschin 						goto next_run;
1044d5011762SAnatolij Gustschin 					}
1045d5011762SAnatolij Gustschin 					if (x + runlen > width)
1046d5011762SAnatolij Gustschin 						cnt = width - x;
1047d5011762SAnatolij Gustschin 					draw_bitmap(&fbp, bm, p, cnt, 0);
1048d5011762SAnatolij Gustschin 					x += runlen;
1049d5011762SAnatolij Gustschin 				}
1050d5011762SAnatolij Gustschin next_run:
1051d5011762SAnatolij Gustschin 				bm += runlen;
1052d5011762SAnatolij Gustschin 				if (runlen & 1)
1053d5011762SAnatolij Gustschin 					bm++;	/* 0 padding if length is odd */
1054d5011762SAnatolij Gustschin 			}
1055d5011762SAnatolij Gustschin 			break;
1056d5011762SAnatolij Gustschin 		default:
1057d5011762SAnatolij Gustschin 			/* encoded run */
1058d5011762SAnatolij Gustschin 			cnt = bm[0];
1059d5011762SAnatolij Gustschin 			runlen = cnt;
106074446b63SAnatolij Gustschin 			pixels += cnt;
106174446b63SAnatolij Gustschin 			if (pixels > limit)
106274446b63SAnatolij Gustschin 				goto error;
106374446b63SAnatolij Gustschin 
106474446b63SAnatolij Gustschin 			if (y < height) {     /* only draw into visible area */
1065d5011762SAnatolij Gustschin 				if (x >= width) {
1066d5011762SAnatolij Gustschin 					x += runlen;
1067d5011762SAnatolij Gustschin 					bm += 2;
1068d5011762SAnatolij Gustschin 					continue;
1069d5011762SAnatolij Gustschin 				}
1070d5011762SAnatolij Gustschin 				if (x + runlen > width)
1071d5011762SAnatolij Gustschin 					cnt = width - x;
1072d5011762SAnatolij Gustschin 				draw_bitmap(&fbp, bm, p, cnt, 1);
1073d5011762SAnatolij Gustschin 				x += runlen;
1074d5011762SAnatolij Gustschin 			}
1075d5011762SAnatolij Gustschin 			bm += 2;
1076d5011762SAnatolij Gustschin 			break;
1077d5011762SAnatolij Gustschin 		}
1078d5011762SAnatolij Gustschin 	}
1079d5011762SAnatolij Gustschin 	return 0;
108074446b63SAnatolij Gustschin error:
108174446b63SAnatolij Gustschin 	printf("Error: Too much encoded pixel data, validate your bitmap\n");
108274446b63SAnatolij Gustschin 	return -1;
1083d5011762SAnatolij Gustschin }
1084d5011762SAnatolij Gustschin #endif
1085d5011762SAnatolij Gustschin 
1086d5011762SAnatolij Gustschin /*
1087352d2591SJean-Christophe PLAGNIOL-VILLARD  * Display the BMP file located at address bmp_image.
1088352d2591SJean-Christophe PLAGNIOL-VILLARD  */
1089352d2591SJean-Christophe PLAGNIOL-VILLARD int video_display_bitmap(ulong bmp_image, int x, int y)
1090352d2591SJean-Christophe PLAGNIOL-VILLARD {
1091352d2591SJean-Christophe PLAGNIOL-VILLARD 	ushort xcount, ycount;
1092352d2591SJean-Christophe PLAGNIOL-VILLARD 	uchar *fb;
1093352d2591SJean-Christophe PLAGNIOL-VILLARD 	bmp_image_t *bmp = (bmp_image_t *) bmp_image;
1094352d2591SJean-Christophe PLAGNIOL-VILLARD 	uchar *bmap;
1095352d2591SJean-Christophe PLAGNIOL-VILLARD 	ushort padded_line;
1096352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned long width, height, bpp;
1097352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned colors;
1098352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned long compression;
1099352d2591SJean-Christophe PLAGNIOL-VILLARD 	bmp_color_table_entry_t cte;
110064e40d72SWolfgang Denk 
1101352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_GZIP
1102352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char *dst = NULL;
1103352d2591SJean-Christophe PLAGNIOL-VILLARD 	ulong len;
1104352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1105352d2591SJean-Christophe PLAGNIOL-VILLARD 
1106352d2591SJean-Christophe PLAGNIOL-VILLARD 	WATCHDOG_RESET();
1107352d2591SJean-Christophe PLAGNIOL-VILLARD 
1108352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (!((bmp->header.signature[0] == 'B') &&
1109352d2591SJean-Christophe PLAGNIOL-VILLARD 	      (bmp->header.signature[1] == 'M'))) {
1110352d2591SJean-Christophe PLAGNIOL-VILLARD 
1111352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_GZIP
1112352d2591SJean-Christophe PLAGNIOL-VILLARD 		/*
1113352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * Could be a gzipped bmp image, try to decrompress...
1114352d2591SJean-Christophe PLAGNIOL-VILLARD 		 */
11156d0f6bcfSJean-Christophe PLAGNIOL-VILLARD 		len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
11166d0f6bcfSJean-Christophe PLAGNIOL-VILLARD 		dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
1117352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (dst == NULL) {
1118352d2591SJean-Christophe PLAGNIOL-VILLARD 			printf("Error: malloc in gunzip failed!\n");
111964e40d72SWolfgang Denk 			return 1;
1120352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
112164e40d72SWolfgang Denk 		if (gunzip(dst, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE,
112264e40d72SWolfgang Denk 			   (uchar *) bmp_image,
112364e40d72SWolfgang Denk 			   &len) != 0) {
112464e40d72SWolfgang Denk 			printf("Error: no valid bmp or bmp.gz image at %lx\n",
112564e40d72SWolfgang Denk 			       bmp_image);
1126352d2591SJean-Christophe PLAGNIOL-VILLARD 			free(dst);
1127352d2591SJean-Christophe PLAGNIOL-VILLARD 			return 1;
1128352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
11296d0f6bcfSJean-Christophe PLAGNIOL-VILLARD 		if (len == CONFIG_SYS_VIDEO_LOGO_MAX_SIZE) {
113064e40d72SWolfgang Denk 			printf("Image could be truncated "
113164e40d72SWolfgang Denk 				"(increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n");
1132352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1133352d2591SJean-Christophe PLAGNIOL-VILLARD 
1134352d2591SJean-Christophe PLAGNIOL-VILLARD 		/*
1135352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * Set addr to decompressed image
1136352d2591SJean-Christophe PLAGNIOL-VILLARD 		 */
1137352d2591SJean-Christophe PLAGNIOL-VILLARD 		bmp = (bmp_image_t *) dst;
1138352d2591SJean-Christophe PLAGNIOL-VILLARD 
1139352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (!((bmp->header.signature[0] == 'B') &&
1140352d2591SJean-Christophe PLAGNIOL-VILLARD 		      (bmp->header.signature[1] == 'M'))) {
114164e40d72SWolfgang Denk 			printf("Error: no valid bmp.gz image at %lx\n",
114264e40d72SWolfgang Denk 			       bmp_image);
1143a49e0d17SMatthias Fuchs 			free(dst);
1144352d2591SJean-Christophe PLAGNIOL-VILLARD 			return 1;
1145352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1146352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1147352d2591SJean-Christophe PLAGNIOL-VILLARD 		printf("Error: no valid bmp image at %lx\n", bmp_image);
1148352d2591SJean-Christophe PLAGNIOL-VILLARD 		return 1;
1149352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_BMP_GZIP */
1150352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1151352d2591SJean-Christophe PLAGNIOL-VILLARD 
1152352d2591SJean-Christophe PLAGNIOL-VILLARD 	width = le32_to_cpu(bmp->header.width);
1153352d2591SJean-Christophe PLAGNIOL-VILLARD 	height = le32_to_cpu(bmp->header.height);
1154352d2591SJean-Christophe PLAGNIOL-VILLARD 	bpp = le16_to_cpu(bmp->header.bit_count);
1155352d2591SJean-Christophe PLAGNIOL-VILLARD 	colors = le32_to_cpu(bmp->header.colors_used);
1156352d2591SJean-Christophe PLAGNIOL-VILLARD 	compression = le32_to_cpu(bmp->header.compression);
1157352d2591SJean-Christophe PLAGNIOL-VILLARD 
115868da5b19SMarek Vasut 	debug("Display-bmp: %ld x %ld  with %d colors\n",
1159352d2591SJean-Christophe PLAGNIOL-VILLARD 	      width, height, colors);
1160352d2591SJean-Christophe PLAGNIOL-VILLARD 
1161d5011762SAnatolij Gustschin 	if (compression != BMP_BI_RGB
1162d5011762SAnatolij Gustschin #ifdef CONFIG_VIDEO_BMP_RLE8
1163d5011762SAnatolij Gustschin 	    && compression != BMP_BI_RLE8
1164d5011762SAnatolij Gustschin #endif
1165d5011762SAnatolij Gustschin 		) {
1166352d2591SJean-Christophe PLAGNIOL-VILLARD 		printf("Error: compression type %ld not supported\n",
1167352d2591SJean-Christophe PLAGNIOL-VILLARD 		       compression);
1168a49e0d17SMatthias Fuchs #ifdef CONFIG_VIDEO_BMP_GZIP
1169a49e0d17SMatthias Fuchs 		if (dst)
1170a49e0d17SMatthias Fuchs 			free(dst);
1171a49e0d17SMatthias Fuchs #endif
1172352d2591SJean-Christophe PLAGNIOL-VILLARD 		return 1;
1173352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1174352d2591SJean-Christophe PLAGNIOL-VILLARD 
1175352d2591SJean-Christophe PLAGNIOL-VILLARD 	padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3;
1176352d2591SJean-Christophe PLAGNIOL-VILLARD 
11771ca298ceSMatthias Weisser #ifdef CONFIG_SPLASH_SCREEN_ALIGN
11781ca298ceSMatthias Weisser 	if (x == BMP_ALIGN_CENTER)
11791ca298ceSMatthias Weisser 		x = max(0, (VIDEO_VISIBLE_COLS - width) / 2);
11801ca298ceSMatthias Weisser 	else if (x < 0)
11811ca298ceSMatthias Weisser 		x = max(0, VIDEO_VISIBLE_COLS - width + x + 1);
11821ca298ceSMatthias Weisser 
11831ca298ceSMatthias Weisser 	if (y == BMP_ALIGN_CENTER)
11841ca298ceSMatthias Weisser 		y = max(0, (VIDEO_VISIBLE_ROWS - height) / 2);
11851ca298ceSMatthias Weisser 	else if (y < 0)
11861ca298ceSMatthias Weisser 		y = max(0, VIDEO_VISIBLE_ROWS - height + y + 1);
11871ca298ceSMatthias Weisser #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
11881ca298ceSMatthias Weisser 
1189352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((x + width) > VIDEO_VISIBLE_COLS)
1190352d2591SJean-Christophe PLAGNIOL-VILLARD 		width = VIDEO_VISIBLE_COLS - x;
1191352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((y + height) > VIDEO_VISIBLE_ROWS)
1192352d2591SJean-Christophe PLAGNIOL-VILLARD 		height = VIDEO_VISIBLE_ROWS - y;
1193352d2591SJean-Christophe PLAGNIOL-VILLARD 
1194352d2591SJean-Christophe PLAGNIOL-VILLARD 	bmap = (uchar *) bmp + le32_to_cpu(bmp->header.data_offset);
1195352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb = (uchar *) (video_fb_address +
1196352d2591SJean-Christophe PLAGNIOL-VILLARD 			((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) +
1197352d2591SJean-Christophe PLAGNIOL-VILLARD 			x * VIDEO_PIXEL_SIZE);
1198352d2591SJean-Christophe PLAGNIOL-VILLARD 
1199d5011762SAnatolij Gustschin #ifdef CONFIG_VIDEO_BMP_RLE8
1200d5011762SAnatolij Gustschin 	if (compression == BMP_BI_RLE8) {
120164e40d72SWolfgang Denk 		return display_rle8_bitmap(bmp, x, y, width, height);
1202d5011762SAnatolij Gustschin 	}
1203d5011762SAnatolij Gustschin #endif
1204d5011762SAnatolij Gustschin 
120568f6618bSTimur Tabi 	/* We handle only 4, 8, or 24 bpp bitmaps */
1206352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (le16_to_cpu(bmp->header.bit_count)) {
120768f6618bSTimur Tabi 	case 4:
120868f6618bSTimur Tabi 		padded_line -= width / 2;
120968f6618bSTimur Tabi 		ycount = height;
121068f6618bSTimur Tabi 
121168f6618bSTimur Tabi 		switch (VIDEO_DATA_FORMAT) {
121268f6618bSTimur Tabi 		case GDF_32BIT_X888RGB:
121368f6618bSTimur Tabi 			while (ycount--) {
121468f6618bSTimur Tabi 				WATCHDOG_RESET();
121568f6618bSTimur Tabi 				/*
121668f6618bSTimur Tabi 				 * Don't assume that 'width' is an
121768f6618bSTimur Tabi 				 * even number
121868f6618bSTimur Tabi 				 */
121968f6618bSTimur Tabi 				for (xcount = 0; xcount < width; xcount++) {
122068f6618bSTimur Tabi 					uchar idx;
122168f6618bSTimur Tabi 
122268f6618bSTimur Tabi 					if (xcount & 1) {
122368f6618bSTimur Tabi 						idx = *bmap & 0xF;
122468f6618bSTimur Tabi 						bmap++;
122568f6618bSTimur Tabi 					} else
122668f6618bSTimur Tabi 						idx = *bmap >> 4;
122768f6618bSTimur Tabi 					cte = bmp->color_table[idx];
122868f6618bSTimur Tabi 					FILL_32BIT_X888RGB(cte.red, cte.green,
122968f6618bSTimur Tabi 							   cte.blue);
123068f6618bSTimur Tabi 				}
123168f6618bSTimur Tabi 				bmap += padded_line;
123268f6618bSTimur Tabi 				fb -= (VIDEO_VISIBLE_COLS + width) *
123368f6618bSTimur Tabi 					VIDEO_PIXEL_SIZE;
123468f6618bSTimur Tabi 			}
123568f6618bSTimur Tabi 			break;
123668f6618bSTimur Tabi 		default:
123768f6618bSTimur Tabi 			puts("4bpp bitmap unsupported with current "
123868f6618bSTimur Tabi 			     "video mode\n");
123968f6618bSTimur Tabi 			break;
124068f6618bSTimur Tabi 		}
124168f6618bSTimur Tabi 		break;
124268f6618bSTimur Tabi 
1243352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 8:
1244352d2591SJean-Christophe PLAGNIOL-VILLARD 		padded_line -= width;
1245352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
1246352d2591SJean-Christophe PLAGNIOL-VILLARD 			/* Copy colormap */
1247352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (xcount = 0; xcount < colors; ++xcount) {
1248352d2591SJean-Christophe PLAGNIOL-VILLARD 				cte = bmp->color_table[xcount];
124964e40d72SWolfgang Denk 				video_set_lut(xcount, cte.red, cte.green,
125064e40d72SWolfgang Denk 					      cte.blue);
1251352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1252352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1253352d2591SJean-Christophe PLAGNIOL-VILLARD 		ycount = height;
1254352d2591SJean-Christophe PLAGNIOL-VILLARD 		switch (VIDEO_DATA_FORMAT) {
1255352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF__8BIT_INDEX:
1256352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1257352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1258352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1259352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1260352d2591SJean-Christophe PLAGNIOL-VILLARD 					*fb++ = *bmap++;
1261352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1262352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
126364e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
126464e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1265352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1266352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1267352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF__8BIT_332RGB:
1268352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1269352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1270352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1271352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1272352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
127364e40d72SWolfgang Denk 					FILL_8BIT_332RGB(cte.red, cte.green,
127464e40d72SWolfgang Denk 							 cte.blue);
1275352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1276352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
127764e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
127864e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1279352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1280352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1281352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_15BIT_555RGB:
1282352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1283e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1284e84d568fSAnatolij Gustschin 				int xpos = x;
1285e84d568fSAnatolij Gustschin #endif
1286352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1287352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1288352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1289352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
1290cc347801SAndrew Dyer #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1291e84d568fSAnatolij Gustschin 					fill_555rgb_pswap(fb, xpos++, cte.red,
129264e40d72SWolfgang Denk 							  cte.green,
129364e40d72SWolfgang Denk 							  cte.blue);
1294e84d568fSAnatolij Gustschin 					fb += 2;
1295cc347801SAndrew Dyer #else
129664e40d72SWolfgang Denk 					FILL_15BIT_555RGB(cte.red, cte.green,
129764e40d72SWolfgang Denk 							  cte.blue);
1298e84d568fSAnatolij Gustschin #endif
1299352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1300352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
130164e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
130264e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1303352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1304352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1305352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_16BIT_565RGB:
1306352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1307352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1308352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1309352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1310352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
131164e40d72SWolfgang Denk 					FILL_16BIT_565RGB(cte.red, cte.green,
131264e40d72SWolfgang Denk 							  cte.blue);
1313352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1314352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
131564e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
131664e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1317352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1318352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1319352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_32BIT_X888RGB:
1320352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1321352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1322352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1323352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1324352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
132564e40d72SWolfgang Denk 					FILL_32BIT_X888RGB(cte.red, cte.green,
132664e40d72SWolfgang Denk 							   cte.blue);
1327352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1328352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
132964e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
133064e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1331352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1332352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1333352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_24BIT_888RGB:
1334352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1335352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1336352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1337352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1338352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
133964e40d72SWolfgang Denk 					FILL_24BIT_888RGB(cte.red, cte.green,
134064e40d72SWolfgang Denk 							  cte.blue);
1341352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1342352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
134364e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
134464e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1345352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1346352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1347352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1348352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1349352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 24:
1350352d2591SJean-Christophe PLAGNIOL-VILLARD 		padded_line -= 3 * width;
1351352d2591SJean-Christophe PLAGNIOL-VILLARD 		ycount = height;
1352352d2591SJean-Christophe PLAGNIOL-VILLARD 		switch (VIDEO_DATA_FORMAT) {
1353352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF__8BIT_332RGB:
1354352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1355352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1356352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1357352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
135864e40d72SWolfgang Denk 					FILL_8BIT_332RGB(bmap[2], bmap[1],
135964e40d72SWolfgang Denk 							 bmap[0]);
1360352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1361352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1362352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
136364e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
136464e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1365352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1366352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1367352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_15BIT_555RGB:
1368352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1369e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1370e84d568fSAnatolij Gustschin 				int xpos = x;
1371e84d568fSAnatolij Gustschin #endif
1372352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1373352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1374352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1375cc347801SAndrew Dyer #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1376e84d568fSAnatolij Gustschin 					fill_555rgb_pswap(fb, xpos++, bmap[2],
1377e84d568fSAnatolij Gustschin 							  bmap[1], bmap[0]);
1378e84d568fSAnatolij Gustschin 					fb += 2;
1379cc347801SAndrew Dyer #else
138064e40d72SWolfgang Denk 					FILL_15BIT_555RGB(bmap[2], bmap[1],
138164e40d72SWolfgang Denk 							  bmap[0]);
1382e84d568fSAnatolij Gustschin #endif
1383352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1384352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1385352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
138664e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
138764e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1388352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1389352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1390352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_16BIT_565RGB:
1391352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1392352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1393352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1394352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
139564e40d72SWolfgang Denk 					FILL_16BIT_565RGB(bmap[2], bmap[1],
139664e40d72SWolfgang Denk 							  bmap[0]);
1397352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1398352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1399352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
140064e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
140164e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1402352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1403352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1404352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_32BIT_X888RGB:
1405352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1406352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1407352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1408352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
140964e40d72SWolfgang Denk 					FILL_32BIT_X888RGB(bmap[2], bmap[1],
141064e40d72SWolfgang Denk 							   bmap[0]);
1411352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1412352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1413352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
141464e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
141564e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1416352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1417352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1418352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_24BIT_888RGB:
1419352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1420352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET();
1421352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1422352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
142364e40d72SWolfgang Denk 					FILL_24BIT_888RGB(bmap[2], bmap[1],
142464e40d72SWolfgang Denk 							  bmap[0]);
1425352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1426352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1427352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
142864e40d72SWolfgang Denk 				fb -= (VIDEO_VISIBLE_COLS + width) *
142964e40d72SWolfgang Denk 							VIDEO_PIXEL_SIZE;
1430352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1431352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1432352d2591SJean-Christophe PLAGNIOL-VILLARD 		default:
143364e40d72SWolfgang Denk 			printf("Error: 24 bits/pixel bitmap incompatible "
143464e40d72SWolfgang Denk 				"with current video mode\n");
1435352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1436352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1437352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1438352d2591SJean-Christophe PLAGNIOL-VILLARD 	default:
1439352d2591SJean-Christophe PLAGNIOL-VILLARD 		printf("Error: %d bit/pixel bitmaps not supported by U-Boot\n",
1440352d2591SJean-Christophe PLAGNIOL-VILLARD 			le16_to_cpu(bmp->header.bit_count));
1441352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1442352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1443352d2591SJean-Christophe PLAGNIOL-VILLARD 
1444352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_GZIP
1445352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (dst) {
1446352d2591SJean-Christophe PLAGNIOL-VILLARD 		free(dst);
1447352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1448352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1449352d2591SJean-Christophe PLAGNIOL-VILLARD 
1450352d2591SJean-Christophe PLAGNIOL-VILLARD 	return (0);
1451352d2591SJean-Christophe PLAGNIOL-VILLARD }
1452352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1453352d2591SJean-Christophe PLAGNIOL-VILLARD 
1454352d2591SJean-Christophe PLAGNIOL-VILLARD 
1455352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_LOGO
1456352d2591SJean-Christophe PLAGNIOL-VILLARD void logo_plot(void *screen, int width, int x, int y)
1457352d2591SJean-Christophe PLAGNIOL-VILLARD {
1458352d2591SJean-Christophe PLAGNIOL-VILLARD 
1459352d2591SJean-Christophe PLAGNIOL-VILLARD 	int xcount, i;
1460352d2591SJean-Christophe PLAGNIOL-VILLARD 	int skip = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE;
1461be129aa7SMatthias Weisser 	int ycount = video_logo_height;
1462352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char r, g, b, *logo_red, *logo_blue, *logo_green;
1463352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char *source;
1464d9015f6aSAnatolij Gustschin 	unsigned char *dest = (unsigned char *) screen +
146564e40d72SWolfgang Denk 		((y * width * VIDEO_PIXEL_SIZE) + x * VIDEO_PIXEL_SIZE);
1466352d2591SJean-Christophe PLAGNIOL-VILLARD 
1467352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_LOGO
1468352d2591SJean-Christophe PLAGNIOL-VILLARD 	source = bmp_logo_bitmap;
1469352d2591SJean-Christophe PLAGNIOL-VILLARD 
1470352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Allocate temporary space for computing colormap */
1471352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_red = malloc(BMP_LOGO_COLORS);
1472352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_green = malloc(BMP_LOGO_COLORS);
1473352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_blue = malloc(BMP_LOGO_COLORS);
1474352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Compute color map */
1475352d2591SJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
1476352d2591SJean-Christophe PLAGNIOL-VILLARD 		logo_red[i] = (bmp_logo_palette[i] & 0x0f00) >> 4;
1477352d2591SJean-Christophe PLAGNIOL-VILLARD 		logo_green[i] = (bmp_logo_palette[i] & 0x00f0);
1478352d2591SJean-Christophe PLAGNIOL-VILLARD 		logo_blue[i] = (bmp_logo_palette[i] & 0x000f) << 4;
1479352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1480352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1481352d2591SJean-Christophe PLAGNIOL-VILLARD 	source = linux_logo;
1482352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_red = linux_logo_red;
1483352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_green = linux_logo_green;
1484352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_blue = linux_logo_blue;
1485352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1486352d2591SJean-Christophe PLAGNIOL-VILLARD 
1487352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
1488352d2591SJean-Christophe PLAGNIOL-VILLARD 		for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
1489352d2591SJean-Christophe PLAGNIOL-VILLARD 			video_set_lut(i + VIDEO_LOGO_LUT_OFFSET,
149064e40d72SWolfgang Denk 				      logo_red[i], logo_green[i],
149164e40d72SWolfgang Denk 				      logo_blue[i]);
1492352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1493352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1494352d2591SJean-Christophe PLAGNIOL-VILLARD 
1495352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (ycount--) {
1496e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1497e84d568fSAnatolij Gustschin 		int xpos = x;
1498e84d568fSAnatolij Gustschin #endif
1499352d2591SJean-Christophe PLAGNIOL-VILLARD 		xcount = VIDEO_LOGO_WIDTH;
1500352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (xcount--) {
1501352d2591SJean-Christophe PLAGNIOL-VILLARD 			r = logo_red[*source - VIDEO_LOGO_LUT_OFFSET];
1502352d2591SJean-Christophe PLAGNIOL-VILLARD 			g = logo_green[*source - VIDEO_LOGO_LUT_OFFSET];
1503352d2591SJean-Christophe PLAGNIOL-VILLARD 			b = logo_blue[*source - VIDEO_LOGO_LUT_OFFSET];
1504352d2591SJean-Christophe PLAGNIOL-VILLARD 
1505352d2591SJean-Christophe PLAGNIOL-VILLARD 			switch (VIDEO_DATA_FORMAT) {
1506352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF__8BIT_INDEX:
1507352d2591SJean-Christophe PLAGNIOL-VILLARD 				*dest = *source;
1508352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1509352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF__8BIT_332RGB:
151064e40d72SWolfgang Denk 				*dest = ((r >> 5) << 5) |
151164e40d72SWolfgang Denk 					((g >> 5) << 2) |
151264e40d72SWolfgang Denk 					 (b >> 6);
1513352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1514352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_15BIT_555RGB:
1515cc347801SAndrew Dyer #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1516cc347801SAndrew Dyer 				fill_555rgb_pswap(dest, xpos++, r, g, b);
1517cc347801SAndrew Dyer #else
1518352d2591SJean-Christophe PLAGNIOL-VILLARD 				*(unsigned short *) dest =
151964e40d72SWolfgang Denk 					SWAP16((unsigned short) (
152064e40d72SWolfgang Denk 							((r >> 3) << 10) |
152164e40d72SWolfgang Denk 							((g >> 3) <<  5) |
152264e40d72SWolfgang Denk 							 (b >> 3)));
1523bed53753SAnatolij Gustschin #endif
1524352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1525352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_16BIT_565RGB:
1526352d2591SJean-Christophe PLAGNIOL-VILLARD 				*(unsigned short *) dest =
152764e40d72SWolfgang Denk 					SWAP16((unsigned short) (
152864e40d72SWolfgang Denk 							((r >> 3) << 11) |
152964e40d72SWolfgang Denk 							((g >> 2) <<  5) |
153064e40d72SWolfgang Denk 							 (b >> 3)));
1531352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1532352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_32BIT_X888RGB:
1533352d2591SJean-Christophe PLAGNIOL-VILLARD 				*(unsigned long *) dest =
153464e40d72SWolfgang Denk 					SWAP32((unsigned long) (
153564e40d72SWolfgang Denk 							(r << 16) |
153664e40d72SWolfgang Denk 							(g <<  8) |
153764e40d72SWolfgang Denk 							 b));
1538352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1539352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_24BIT_888RGB:
1540352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_FB_LITTLE_ENDIAN
1541352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[0] = b;
1542352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[1] = g;
1543352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[2] = r;
1544352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1545352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[0] = r;
1546352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[1] = g;
1547352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[2] = b;
1548352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1549352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1550352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1551352d2591SJean-Christophe PLAGNIOL-VILLARD 			source++;
1552352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest += VIDEO_PIXEL_SIZE;
1553352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1554352d2591SJean-Christophe PLAGNIOL-VILLARD 		dest += skip;
1555352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1556352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_LOGO
1557352d2591SJean-Christophe PLAGNIOL-VILLARD 	free(logo_red);
1558352d2591SJean-Christophe PLAGNIOL-VILLARD 	free(logo_green);
1559352d2591SJean-Christophe PLAGNIOL-VILLARD 	free(logo_blue);
1560352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1561352d2591SJean-Christophe PLAGNIOL-VILLARD }
1562352d2591SJean-Christophe PLAGNIOL-VILLARD 
1563352d2591SJean-Christophe PLAGNIOL-VILLARD static void *video_logo(void)
1564352d2591SJean-Christophe PLAGNIOL-VILLARD {
1565352d2591SJean-Christophe PLAGNIOL-VILLARD 	char info[128];
1566a9a62af1SWolfgang Denk 	int space, len;
1567a9a62af1SWolfgang Denk 	__maybe_unused int y_off = 0;
1568352d2591SJean-Christophe PLAGNIOL-VILLARD 
1569352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SPLASH_SCREEN
1570352d2591SJean-Christophe PLAGNIOL-VILLARD 	char *s;
1571352d2591SJean-Christophe PLAGNIOL-VILLARD 	ulong addr;
1572352d2591SJean-Christophe PLAGNIOL-VILLARD 
157357912939SWolfgang Denk 	s = getenv("splashimage");
157457912939SWolfgang Denk 	if (s != NULL) {
15751ca298ceSMatthias Weisser 		int x = 0, y = 0;
1576352d2591SJean-Christophe PLAGNIOL-VILLARD 
15771ca298ceSMatthias Weisser 		addr = simple_strtoul(s, NULL, 16);
15781ca298ceSMatthias Weisser #ifdef CONFIG_SPLASH_SCREEN_ALIGN
157957912939SWolfgang Denk 		s = getenv("splashpos");
158057912939SWolfgang Denk 		if (s != NULL) {
15811ca298ceSMatthias Weisser 			if (s[0] == 'm')
15821ca298ceSMatthias Weisser 				x = BMP_ALIGN_CENTER;
15831ca298ceSMatthias Weisser 			else
15841ca298ceSMatthias Weisser 				x = simple_strtol(s, NULL, 0);
15851ca298ceSMatthias Weisser 
158657912939SWolfgang Denk 			s = strchr(s + 1, ',');
158757912939SWolfgang Denk 			if (s != NULL) {
15881ca298ceSMatthias Weisser 				if (s[1] == 'm')
15891ca298ceSMatthias Weisser 					y = BMP_ALIGN_CENTER;
15901ca298ceSMatthias Weisser 				else
15911ca298ceSMatthias Weisser 					y = simple_strtol(s + 1, NULL, 0);
15921ca298ceSMatthias Weisser 			}
15931ca298ceSMatthias Weisser 		}
15941ca298ceSMatthias Weisser #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
15951ca298ceSMatthias Weisser 
15961ca298ceSMatthias Weisser 		if (video_display_bitmap(addr, x, y) == 0) {
1597be129aa7SMatthias Weisser 			video_logo_height = 0;
1598352d2591SJean-Christophe PLAGNIOL-VILLARD 			return ((void *) (video_fb_address));
1599352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1600352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1601352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_SPLASH_SCREEN */
1602352d2591SJean-Christophe PLAGNIOL-VILLARD 
1603352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_plot(video_fb_address, VIDEO_COLS, 0, 0);
1604352d2591SJean-Christophe PLAGNIOL-VILLARD 
1605ce0f709bSAndreas Bießmann 	sprintf(info, " %s", version_string);
16063dcbe628SAnatolij Gustschin 
16073dcbe628SAnatolij Gustschin 	space = (VIDEO_LINE_LEN / 2 - VIDEO_INFO_X) / VIDEO_FONT_WIDTH;
16083dcbe628SAnatolij Gustschin 	len = strlen(info);
16093dcbe628SAnatolij Gustschin 
16103dcbe628SAnatolij Gustschin 	if (len > space) {
16113dcbe628SAnatolij Gustschin 		video_drawchars(VIDEO_INFO_X, VIDEO_INFO_Y,
16123dcbe628SAnatolij Gustschin 				(uchar *) info, space);
16133dcbe628SAnatolij Gustschin 		video_drawchars(VIDEO_INFO_X + VIDEO_FONT_WIDTH,
16143dcbe628SAnatolij Gustschin 				VIDEO_INFO_Y + VIDEO_FONT_HEIGHT,
16153dcbe628SAnatolij Gustschin 				(uchar *) info + space, len - space);
16163dcbe628SAnatolij Gustschin 		y_off = 1;
16173dcbe628SAnatolij Gustschin 	} else
1618352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_drawstring(VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *) info);
1619352d2591SJean-Christophe PLAGNIOL-VILLARD 
1620352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_EXTRA_INFO
1621352d2591SJean-Christophe PLAGNIOL-VILLARD 	{
162264e40d72SWolfgang Denk 		int i, n =
162364e40d72SWolfgang Denk 			((video_logo_height -
162464e40d72SWolfgang Denk 			  VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT);
1625352d2591SJean-Christophe PLAGNIOL-VILLARD 
1626352d2591SJean-Christophe PLAGNIOL-VILLARD 		for (i = 1; i < n; i++) {
1627352d2591SJean-Christophe PLAGNIOL-VILLARD 			video_get_info_str(i, info);
16283dcbe628SAnatolij Gustschin 			if (!*info)
16293dcbe628SAnatolij Gustschin 				continue;
16303dcbe628SAnatolij Gustschin 
16313dcbe628SAnatolij Gustschin 			len = strlen(info);
16323dcbe628SAnatolij Gustschin 			if (len > space) {
16333dcbe628SAnatolij Gustschin 				video_drawchars(VIDEO_INFO_X,
16343dcbe628SAnatolij Gustschin 						VIDEO_INFO_Y +
163564e40d72SWolfgang Denk 						(i + y_off) *
163664e40d72SWolfgang Denk 							VIDEO_FONT_HEIGHT,
16373dcbe628SAnatolij Gustschin 						(uchar *) info, space);
16383dcbe628SAnatolij Gustschin 				y_off++;
163964e40d72SWolfgang Denk 				video_drawchars(VIDEO_INFO_X +
164064e40d72SWolfgang Denk 						VIDEO_FONT_WIDTH,
16413dcbe628SAnatolij Gustschin 						VIDEO_INFO_Y +
164264e40d72SWolfgang Denk 							(i + y_off) *
164364e40d72SWolfgang Denk 							VIDEO_FONT_HEIGHT,
16443dcbe628SAnatolij Gustschin 						(uchar *) info + space,
16453dcbe628SAnatolij Gustschin 						len - space);
16463dcbe628SAnatolij Gustschin 			} else {
1647352d2591SJean-Christophe PLAGNIOL-VILLARD 				video_drawstring(VIDEO_INFO_X,
16483dcbe628SAnatolij Gustschin 						 VIDEO_INFO_Y +
164964e40d72SWolfgang Denk 						 (i + y_off) *
165064e40d72SWolfgang Denk 							VIDEO_FONT_HEIGHT,
1651352d2591SJean-Christophe PLAGNIOL-VILLARD 						 (uchar *) info);
1652352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1653352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
16543dcbe628SAnatolij Gustschin 	}
1655352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1656352d2591SJean-Christophe PLAGNIOL-VILLARD 
1657be129aa7SMatthias Weisser 	return (video_fb_address + video_logo_height * VIDEO_LINE_LEN);
1658352d2591SJean-Christophe PLAGNIOL-VILLARD }
1659352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1660352d2591SJean-Christophe PLAGNIOL-VILLARD 
1661352d2591SJean-Christophe PLAGNIOL-VILLARD static int video_init(void)
1662352d2591SJean-Christophe PLAGNIOL-VILLARD {
1663352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char color8;
1664352d2591SJean-Christophe PLAGNIOL-VILLARD 
166557912939SWolfgang Denk 	pGD = video_hw_init();
166657912939SWolfgang Denk 	if (pGD == NULL)
1667352d2591SJean-Christophe PLAGNIOL-VILLARD 		return -1;
1668352d2591SJean-Christophe PLAGNIOL-VILLARD 
1669352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_fb_address = (void *) VIDEO_FB_ADRS;
1670352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_HW_CURSOR
1671352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_init_hw_cursor(VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
1672352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1673352d2591SJean-Christophe PLAGNIOL-VILLARD 
1674352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Init drawing pats */
1675352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (VIDEO_DATA_FORMAT) {
1676352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_INDEX:
167764e40d72SWolfgang Denk 		video_set_lut(0x01, CONSOLE_FG_COL, CONSOLE_FG_COL,
167864e40d72SWolfgang Denk 			      CONSOLE_FG_COL);
167964e40d72SWolfgang Denk 		video_set_lut(0x00, CONSOLE_BG_COL, CONSOLE_BG_COL,
168064e40d72SWolfgang Denk 			      CONSOLE_BG_COL);
1681352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = 0x01010101;
1682352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = 0x00000000;
1683352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1684352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_332RGB:
1685352d2591SJean-Christophe PLAGNIOL-VILLARD 		color8 = ((CONSOLE_FG_COL & 0xe0) |
168664e40d72SWolfgang Denk 			  ((CONSOLE_FG_COL >> 3) & 0x1c) |
168764e40d72SWolfgang Denk 			  CONSOLE_FG_COL >> 6);
168864e40d72SWolfgang Denk 		fgx = (color8 << 24) | (color8 << 16) | (color8 << 8) |
168964e40d72SWolfgang Denk 			color8;
1690352d2591SJean-Christophe PLAGNIOL-VILLARD 		color8 = ((CONSOLE_BG_COL & 0xe0) |
169164e40d72SWolfgang Denk 			  ((CONSOLE_BG_COL >> 3) & 0x1c) |
169264e40d72SWolfgang Denk 			  CONSOLE_BG_COL >> 6);
169364e40d72SWolfgang Denk 		bgx = (color8 << 24) | (color8 << 16) | (color8 << 8) |
169464e40d72SWolfgang Denk 			color8;
1695352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1696352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_15BIT_555RGB:
1697352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = (((CONSOLE_FG_COL >> 3) << 26) |
169864e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) << 21) |
169964e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) << 16) |
170064e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) << 10) |
170164e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) <<  5) |
1702352d2591SJean-Christophe PLAGNIOL-VILLARD 			(CONSOLE_FG_COL >> 3));
1703352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = (((CONSOLE_BG_COL >> 3) << 26) |
170464e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) << 21) |
170564e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) << 16) |
170664e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) << 10) |
170764e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) <<  5) |
1708352d2591SJean-Christophe PLAGNIOL-VILLARD 			(CONSOLE_BG_COL >> 3));
1709352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1710352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_16BIT_565RGB:
1711352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = (((CONSOLE_FG_COL >> 3) << 27) |
171264e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 2) << 21) |
171364e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) << 16) |
171464e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 3) << 11) |
171564e40d72SWolfgang Denk 		       ((CONSOLE_FG_COL >> 2) <<  5) |
1716352d2591SJean-Christophe PLAGNIOL-VILLARD 			(CONSOLE_FG_COL >> 3));
1717352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = (((CONSOLE_BG_COL >> 3) << 27) |
171864e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 2) << 21) |
171964e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) << 16) |
172064e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 3) << 11) |
172164e40d72SWolfgang Denk 		       ((CONSOLE_BG_COL >> 2) <<  5) |
1722352d2591SJean-Christophe PLAGNIOL-VILLARD 			(CONSOLE_BG_COL >> 3));
1723352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1724352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_32BIT_X888RGB:
172564e40d72SWolfgang Denk 		fgx =	(CONSOLE_FG_COL << 16) |
172664e40d72SWolfgang Denk 			(CONSOLE_FG_COL <<  8) |
172764e40d72SWolfgang Denk 			 CONSOLE_FG_COL;
172864e40d72SWolfgang Denk 		bgx =	(CONSOLE_BG_COL << 16) |
172964e40d72SWolfgang Denk 			(CONSOLE_BG_COL <<  8) |
173064e40d72SWolfgang Denk 			 CONSOLE_BG_COL;
1731352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1732352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_24BIT_888RGB:
173364e40d72SWolfgang Denk 		fgx =	(CONSOLE_FG_COL << 24) |
173464e40d72SWolfgang Denk 			(CONSOLE_FG_COL << 16) |
173564e40d72SWolfgang Denk 			(CONSOLE_FG_COL <<  8) |
173664e40d72SWolfgang Denk 			 CONSOLE_FG_COL;
173764e40d72SWolfgang Denk 		bgx =	(CONSOLE_BG_COL << 24) |
173864e40d72SWolfgang Denk 			(CONSOLE_BG_COL << 16) |
173964e40d72SWolfgang Denk 			(CONSOLE_BG_COL <<  8) |
174064e40d72SWolfgang Denk 			 CONSOLE_BG_COL;
1741352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1742352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1743352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx ^ bgx;
1744352d2591SJean-Christophe PLAGNIOL-VILLARD 
1745352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_LOGO
1746352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Plot the logo and get start point of console */
174772c65f6fSWolfgang Denk 	debug("Video: Drawing the logo ...\n");
1748352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_console_address = video_logo();
1749352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1750352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_console_address = video_fb_address;
1751352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1752352d2591SJean-Christophe PLAGNIOL-VILLARD 
1753352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Initialize the console */
1754352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_col = 0;
1755352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_row = 0;
1756352d2591SJean-Christophe PLAGNIOL-VILLARD 
1757352d2591SJean-Christophe PLAGNIOL-VILLARD 	return 0;
1758352d2591SJean-Christophe PLAGNIOL-VILLARD }
1759352d2591SJean-Christophe PLAGNIOL-VILLARD 
17606cc7ba9eSWolfgang Denk /*
17616cc7ba9eSWolfgang Denk  * Implement a weak default function for boards that optionally
17626cc7ba9eSWolfgang Denk  * need to skip the video initialization.
17636cc7ba9eSWolfgang Denk  */
17646cc7ba9eSWolfgang Denk int __board_video_skip(void)
17656cc7ba9eSWolfgang Denk {
17666cc7ba9eSWolfgang Denk 	/* As default, don't skip test */
17676cc7ba9eSWolfgang Denk 	return 0;
17686cc7ba9eSWolfgang Denk }
176964e40d72SWolfgang Denk 
177064e40d72SWolfgang Denk int board_video_skip(void)
177164e40d72SWolfgang Denk 	__attribute__ ((weak, alias("__board_video_skip")));
17726cc7ba9eSWolfgang Denk 
1773352d2591SJean-Christophe PLAGNIOL-VILLARD int drv_video_init(void)
1774352d2591SJean-Christophe PLAGNIOL-VILLARD {
1775352d2591SJean-Christophe PLAGNIOL-VILLARD 	int skip_dev_init;
177652cb4d4fSJean-Christophe PLAGNIOL-VILLARD 	struct stdio_dev console_dev;
1777352d2591SJean-Christophe PLAGNIOL-VILLARD 
17786cc7ba9eSWolfgang Denk 	/* Check if video initialization should be skipped */
17796cc7ba9eSWolfgang Denk 	if (board_video_skip())
17806cc7ba9eSWolfgang Denk 		return 0;
17816cc7ba9eSWolfgang Denk 
1782352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Init video chip - returns with framebuffer cleared */
1783f62f6469SWolfgang Denk 	skip_dev_init = (video_init() == -1);
1784352d2591SJean-Christophe PLAGNIOL-VILLARD 
1785f62f6469SWolfgang Denk #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
178672c65f6fSWolfgang Denk 	debug("KBD: Keyboard init ...\n");
1787f62f6469SWolfgang Denk 	skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
1788f62f6469SWolfgang Denk #endif
1789f62f6469SWolfgang Denk 
1790f62f6469SWolfgang Denk 	if (skip_dev_init)
1791f62f6469SWolfgang Denk 		return 0;
1792f62f6469SWolfgang Denk 
1793352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Init vga device */
1794352d2591SJean-Christophe PLAGNIOL-VILLARD 	memset(&console_dev, 0, sizeof(console_dev));
1795352d2591SJean-Christophe PLAGNIOL-VILLARD 	strcpy(console_dev.name, "vga");
1796352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.ext = DEV_EXT_VIDEO;	/* Video extensions */
1797352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
1798352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.putc = video_putc;	/* 'putc' function */
1799352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.puts = video_puts;	/* 'puts' function */
1800352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.tstc = NULL;	/* 'tstc' function */
1801352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.getc = NULL;	/* 'getc' function */
1802352d2591SJean-Christophe PLAGNIOL-VILLARD 
1803f62f6469SWolfgang Denk #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
1804f62f6469SWolfgang Denk 	/* Also init console device */
1805f62f6469SWolfgang Denk 	console_dev.flags |= DEV_FLAGS_INPUT;
1806352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.tstc = VIDEO_TSTC_FCT;	/* 'tstc' function */
1807352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.getc = VIDEO_GETC_FCT;	/* 'getc' function */
1808352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
1809f62f6469SWolfgang Denk 
181052cb4d4fSJean-Christophe PLAGNIOL-VILLARD 	if (stdio_register(&console_dev) != 0)
1811352d2591SJean-Christophe PLAGNIOL-VILLARD 		return 0;
1812f62f6469SWolfgang Denk 
1813f62f6469SWolfgang Denk 	/* Return success */
1814f62f6469SWolfgang Denk 	return 1;
1815352d2591SJean-Christophe PLAGNIOL-VILLARD }
1816