xref: /rk3399_rockchip-uboot/drivers/video/cfb_console.c (revision ce0f709bcd52bbe5f432771ad3a18bd3d5a6747f)
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
32352d2591SJean-Christophe PLAGNIOL-VILLARD  * information strings (that normaly goes to serial port) can be drawed.
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.
39352d2591SJean-Christophe PLAGNIOL-VILLARD 
40352d2591SJean-Christophe PLAGNIOL-VILLARD  The driver uses graphic specific defines/parameters/functions:
41352d2591SJean-Christophe PLAGNIOL-VILLARD 
42352d2591SJean-Christophe PLAGNIOL-VILLARD  (for SMI LynxE graphic chip)
43352d2591SJean-Christophe PLAGNIOL-VILLARD 
44352d2591SJean-Christophe PLAGNIOL-VILLARD  CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810
45352d2591SJean-Christophe PLAGNIOL-VILLARD  VIDEO_FB_LITTLE_ENDIAN	 - framebuffer organisation default: big endian
46352d2591SJean-Christophe PLAGNIOL-VILLARD  VIDEO_HW_RECTFILL	 - graphic driver supports hardware rectangle fill
47352d2591SJean-Christophe PLAGNIOL-VILLARD  VIDEO_HW_BITBLT	 - graphic driver supports hardware bit blt
48352d2591SJean-Christophe PLAGNIOL-VILLARD 
49352d2591SJean-Christophe PLAGNIOL-VILLARD  Console Parameters are set by graphic drivers global struct:
50352d2591SJean-Christophe PLAGNIOL-VILLARD 
51352d2591SJean-Christophe PLAGNIOL-VILLARD  VIDEO_VISIBLE_COLS	     - x resolution
52352d2591SJean-Christophe PLAGNIOL-VILLARD  VIDEO_VISIBLE_ROWS	     - y resolution
53352d2591SJean-Christophe PLAGNIOL-VILLARD  VIDEO_PIXEL_SIZE	     - storage size in byte per pixel
54352d2591SJean-Christophe PLAGNIOL-VILLARD  VIDEO_DATA_FORMAT	     - graphical data format GDF
55352d2591SJean-Christophe PLAGNIOL-VILLARD  VIDEO_FB_ADRS		     - start of video memory
56352d2591SJean-Christophe PLAGNIOL-VILLARD 
57352d2591SJean-Christophe PLAGNIOL-VILLARD  CONFIG_I8042_KBD	     - AT Keyboard driver for i8042
58352d2591SJean-Christophe PLAGNIOL-VILLARD  VIDEO_KBD_INIT_FCT	     - init function for keyboard
59352d2591SJean-Christophe PLAGNIOL-VILLARD  VIDEO_TSTC_FCT		     - keyboard_tstc function
60352d2591SJean-Christophe PLAGNIOL-VILLARD  VIDEO_GETC_FCT		     - keyboard_getc function
61352d2591SJean-Christophe PLAGNIOL-VILLARD 
62352d2591SJean-Christophe PLAGNIOL-VILLARD  CONFIG_CONSOLE_CURSOR	     - on/off drawing cursor is done with delay
63352d2591SJean-Christophe PLAGNIOL-VILLARD 			       loop in VIDEO_TSTC_FCT (i8042)
646d0f6bcfSJean-Christophe PLAGNIOL-VILLARD  CONFIG_SYS_CONSOLE_BLINK_COUNT     - value for delay loop - blink rate
65352d2591SJean-Christophe PLAGNIOL-VILLARD  CONFIG_CONSOLE_TIME	     - display time/date in upper right corner,
66352d2591SJean-Christophe PLAGNIOL-VILLARD 			       needs CONFIG_CMD_DATE and CONFIG_CONSOLE_CURSOR
67352d2591SJean-Christophe PLAGNIOL-VILLARD  CONFIG_VIDEO_LOGO	     - display Linux Logo in upper left corner
68352d2591SJean-Christophe PLAGNIOL-VILLARD  CONFIG_VIDEO_BMP_LOGO	     - use bmp_logo instead of linux_logo
69352d2591SJean-Christophe PLAGNIOL-VILLARD  CONFIG_CONSOLE_EXTRA_INFO   - display additional board information strings
70352d2591SJean-Christophe PLAGNIOL-VILLARD 			       that normaly goes to serial port. This define
71352d2591SJean-Christophe PLAGNIOL-VILLARD 			       requires a board specific function:
72352d2591SJean-Christophe PLAGNIOL-VILLARD 			       video_drawstring (VIDEO_INFO_X,
73352d2591SJean-Christophe PLAGNIOL-VILLARD 						 VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
74352d2591SJean-Christophe PLAGNIOL-VILLARD 						 info);
75352d2591SJean-Christophe PLAGNIOL-VILLARD 			       that fills a info buffer at i=row.
76352d2591SJean-Christophe PLAGNIOL-VILLARD 			       s.a: board/eltec/bab7xx.
77352d2591SJean-Christophe PLAGNIOL-VILLARD CONFIG_VGA_AS_SINGLE_DEVICE  - If set the framebuffer device will be initialised
78352d2591SJean-Christophe PLAGNIOL-VILLARD 			       as an output only device. The Keyboard driver
79352d2591SJean-Christophe PLAGNIOL-VILLARD 			       will not be set-up. This may be used, if you
80352d2591SJean-Christophe PLAGNIOL-VILLARD 			       have none or more than one Keyboard devices
81352d2591SJean-Christophe PLAGNIOL-VILLARD 			       (USB Keyboard, AT Keyboard).
82352d2591SJean-Christophe PLAGNIOL-VILLARD 
83352d2591SJean-Christophe PLAGNIOL-VILLARD CONFIG_VIDEO_SW_CURSOR:	     - Draws a cursor after the last character. No
84352d2591SJean-Christophe PLAGNIOL-VILLARD 			       blinking is provided. Uses the macros CURSOR_SET
85352d2591SJean-Christophe PLAGNIOL-VILLARD 			       and CURSOR_OFF.
86352d2591SJean-Christophe PLAGNIOL-VILLARD CONFIG_VIDEO_HW_CURSOR:	     - Uses the hardware cursor capability of the
87352d2591SJean-Christophe PLAGNIOL-VILLARD 			       graphic chip. Uses the macro CURSOR_SET.
88352d2591SJean-Christophe PLAGNIOL-VILLARD 			       ATTENTION: If booting an OS, the display driver
89352d2591SJean-Christophe PLAGNIOL-VILLARD 			       must disable the hardware register of the graphic
90352d2591SJean-Christophe PLAGNIOL-VILLARD 			       chip. Otherwise a blinking field is displayed
91352d2591SJean-Christophe PLAGNIOL-VILLARD */
92352d2591SJean-Christophe PLAGNIOL-VILLARD 
93352d2591SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
9409c2e90cSAndreas Bießmann #include <version.h>
95352d2591SJean-Christophe PLAGNIOL-VILLARD 
96352d2591SJean-Christophe PLAGNIOL-VILLARD #include <malloc.h>
97352d2591SJean-Christophe PLAGNIOL-VILLARD 
98352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
99352d2591SJean-Christophe PLAGNIOL-VILLARD /* Console device defines with SMI graphic				     */
100352d2591SJean-Christophe PLAGNIOL-VILLARD /* Any other graphic must change this section				     */
101352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
102352d2591SJean-Christophe PLAGNIOL-VILLARD 
103352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_SMI_LYNXEM
104352d2591SJean-Christophe PLAGNIOL-VILLARD 
105352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
106352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_RECTFILL
107352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_BITBLT
108352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
109352d2591SJean-Christophe PLAGNIOL-VILLARD 
110352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
111352d2591SJean-Christophe PLAGNIOL-VILLARD /* Defines for the CT69000 driver					     */
112352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
113352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_CT69000
114352d2591SJean-Christophe PLAGNIOL-VILLARD 
115352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
116352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_RECTFILL
117352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_BITBLT
118352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
119352d2591SJean-Christophe PLAGNIOL-VILLARD 
120352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
121352d2591SJean-Christophe PLAGNIOL-VILLARD /* Defines for the SED13806 driver					     */
122352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
123352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_SED13806
124352d2591SJean-Christophe PLAGNIOL-VILLARD 
125352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_TOTAL5200
126352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
127352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
128352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_RECTFILL
129352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_HW_BITBLT
130352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
131352d2591SJean-Christophe PLAGNIOL-VILLARD 
132352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
133352d2591SJean-Christophe PLAGNIOL-VILLARD /* Defines for the SED13806 driver					     */
134352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
135352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_SM501
136352d2591SJean-Christophe PLAGNIOL-VILLARD 
137352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_HH405
138352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_LITTLE_ENDIAN
139352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
140352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
141352d2591SJean-Christophe PLAGNIOL-VILLARD 
142352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
143bed53753SAnatolij Gustschin /* Defines for the MB862xx driver					     */
144bed53753SAnatolij Gustschin /*****************************************************************************/
145bed53753SAnatolij Gustschin #ifdef CONFIG_VIDEO_MB862xx
146bed53753SAnatolij Gustschin 
147bed53753SAnatolij Gustschin #ifdef CONFIG_VIDEO_CORALP
148bed53753SAnatolij Gustschin #define VIDEO_FB_LITTLE_ENDIAN
149bed53753SAnatolij Gustschin #endif
1505d16ca87SAnatolij Gustschin #ifdef CONFIG_VIDEO_MB862xx_ACCEL
151bed53753SAnatolij Gustschin #define VIDEO_HW_RECTFILL
152bed53753SAnatolij Gustschin #define VIDEO_HW_BITBLT
153bed53753SAnatolij Gustschin #endif
1545d16ca87SAnatolij Gustschin #endif
155bed53753SAnatolij Gustschin 
156bed53753SAnatolij Gustschin /*****************************************************************************/
157352d2591SJean-Christophe PLAGNIOL-VILLARD /* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc	     */
158352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
159352d2591SJean-Christophe PLAGNIOL-VILLARD #include <video_fb.h>
160352d2591SJean-Christophe PLAGNIOL-VILLARD 
161352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
162352d2591SJean-Christophe PLAGNIOL-VILLARD /* some Macros								     */
163352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
164352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_VISIBLE_COLS	(pGD->winSizeX)
165352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_VISIBLE_ROWS	(pGD->winSizeY)
166352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_PIXEL_SIZE	(pGD->gdfBytesPP)
167352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_DATA_FORMAT	(pGD->gdfIndex)
168352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_FB_ADRS		(pGD->frameAdrs)
169352d2591SJean-Christophe PLAGNIOL-VILLARD 
170352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
171352d2591SJean-Christophe PLAGNIOL-VILLARD /* Console device defines with i8042 keyboard controller		     */
172352d2591SJean-Christophe PLAGNIOL-VILLARD /* Any other keyboard controller must change this section		     */
173352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
174352d2591SJean-Christophe PLAGNIOL-VILLARD 
175352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_I8042_KBD
176352d2591SJean-Christophe PLAGNIOL-VILLARD #include <i8042.h>
177352d2591SJean-Christophe PLAGNIOL-VILLARD 
178352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_KBD_INIT_FCT	i8042_kbd_init()
179352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_TSTC_FCT		i8042_tstc
180352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_GETC_FCT		i8042_getc
181352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
182352d2591SJean-Christophe PLAGNIOL-VILLARD 
183352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
184352d2591SJean-Christophe PLAGNIOL-VILLARD /* Console device							     */
185352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
186352d2591SJean-Christophe PLAGNIOL-VILLARD 
187352d2591SJean-Christophe PLAGNIOL-VILLARD #include <version.h>
188352d2591SJean-Christophe PLAGNIOL-VILLARD #include <linux/types.h>
18952cb4d4fSJean-Christophe PLAGNIOL-VILLARD #include <stdio_dev.h>
190352d2591SJean-Christophe PLAGNIOL-VILLARD #include <video_font.h>
191352d2591SJean-Christophe PLAGNIOL-VILLARD 
192352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CMD_DATE)
193352d2591SJean-Christophe PLAGNIOL-VILLARD #include <rtc.h>
194352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
195352d2591SJean-Christophe PLAGNIOL-VILLARD 
196352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
197352d2591SJean-Christophe PLAGNIOL-VILLARD #include <watchdog.h>
198352d2591SJean-Christophe PLAGNIOL-VILLARD #include <bmp_layout.h>
1991ca298ceSMatthias Weisser 
2001ca298ceSMatthias Weisser #ifdef CONFIG_SPLASH_SCREEN_ALIGN
2011ca298ceSMatthias Weisser #define BMP_ALIGN_CENTER	0x7FFF
2021ca298ceSMatthias Weisser #endif
2031ca298ceSMatthias Weisser 
204352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
205352d2591SJean-Christophe PLAGNIOL-VILLARD 
206352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
207352d2591SJean-Christophe PLAGNIOL-VILLARD /* Cursor definition:							     */
2087817cb20SMarcel Ziswiler /* CONFIG_CONSOLE_CURSOR:  Uses a timer function (see drivers/input/i8042.c) */
2097817cb20SMarcel Ziswiler /*                         to let the cursor blink. Uses the macros	     */
2107817cb20SMarcel Ziswiler /*                         CURSOR_OFF and CURSOR_ON.			     */
211352d2591SJean-Christophe PLAGNIOL-VILLARD /* CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No	     */
212352d2591SJean-Christophe PLAGNIOL-VILLARD /*			   blinking is provided. Uses the macros CURSOR_SET  */
213352d2591SJean-Christophe PLAGNIOL-VILLARD /*			   and CURSOR_OFF.				     */
214352d2591SJean-Christophe PLAGNIOL-VILLARD /* CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the	     */
215352d2591SJean-Christophe PLAGNIOL-VILLARD /*			   graphic chip. Uses the macro CURSOR_SET.	     */
216352d2591SJean-Christophe PLAGNIOL-VILLARD /*			   ATTENTION: If booting an OS, the display driver   */
217352d2591SJean-Christophe PLAGNIOL-VILLARD /*			   must disable the hardware register of the graphic */
218352d2591SJean-Christophe PLAGNIOL-VILLARD /*			   chip. Otherwise a blinking field is displayed     */
219352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
220352d2591SJean-Christophe PLAGNIOL-VILLARD #if !defined(CONFIG_CONSOLE_CURSOR) && \
221352d2591SJean-Christophe PLAGNIOL-VILLARD     !defined(CONFIG_VIDEO_SW_CURSOR) && \
222352d2591SJean-Christophe PLAGNIOL-VILLARD     !defined(CONFIG_VIDEO_HW_CURSOR)
223352d2591SJean-Christophe PLAGNIOL-VILLARD /* no Cursor defined */
224352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_ON
225352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_OFF
226352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_SET
227352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
228352d2591SJean-Christophe PLAGNIOL-VILLARD 
229352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_CONSOLE_CURSOR
230352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CURSOR_ON
231352d2591SJean-Christophe PLAGNIOL-VILLARD #error	only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
232352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
233352d2591SJean-Christophe PLAGNIOL-VILLARD void	console_cursor (int state);
23465618636STimur Tabi #define CURSOR_ON  console_cursor(1)
23565618636STimur Tabi #define CURSOR_OFF console_cursor(0)
236352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_SET
237352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_I8042_KBD
2387817cb20SMarcel Ziswiler #warning Cursor drawing on/off needs timer function s.a. drivers/input/i8042.c
239352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
240352d2591SJean-Christophe PLAGNIOL-VILLARD #else
241352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_CONSOLE_TIME
242352d2591SJean-Christophe PLAGNIOL-VILLARD #error	CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME
243352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
244352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_CONSOLE_CURSOR */
245352d2591SJean-Christophe PLAGNIOL-VILLARD 
246352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_SW_CURSOR
247352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CURSOR_ON
248352d2591SJean-Christophe PLAGNIOL-VILLARD #error	only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
249352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
250352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_ON
251352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\
25265618636STimur Tabi 				 console_row * VIDEO_FONT_HEIGHT, ' ')
25365618636STimur Tabi #define CURSOR_SET video_set_cursor()
254352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_SW_CURSOR */
255352d2591SJean-Christophe PLAGNIOL-VILLARD 
256352d2591SJean-Christophe PLAGNIOL-VILLARD 
257352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_HW_CURSOR
258352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CURSOR_ON
259352d2591SJean-Christophe PLAGNIOL-VILLARD #error	only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
260352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
261352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_ON
262352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_OFF
263352d2591SJean-Christophe PLAGNIOL-VILLARD #define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \
26465618636STimur Tabi 		  (console_row * VIDEO_FONT_HEIGHT) + video_logo_height)
265352d2591SJean-Christophe PLAGNIOL-VILLARD #endif	/* CONFIG_VIDEO_HW_CURSOR */
266352d2591SJean-Christophe PLAGNIOL-VILLARD 
267352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_LOGO
268352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_BMP_LOGO
269352d2591SJean-Christophe PLAGNIOL-VILLARD #include <bmp_logo.h>
270352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_WIDTH	BMP_LOGO_WIDTH
271352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_HEIGHT	BMP_LOGO_HEIGHT
272352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_LUT_OFFSET	BMP_LOGO_OFFSET
273352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_COLORS	BMP_LOGO_COLORS
274352d2591SJean-Christophe PLAGNIOL-VILLARD 
275352d2591SJean-Christophe PLAGNIOL-VILLARD #else	/* CONFIG_VIDEO_BMP_LOGO */
276352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_WIDTH	80
277352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_HEIGHT	80
278352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_COLORS	214
279352d2591SJean-Christophe PLAGNIOL-VILLARD #define LINUX_LOGO_LUT_OFFSET	0x20
280352d2591SJean-Christophe PLAGNIOL-VILLARD #define __initdata
281352d2591SJean-Christophe PLAGNIOL-VILLARD #include <linux_logo.h>
282352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_WIDTH	LINUX_LOGO_WIDTH
283352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_HEIGHT	LINUX_LOGO_HEIGHT
284352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_LUT_OFFSET	LINUX_LOGO_LUT_OFFSET
285352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_COLORS	LINUX_LOGO_COLORS
286352d2591SJean-Christophe PLAGNIOL-VILLARD #endif	/* CONFIG_VIDEO_BMP_LOGO */
287352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_INFO_X		(VIDEO_LOGO_WIDTH)
288352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_INFO_Y		(VIDEO_FONT_HEIGHT/2)
289352d2591SJean-Christophe PLAGNIOL-VILLARD #else	/* CONFIG_VIDEO_LOGO */
290352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_WIDTH	0
291352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LOGO_HEIGHT	0
292352d2591SJean-Christophe PLAGNIOL-VILLARD #endif	/* CONFIG_VIDEO_LOGO */
293352d2591SJean-Christophe PLAGNIOL-VILLARD 
294352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_COLS		VIDEO_VISIBLE_COLS
295352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_ROWS		VIDEO_VISIBLE_ROWS
296352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_SIZE		(VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE)
297352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_PIX_BLOCKS	(VIDEO_SIZE >> 2)
298352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_LINE_LEN		(VIDEO_COLS*VIDEO_PIXEL_SIZE)
299352d2591SJean-Christophe PLAGNIOL-VILLARD #define VIDEO_BURST_LEN		(VIDEO_COLS/8)
300352d2591SJean-Christophe PLAGNIOL-VILLARD 
301352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	CONFIG_VIDEO_LOGO
302be129aa7SMatthias Weisser #define CONSOLE_ROWS		((VIDEO_ROWS - video_logo_height) / VIDEO_FONT_HEIGHT)
303352d2591SJean-Christophe PLAGNIOL-VILLARD #else
304352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROWS		(VIDEO_ROWS / VIDEO_FONT_HEIGHT)
305352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
306352d2591SJean-Christophe PLAGNIOL-VILLARD 
307352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_COLS		(VIDEO_COLS / VIDEO_FONT_WIDTH)
308352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_SIZE	(VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN)
309352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_FIRST	(video_console_address)
310352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_SECOND	(video_console_address + CONSOLE_ROW_SIZE)
311352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_ROW_LAST	(video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
312352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_SIZE		(CONSOLE_ROW_SIZE * CONSOLE_ROWS)
313352d2591SJean-Christophe PLAGNIOL-VILLARD #define CONSOLE_SCROLL_SIZE	(CONSOLE_SIZE - CONSOLE_ROW_SIZE)
314352d2591SJean-Christophe PLAGNIOL-VILLARD 
315352d2591SJean-Christophe PLAGNIOL-VILLARD /* Macros */
316352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef	VIDEO_FB_LITTLE_ENDIAN
317352d2591SJean-Christophe PLAGNIOL-VILLARD #define SWAP16(x)	 ((((x) & 0x00ff) << 8) | ( (x) >> 8))
318352d2591SJean-Christophe PLAGNIOL-VILLARD #define SWAP32(x)	 ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
319352d2591SJean-Christophe PLAGNIOL-VILLARD 			  (((x) & 0x00ff0000) >>  8) | (((x) & 0xff000000) >> 24) )
320352d2591SJean-Christophe PLAGNIOL-VILLARD #define SHORTSWAP32(x)	 ((((x) & 0x000000ff) <<  8) | (((x) & 0x0000ff00) >> 8)|\
321352d2591SJean-Christophe PLAGNIOL-VILLARD 			  (((x) & 0x00ff0000) <<  8) | (((x) & 0xff000000) >> 8) )
322352d2591SJean-Christophe PLAGNIOL-VILLARD #else
323352d2591SJean-Christophe PLAGNIOL-VILLARD #define SWAP16(x)	 (x)
324352d2591SJean-Christophe PLAGNIOL-VILLARD #define SWAP32(x)	 (x)
325229b6dceSWolfgang Grandegger #if defined(VIDEO_FB_16BPP_WORD_SWAP)
326bed53753SAnatolij Gustschin #define SHORTSWAP32(x)	 ( ((x) >> 16) | ((x) << 16) )
327cc347801SAndrew Dyer #else
328cc347801SAndrew Dyer #define SHORTSWAP32(x)	 (x)
329bed53753SAnatolij Gustschin #endif
330352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
331352d2591SJean-Christophe PLAGNIOL-VILLARD 
332352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
333352d2591SJean-Christophe PLAGNIOL-VILLARD #define PRINTD(x)	  printf(x)
334352d2591SJean-Christophe PLAGNIOL-VILLARD #else
335352d2591SJean-Christophe PLAGNIOL-VILLARD #define PRINTD(x)
336352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
337352d2591SJean-Christophe PLAGNIOL-VILLARD 
338352d2591SJean-Christophe PLAGNIOL-VILLARD 
339352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_EXTRA_INFO
340352d2591SJean-Christophe PLAGNIOL-VILLARD extern void video_get_info_str (    /* setup a board string: type, speed, etc. */
341352d2591SJean-Christophe PLAGNIOL-VILLARD     int line_number,	    /* location to place info string beside logo */
342352d2591SJean-Christophe PLAGNIOL-VILLARD     char *info		    /* buffer for info string */
343352d2591SJean-Christophe PLAGNIOL-VILLARD     );
344352d2591SJean-Christophe PLAGNIOL-VILLARD 
345352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
346352d2591SJean-Christophe PLAGNIOL-VILLARD 
347352d2591SJean-Christophe PLAGNIOL-VILLARD /* Locals */
348352d2591SJean-Christophe PLAGNIOL-VILLARD static GraphicDevice *pGD;	/* Pointer to Graphic array */
349352d2591SJean-Christophe PLAGNIOL-VILLARD 
350352d2591SJean-Christophe PLAGNIOL-VILLARD static void *video_fb_address;		/* frame buffer address */
351352d2591SJean-Christophe PLAGNIOL-VILLARD static void *video_console_address;	/* console buffer start address */
352352d2591SJean-Christophe PLAGNIOL-VILLARD 
353be129aa7SMatthias Weisser static int video_logo_height = VIDEO_LOGO_HEIGHT;
354be129aa7SMatthias Weisser 
355352d2591SJean-Christophe PLAGNIOL-VILLARD static int console_col = 0; /* cursor col */
356352d2591SJean-Christophe PLAGNIOL-VILLARD static int console_row = 0; /* cursor row */
357352d2591SJean-Christophe PLAGNIOL-VILLARD 
358352d2591SJean-Christophe PLAGNIOL-VILLARD static u32 eorx, fgx, bgx;  /* color pats */
359352d2591SJean-Christophe PLAGNIOL-VILLARD 
360352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table8[] = {
361352d2591SJean-Christophe PLAGNIOL-VILLARD 	    0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
362352d2591SJean-Christophe PLAGNIOL-VILLARD 	    0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
363352d2591SJean-Christophe PLAGNIOL-VILLARD 	    0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
364352d2591SJean-Christophe PLAGNIOL-VILLARD 	    0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff };
365352d2591SJean-Christophe PLAGNIOL-VILLARD 
366352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table15[] = {
367352d2591SJean-Christophe PLAGNIOL-VILLARD 	    0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff };
368352d2591SJean-Christophe PLAGNIOL-VILLARD 
369352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table16[] = {
370352d2591SJean-Christophe PLAGNIOL-VILLARD 	    0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff };
371352d2591SJean-Christophe PLAGNIOL-VILLARD 
372352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table24[16][3] = {
373352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x00000000, 0x00000000 },
374352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x00000000, 0x00ffffff },
375352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x0000ffff, 0xff000000 },
376352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x0000ffff, 0xffffffff },
377352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x000000ff, 0xffff0000, 0x00000000 },
378352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x000000ff, 0xffff0000, 0x00ffffff },
379352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x000000ff, 0xffffffff, 0xff000000 },
380352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x000000ff, 0xffffffff, 0xffffffff },
381352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0xffffff00, 0x00000000, 0x00000000 },
382352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0xffffff00, 0x00000000, 0x00ffffff },
383352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0xffffff00, 0x0000ffff, 0xff000000 },
384352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0xffffff00, 0x0000ffff, 0xffffffff },
385352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0xffffffff, 0xffff0000, 0x00000000 },
386352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0xffffffff, 0xffff0000, 0x00ffffff },
387352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0xffffffff, 0xffffffff, 0xff000000 },
388352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0xffffffff, 0xffffffff, 0xffffffff } };
389352d2591SJean-Christophe PLAGNIOL-VILLARD 
390352d2591SJean-Christophe PLAGNIOL-VILLARD static const int video_font_draw_table32[16][4] = {
391352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
392352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
393352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
394352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
395352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
396352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
397352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
398352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
399352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
400352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
401352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
402352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
403352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
404352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
405352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
406352d2591SJean-Christophe PLAGNIOL-VILLARD 	    { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } };
407352d2591SJean-Christophe PLAGNIOL-VILLARD 
408352d2591SJean-Christophe PLAGNIOL-VILLARD 
409352d2591SJean-Christophe PLAGNIOL-VILLARD /******************************************************************************/
410352d2591SJean-Christophe PLAGNIOL-VILLARD 
411352d2591SJean-Christophe PLAGNIOL-VILLARD static void video_drawchars (int xx, int yy, unsigned char *s, int count)
412352d2591SJean-Christophe PLAGNIOL-VILLARD {
413352d2591SJean-Christophe PLAGNIOL-VILLARD 	u8 *cdat, *dest, *dest0;
414352d2591SJean-Christophe PLAGNIOL-VILLARD 	int rows, offset, c;
415352d2591SJean-Christophe PLAGNIOL-VILLARD 
416352d2591SJean-Christophe PLAGNIOL-VILLARD 	offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE;
417352d2591SJean-Christophe PLAGNIOL-VILLARD 	dest0 = video_fb_address + offset;
418352d2591SJean-Christophe PLAGNIOL-VILLARD 
419352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (VIDEO_DATA_FORMAT) {
420352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_INDEX:
421352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_332RGB:
422352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
423352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
424352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
425352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
426352d2591SJean-Christophe PLAGNIOL-VILLARD 			     rows--;
427352d2591SJean-Christophe PLAGNIOL-VILLARD 			     dest += VIDEO_LINE_LEN) {
428352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
429352d2591SJean-Christophe PLAGNIOL-VILLARD 
430352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[0] = (video_font_draw_table8[bits >> 4] & eorx) ^ bgx;
431352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[1] = (video_font_draw_table8[bits & 15] & eorx) ^ bgx;
432352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
433352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
434352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
435352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
436352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
437352d2591SJean-Christophe PLAGNIOL-VILLARD 
438352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_15BIT_555RGB:
439352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
440352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
441352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
442352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
443352d2591SJean-Christophe PLAGNIOL-VILLARD 			     rows--;
444352d2591SJean-Christophe PLAGNIOL-VILLARD 			     dest += VIDEO_LINE_LEN) {
445352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
446352d2591SJean-Christophe PLAGNIOL-VILLARD 
447352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 6] & eorx) ^ bgx);
448352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 4 & 3] & eorx) ^ bgx);
449352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 2 & 3] & eorx) ^ bgx);
450352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table15 [bits & 3] & eorx) ^ bgx);
451352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
452352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
453352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
454352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
455352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
456352d2591SJean-Christophe PLAGNIOL-VILLARD 
457352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_16BIT_565RGB:
458352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
459352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
460352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
461352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
462352d2591SJean-Christophe PLAGNIOL-VILLARD 			     rows--;
463352d2591SJean-Christophe PLAGNIOL-VILLARD 			     dest += VIDEO_LINE_LEN) {
464352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
465352d2591SJean-Christophe PLAGNIOL-VILLARD 
466352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 6] & eorx) ^ bgx);
467352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 4 & 3] & eorx) ^ bgx);
468352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 2 & 3] & eorx) ^ bgx);
469352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table16 [bits & 3] & eorx) ^ bgx);
470352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
471352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
472352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
473352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
474352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
475352d2591SJean-Christophe PLAGNIOL-VILLARD 
476352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_32BIT_X888RGB:
477352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
478352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
479352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
480352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
481352d2591SJean-Christophe PLAGNIOL-VILLARD 			     rows--;
482352d2591SJean-Christophe PLAGNIOL-VILLARD 			     dest += VIDEO_LINE_LEN) {
483352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
484352d2591SJean-Christophe PLAGNIOL-VILLARD 
485352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[0] = SWAP32 ((video_font_draw_table32 [bits >> 4][0] & eorx) ^ bgx);
486352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[1] = SWAP32 ((video_font_draw_table32 [bits >> 4][1] & eorx) ^ bgx);
487352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[2] = SWAP32 ((video_font_draw_table32 [bits >> 4][2] & eorx) ^ bgx);
488352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[3] = SWAP32 ((video_font_draw_table32 [bits >> 4][3] & eorx) ^ bgx);
489352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[4] = SWAP32 ((video_font_draw_table32 [bits & 15][0] & eorx) ^ bgx);
490352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[5] = SWAP32 ((video_font_draw_table32 [bits & 15][1] & eorx) ^ bgx);
491352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[6] = SWAP32 ((video_font_draw_table32 [bits & 15][2] & eorx) ^ bgx);
492352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[7] = SWAP32 ((video_font_draw_table32 [bits & 15][3] & eorx) ^ bgx);
493352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
494352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
495352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
496352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
497352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
498352d2591SJean-Christophe PLAGNIOL-VILLARD 
499352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_24BIT_888RGB:
500352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (count--) {
501352d2591SJean-Christophe PLAGNIOL-VILLARD 			c = *s;
502352d2591SJean-Christophe PLAGNIOL-VILLARD 			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
503352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
504352d2591SJean-Christophe PLAGNIOL-VILLARD 			     rows--;
505352d2591SJean-Christophe PLAGNIOL-VILLARD 			     dest += VIDEO_LINE_LEN) {
506352d2591SJean-Christophe PLAGNIOL-VILLARD 				u8 bits = *cdat++;
507352d2591SJean-Christophe PLAGNIOL-VILLARD 
508352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[0] = (video_font_draw_table24[bits >> 4][0] & eorx) ^ bgx;
509352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[1] = (video_font_draw_table24[bits >> 4][1] & eorx) ^ bgx;
510352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[2] = (video_font_draw_table24[bits >> 4][2] & eorx) ^ bgx;
511352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[3] = (video_font_draw_table24[bits & 15][0] & eorx) ^ bgx;
512352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[4] = (video_font_draw_table24[bits & 15][1] & eorx) ^ bgx;
513352d2591SJean-Christophe PLAGNIOL-VILLARD 				((u32 *) dest)[5] = (video_font_draw_table24[bits & 15][2] & eorx) ^ bgx;
514352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
515352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
516352d2591SJean-Christophe PLAGNIOL-VILLARD 			s++;
517352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
518352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
519352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
520352d2591SJean-Christophe PLAGNIOL-VILLARD }
521352d2591SJean-Christophe PLAGNIOL-VILLARD 
522352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
523352d2591SJean-Christophe PLAGNIOL-VILLARD 
524352d2591SJean-Christophe PLAGNIOL-VILLARD static inline void video_drawstring (int xx, int yy, unsigned char *s)
525352d2591SJean-Christophe PLAGNIOL-VILLARD {
526352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_drawchars (xx, yy, s, strlen ((char *)s));
527352d2591SJean-Christophe PLAGNIOL-VILLARD }
528352d2591SJean-Christophe PLAGNIOL-VILLARD 
529352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
530352d2591SJean-Christophe PLAGNIOL-VILLARD 
531352d2591SJean-Christophe PLAGNIOL-VILLARD static void video_putchar (int xx, int yy, unsigned char c)
532352d2591SJean-Christophe PLAGNIOL-VILLARD {
533be129aa7SMatthias Weisser 	video_drawchars (xx, yy + video_logo_height, &c, 1);
534352d2591SJean-Christophe PLAGNIOL-VILLARD }
535352d2591SJean-Christophe PLAGNIOL-VILLARD 
536352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
537352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
538352d2591SJean-Christophe PLAGNIOL-VILLARD static void video_set_cursor (void)
539352d2591SJean-Christophe PLAGNIOL-VILLARD {
540352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* swap drawing colors */
541352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx;
542352d2591SJean-Christophe PLAGNIOL-VILLARD 	fgx = bgx;
543352d2591SJean-Christophe PLAGNIOL-VILLARD 	bgx = eorx;
544352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx ^ bgx;
545352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* draw cursor */
546352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_putchar (console_col * VIDEO_FONT_WIDTH,
547352d2591SJean-Christophe PLAGNIOL-VILLARD 		       console_row * VIDEO_FONT_HEIGHT,
548352d2591SJean-Christophe PLAGNIOL-VILLARD 		       ' ');
549352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* restore drawing colors */
550352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx;
551352d2591SJean-Christophe PLAGNIOL-VILLARD 	fgx = bgx;
552352d2591SJean-Christophe PLAGNIOL-VILLARD 	bgx = eorx;
553352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx ^ bgx;
554352d2591SJean-Christophe PLAGNIOL-VILLARD }
555352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
556352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
557352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_CURSOR
558352d2591SJean-Christophe PLAGNIOL-VILLARD void console_cursor (int state)
559352d2591SJean-Christophe PLAGNIOL-VILLARD {
560352d2591SJean-Christophe PLAGNIOL-VILLARD 	static int last_state = 0;
561352d2591SJean-Christophe PLAGNIOL-VILLARD 
562352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_TIME
563352d2591SJean-Christophe PLAGNIOL-VILLARD 	struct rtc_time tm;
564352d2591SJean-Christophe PLAGNIOL-VILLARD 	char info[16];
565352d2591SJean-Christophe PLAGNIOL-VILLARD 
566352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* time update only if cursor is on (faster scroll) */
567352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (state) {
568352d2591SJean-Christophe PLAGNIOL-VILLARD 		rtc_get (&tm);
569352d2591SJean-Christophe PLAGNIOL-VILLARD 
570352d2591SJean-Christophe PLAGNIOL-VILLARD 		sprintf (info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min,
571352d2591SJean-Christophe PLAGNIOL-VILLARD 			 tm.tm_sec);
572352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
573352d2591SJean-Christophe PLAGNIOL-VILLARD 				  VIDEO_INFO_Y, (uchar *)info);
574352d2591SJean-Christophe PLAGNIOL-VILLARD 
575352d2591SJean-Christophe PLAGNIOL-VILLARD 		sprintf (info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon,
576352d2591SJean-Christophe PLAGNIOL-VILLARD 			 tm.tm_year);
577352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
578352d2591SJean-Christophe PLAGNIOL-VILLARD 				  VIDEO_INFO_Y + 1 * VIDEO_FONT_HEIGHT, (uchar *)info);
579352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
580352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
581352d2591SJean-Christophe PLAGNIOL-VILLARD 
582352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (state && (last_state != state)) {
583352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_set_cursor ();
584352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
585352d2591SJean-Christophe PLAGNIOL-VILLARD 
586352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (!state && (last_state != state)) {
587352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* clear cursor */
588352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_putchar (console_col * VIDEO_FONT_WIDTH,
589352d2591SJean-Christophe PLAGNIOL-VILLARD 			       console_row * VIDEO_FONT_HEIGHT,
590352d2591SJean-Christophe PLAGNIOL-VILLARD 			       ' ');
591352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
592352d2591SJean-Christophe PLAGNIOL-VILLARD 
593352d2591SJean-Christophe PLAGNIOL-VILLARD 	last_state = state;
594352d2591SJean-Christophe PLAGNIOL-VILLARD }
595352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
596352d2591SJean-Christophe PLAGNIOL-VILLARD 
597352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
598352d2591SJean-Christophe PLAGNIOL-VILLARD 
599352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef VIDEO_HW_RECTFILL
600352d2591SJean-Christophe PLAGNIOL-VILLARD static void memsetl (int *p, int c, int v)
601352d2591SJean-Christophe PLAGNIOL-VILLARD {
602352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (c--)
603352d2591SJean-Christophe PLAGNIOL-VILLARD 		*(p++) = v;
604352d2591SJean-Christophe PLAGNIOL-VILLARD }
605352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
606352d2591SJean-Christophe PLAGNIOL-VILLARD 
607352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
608352d2591SJean-Christophe PLAGNIOL-VILLARD 
609352d2591SJean-Christophe PLAGNIOL-VILLARD #ifndef VIDEO_HW_BITBLT
610352d2591SJean-Christophe PLAGNIOL-VILLARD static void memcpyl (int *d, int *s, int c)
611352d2591SJean-Christophe PLAGNIOL-VILLARD {
612352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (c--)
613352d2591SJean-Christophe PLAGNIOL-VILLARD 		*(d++) = *(s++);
614352d2591SJean-Christophe PLAGNIOL-VILLARD }
615352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
616352d2591SJean-Christophe PLAGNIOL-VILLARD 
617352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
618352d2591SJean-Christophe PLAGNIOL-VILLARD 
619352d2591SJean-Christophe PLAGNIOL-VILLARD static void console_scrollup (void)
620352d2591SJean-Christophe PLAGNIOL-VILLARD {
621352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* copy up rows ignoring the first one */
622352d2591SJean-Christophe PLAGNIOL-VILLARD 
623352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_HW_BITBLT
624352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_hw_bitblt (VIDEO_PIXEL_SIZE,	/* bytes per pixel */
625352d2591SJean-Christophe PLAGNIOL-VILLARD 			 0,	/* source pos x */
626be129aa7SMatthias Weisser 			 video_logo_height + VIDEO_FONT_HEIGHT, /* source pos y */
627352d2591SJean-Christophe PLAGNIOL-VILLARD 			 0,	/* dest pos x */
628be129aa7SMatthias Weisser 			 video_logo_height,	/* dest pos y */
629352d2591SJean-Christophe PLAGNIOL-VILLARD 			 VIDEO_VISIBLE_COLS,	/* frame width */
630be129aa7SMatthias Weisser 			 VIDEO_VISIBLE_ROWS - video_logo_height - VIDEO_FONT_HEIGHT	/* frame height */
631352d2591SJean-Christophe PLAGNIOL-VILLARD 		);
632352d2591SJean-Christophe PLAGNIOL-VILLARD #else
633352d2591SJean-Christophe PLAGNIOL-VILLARD 	memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND,
634352d2591SJean-Christophe PLAGNIOL-VILLARD 		 CONSOLE_SCROLL_SIZE >> 2);
635352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
636352d2591SJean-Christophe PLAGNIOL-VILLARD 
637352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* clear the last one */
638352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_HW_RECTFILL
639352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_hw_rectfill (VIDEO_PIXEL_SIZE,	/* bytes per pixel */
640352d2591SJean-Christophe PLAGNIOL-VILLARD 			   0,	/* dest pos x */
641352d2591SJean-Christophe PLAGNIOL-VILLARD 			   VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT,	/* dest pos y */
642352d2591SJean-Christophe PLAGNIOL-VILLARD 			   VIDEO_VISIBLE_COLS,	/* frame width */
643352d2591SJean-Christophe PLAGNIOL-VILLARD 			   VIDEO_FONT_HEIGHT,	/* frame height */
644352d2591SJean-Christophe PLAGNIOL-VILLARD 			   CONSOLE_BG_COL	/* fill color */
645352d2591SJean-Christophe PLAGNIOL-VILLARD 		);
646352d2591SJean-Christophe PLAGNIOL-VILLARD #else
647352d2591SJean-Christophe PLAGNIOL-VILLARD 	memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
648352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
649352d2591SJean-Christophe PLAGNIOL-VILLARD }
650352d2591SJean-Christophe PLAGNIOL-VILLARD 
651352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
652352d2591SJean-Christophe PLAGNIOL-VILLARD 
653352d2591SJean-Christophe PLAGNIOL-VILLARD static void console_back (void)
654352d2591SJean-Christophe PLAGNIOL-VILLARD {
65565618636STimur Tabi 	CURSOR_OFF;
65665618636STimur Tabi 	console_col--;
657352d2591SJean-Christophe PLAGNIOL-VILLARD 
658352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (console_col < 0) {
659352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_col = CONSOLE_COLS - 1;
660352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_row--;
661352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (console_row < 0)
662352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_row = 0;
663352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
664352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_putchar (console_col * VIDEO_FONT_WIDTH,
665352d2591SJean-Christophe PLAGNIOL-VILLARD 		       console_row * VIDEO_FONT_HEIGHT,
666352d2591SJean-Christophe PLAGNIOL-VILLARD 		       ' ');
667352d2591SJean-Christophe PLAGNIOL-VILLARD }
668352d2591SJean-Christophe PLAGNIOL-VILLARD 
669352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
670352d2591SJean-Christophe PLAGNIOL-VILLARD 
671352d2591SJean-Christophe PLAGNIOL-VILLARD static void console_newline (void)
672352d2591SJean-Christophe PLAGNIOL-VILLARD {
67320c450efSAnatolij Gustschin 	/* Check if last character in the line was just drawn. If so, cursor was
67420c450efSAnatolij Gustschin 	   overwriten and need not to be cleared. Cursor clearing without this
67520c450efSAnatolij Gustschin 	   check causes overwriting the 1st character of the line if line lenght
67620c450efSAnatolij Gustschin 	   is >= CONSOLE_COLS
67720c450efSAnatolij Gustschin 	 */
67820c450efSAnatolij Gustschin 	if (console_col < CONSOLE_COLS)
67965618636STimur Tabi 		CURSOR_OFF;
68020c450efSAnatolij Gustschin 	console_row++;
681352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_col = 0;
682352d2591SJean-Christophe PLAGNIOL-VILLARD 
683352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Check if we need to scroll the terminal */
684352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (console_row >= CONSOLE_ROWS) {
685352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* Scroll everything up */
686352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_scrollup ();
687352d2591SJean-Christophe PLAGNIOL-VILLARD 
688352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* Decrement row number */
689352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_row--;
690352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
691352d2591SJean-Christophe PLAGNIOL-VILLARD }
692352d2591SJean-Christophe PLAGNIOL-VILLARD 
69320c450efSAnatolij Gustschin static void console_cr (void)
69420c450efSAnatolij Gustschin {
69565618636STimur Tabi 	CURSOR_OFF;
69665618636STimur Tabi 	console_col = 0;
69720c450efSAnatolij Gustschin }
69820c450efSAnatolij Gustschin 
699352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
700352d2591SJean-Christophe PLAGNIOL-VILLARD 
701352d2591SJean-Christophe PLAGNIOL-VILLARD void video_putc (const char c)
702352d2591SJean-Christophe PLAGNIOL-VILLARD {
70320c450efSAnatolij Gustschin 	static int nl = 1;
70420c450efSAnatolij Gustschin 
705352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (c) {
70620c450efSAnatolij Gustschin 	case 13:		/* back to first column */
70720c450efSAnatolij Gustschin 		console_cr ();
708352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
709352d2591SJean-Christophe PLAGNIOL-VILLARD 
710352d2591SJean-Christophe PLAGNIOL-VILLARD 	case '\n':		/* next line */
71120c450efSAnatolij Gustschin 		if (console_col || (!console_col && nl))
712352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_newline ();
71320c450efSAnatolij Gustschin 		nl = 1;
714352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
715352d2591SJean-Christophe PLAGNIOL-VILLARD 
716352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 9:		/* tab 8 */
71765618636STimur Tabi 		CURSOR_OFF;
71865618636STimur Tabi 		console_col |= 0x0008;
719352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_col &= ~0x0007;
720352d2591SJean-Christophe PLAGNIOL-VILLARD 
721352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (console_col >= CONSOLE_COLS)
722352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_newline ();
723352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
724352d2591SJean-Christophe PLAGNIOL-VILLARD 
725352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 8:		/* backspace */
726352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_back ();
727352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
728352d2591SJean-Christophe PLAGNIOL-VILLARD 
729352d2591SJean-Christophe PLAGNIOL-VILLARD 	default:		/* draw the char */
730352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_putchar (console_col * VIDEO_FONT_WIDTH,
731352d2591SJean-Christophe PLAGNIOL-VILLARD 			       console_row * VIDEO_FONT_HEIGHT,
732352d2591SJean-Christophe PLAGNIOL-VILLARD 			       c);
733352d2591SJean-Christophe PLAGNIOL-VILLARD 		console_col++;
734352d2591SJean-Christophe PLAGNIOL-VILLARD 
735352d2591SJean-Christophe PLAGNIOL-VILLARD 		/* check for newline */
73620c450efSAnatolij Gustschin 		if (console_col >= CONSOLE_COLS) {
737352d2591SJean-Christophe PLAGNIOL-VILLARD 			console_newline ();
73820c450efSAnatolij Gustschin 			nl = 0;
73920c450efSAnatolij Gustschin 		}
740352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
74165618636STimur Tabi 	CURSOR_SET;
74265618636STimur Tabi }
743352d2591SJean-Christophe PLAGNIOL-VILLARD 
744352d2591SJean-Christophe PLAGNIOL-VILLARD 
745352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
746352d2591SJean-Christophe PLAGNIOL-VILLARD 
747352d2591SJean-Christophe PLAGNIOL-VILLARD void video_puts (const char *s)
748352d2591SJean-Christophe PLAGNIOL-VILLARD {
749352d2591SJean-Christophe PLAGNIOL-VILLARD 	int count = strlen (s);
750352d2591SJean-Christophe PLAGNIOL-VILLARD 
751352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (count--)
752352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_putc (*s++);
753352d2591SJean-Christophe PLAGNIOL-VILLARD }
754352d2591SJean-Christophe PLAGNIOL-VILLARD 
755352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
756352d2591SJean-Christophe PLAGNIOL-VILLARD 
75710543820SAnatolij Gustschin /*
75810543820SAnatolij Gustschin  * Do not enforce drivers (or board code) to provide empty
75910543820SAnatolij Gustschin  * video_set_lut() if they do not support 8 bpp format.
76010543820SAnatolij Gustschin  * Implement weak default function instead.
76110543820SAnatolij Gustschin  */
76210543820SAnatolij Gustschin void __video_set_lut (unsigned int index, unsigned char r,
76310543820SAnatolij Gustschin 		      unsigned char g, unsigned char b)
76410543820SAnatolij Gustschin {
76510543820SAnatolij Gustschin }
76610543820SAnatolij Gustschin void video_set_lut (unsigned int, unsigned char, unsigned char, unsigned char)
76710543820SAnatolij Gustschin 			__attribute__((weak, alias("__video_set_lut")));
76810543820SAnatolij Gustschin 
769352d2591SJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
770352d2591SJean-Christophe PLAGNIOL-VILLARD 
771352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_8BIT_332RGB(r,g,b)	{			\
772352d2591SJean-Christophe PLAGNIOL-VILLARD 	*fb = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6);	\
773352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb ++;						\
774352d2591SJean-Christophe PLAGNIOL-VILLARD }
775352d2591SJean-Christophe PLAGNIOL-VILLARD 
776352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_15BIT_555RGB(r,g,b) {			\
777352d2591SJean-Christophe PLAGNIOL-VILLARD 	*(unsigned short *)fb = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \
778352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 2;					\
779352d2591SJean-Christophe PLAGNIOL-VILLARD }
780352d2591SJean-Christophe PLAGNIOL-VILLARD 
781352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_16BIT_565RGB(r,g,b) {			\
782352d2591SJean-Christophe PLAGNIOL-VILLARD 	*(unsigned short *)fb = SWAP16((unsigned short)((((r)>>3)<<11) | (((g)>>2)<<5) | ((b)>>3))); \
783352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 2;					\
784352d2591SJean-Christophe PLAGNIOL-VILLARD }
785352d2591SJean-Christophe PLAGNIOL-VILLARD 
786352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_32BIT_X888RGB(r,g,b) {			\
787352d2591SJean-Christophe PLAGNIOL-VILLARD 	*(unsigned long *)fb = SWAP32((unsigned long)(((r<<16) | (g<<8) | b))); \
788352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 4;					\
789352d2591SJean-Christophe PLAGNIOL-VILLARD }
790352d2591SJean-Christophe PLAGNIOL-VILLARD 
791352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_FB_LITTLE_ENDIAN
792352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_24BIT_888RGB(r,g,b) {			\
793352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[0] = b;					\
794352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[1] = g;					\
795352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[2] = r;					\
796352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 3;					\
797352d2591SJean-Christophe PLAGNIOL-VILLARD }
798352d2591SJean-Christophe PLAGNIOL-VILLARD #else
799352d2591SJean-Christophe PLAGNIOL-VILLARD #define FILL_24BIT_888RGB(r,g,b) {			\
800352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[0] = r;					\
801352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[1] = g;					\
802352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb[2] = b;					\
803352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb += 3;					\
804352d2591SJean-Christophe PLAGNIOL-VILLARD }
805352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
806352d2591SJean-Christophe PLAGNIOL-VILLARD 
807e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
808e84d568fSAnatolij Gustschin static void inline fill_555rgb_pswap(uchar *fb, int x,
809e84d568fSAnatolij Gustschin 				     u8 r, u8 g, u8 b)
810e84d568fSAnatolij Gustschin {
811e84d568fSAnatolij Gustschin 	ushort *dst = (ushort *)fb;
812e84d568fSAnatolij Gustschin 	ushort color = (ushort)(((r >> 3) << 10) |
813e84d568fSAnatolij Gustschin 				((g >> 3) << 5) |
814e84d568fSAnatolij Gustschin 				(b >> 3));
815e84d568fSAnatolij Gustschin 	if (x & 1)
816e84d568fSAnatolij Gustschin 		*(--dst) = color;
817e84d568fSAnatolij Gustschin 	else
818e84d568fSAnatolij Gustschin 		*(++dst) = color;
819e84d568fSAnatolij Gustschin }
820e84d568fSAnatolij Gustschin #endif
821352d2591SJean-Christophe PLAGNIOL-VILLARD 
822352d2591SJean-Christophe PLAGNIOL-VILLARD /*
823d5011762SAnatolij Gustschin  * RLE8 bitmap support
824d5011762SAnatolij Gustschin  */
825d5011762SAnatolij Gustschin 
826d5011762SAnatolij Gustschin #ifdef CONFIG_VIDEO_BMP_RLE8
827d5011762SAnatolij Gustschin /* Pre-calculated color table entry */
828d5011762SAnatolij Gustschin struct palette {
829d5011762SAnatolij Gustschin 	union {
830d5011762SAnatolij Gustschin 		unsigned short	w;	/* word */
831d5011762SAnatolij Gustschin 		unsigned int	dw;	/* double word */
832d5011762SAnatolij Gustschin 	} ce; /* color entry */
833d5011762SAnatolij Gustschin };
834d5011762SAnatolij Gustschin 
835d5011762SAnatolij Gustschin /*
836d5011762SAnatolij Gustschin  * Helper to draw encoded/unencoded run.
837d5011762SAnatolij Gustschin  */
838d5011762SAnatolij Gustschin static void draw_bitmap (uchar **fb, uchar *bm, struct palette *p,
839d5011762SAnatolij Gustschin 			 int cnt, int enc)
840d5011762SAnatolij Gustschin {
841d5011762SAnatolij Gustschin 	ulong addr = (ulong)*fb;
842d5011762SAnatolij Gustschin 	int *off;
843d5011762SAnatolij Gustschin 	int enc_off = 1;
844d5011762SAnatolij Gustschin 	int i;
845d5011762SAnatolij Gustschin 
846d5011762SAnatolij Gustschin 	/*
847d5011762SAnatolij Gustschin 	 * Setup offset of the color index in the bitmap.
848d5011762SAnatolij Gustschin 	 * Color index of encoded run is at offset 1.
849d5011762SAnatolij Gustschin 	 */
850d5011762SAnatolij Gustschin 	off = enc ? &enc_off : &i;
851d5011762SAnatolij Gustschin 
852d5011762SAnatolij Gustschin 	switch (VIDEO_DATA_FORMAT) {
853d5011762SAnatolij Gustschin 	case GDF__8BIT_INDEX:
854d5011762SAnatolij Gustschin 		for (i = 0; i < cnt; i++)
855d5011762SAnatolij Gustschin 			*(unsigned char *)addr++ = bm[*off];
856d5011762SAnatolij Gustschin 		break;
857d5011762SAnatolij Gustschin 	case GDF_15BIT_555RGB:
858d5011762SAnatolij Gustschin 	case GDF_16BIT_565RGB:
859d5011762SAnatolij Gustschin 		/* differences handled while pre-calculating palette */
860d5011762SAnatolij Gustschin 		for (i = 0; i < cnt; i++) {
861d5011762SAnatolij Gustschin 			*(unsigned short *)addr = p[bm[*off]].ce.w;
862d5011762SAnatolij Gustschin 			addr += 2;
863d5011762SAnatolij Gustschin 		}
864d5011762SAnatolij Gustschin 		break;
865d5011762SAnatolij Gustschin 	case GDF_32BIT_X888RGB:
866d5011762SAnatolij Gustschin 		for (i = 0; i < cnt; i++) {
867d5011762SAnatolij Gustschin 			*(unsigned long *)addr = p[bm[*off]].ce.dw;
868d5011762SAnatolij Gustschin 			addr += 4;
869d5011762SAnatolij Gustschin 		}
870d5011762SAnatolij Gustschin 		break;
871d5011762SAnatolij Gustschin 	}
872d5011762SAnatolij Gustschin 	*fb = (uchar *)addr; /* return modified address */
873d5011762SAnatolij Gustschin }
874d5011762SAnatolij Gustschin 
875d5011762SAnatolij Gustschin static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
876d5011762SAnatolij Gustschin 				int width, int height)
877d5011762SAnatolij Gustschin {
878d5011762SAnatolij Gustschin 	unsigned char *bm;
879d5011762SAnatolij Gustschin 	unsigned char *fbp;
880d5011762SAnatolij Gustschin 	unsigned int cnt, runlen;
881d5011762SAnatolij Gustschin 	int decode = 1;
882d5011762SAnatolij Gustschin 	int x, y, bpp, i, ncolors;
883d5011762SAnatolij Gustschin 	struct palette p[256];
884d5011762SAnatolij Gustschin 	bmp_color_table_entry_t cte;
885d5011762SAnatolij Gustschin 	int green_shift, red_off;
88674446b63SAnatolij Gustschin 	int limit = VIDEO_COLS * VIDEO_ROWS;
88774446b63SAnatolij Gustschin 	int pixels = 0;
888d5011762SAnatolij Gustschin 
889d5011762SAnatolij Gustschin 	x = 0;
890d5011762SAnatolij Gustschin 	y = __le32_to_cpu(img->header.height) - 1;
891d5011762SAnatolij Gustschin 	ncolors = __le32_to_cpu(img->header.colors_used);
892d5011762SAnatolij Gustschin 	bpp = VIDEO_PIXEL_SIZE;
893d5011762SAnatolij Gustschin 	fbp = (unsigned char *)((unsigned int)video_fb_address +
894d5011762SAnatolij Gustschin 				(((y + yoff) * VIDEO_COLS) + xoff) * bpp);
895d5011762SAnatolij Gustschin 
896d5011762SAnatolij Gustschin 	bm = (uchar *)img + __le32_to_cpu(img->header.data_offset);
897d5011762SAnatolij Gustschin 
898d5011762SAnatolij Gustschin 	/* pre-calculate and setup palette */
899d5011762SAnatolij Gustschin 	switch (VIDEO_DATA_FORMAT) {
900d5011762SAnatolij Gustschin 	case GDF__8BIT_INDEX:
901d5011762SAnatolij Gustschin 		for (i = 0; i < ncolors; i++) {
902d5011762SAnatolij Gustschin 			cte = img->color_table[i];
903d5011762SAnatolij Gustschin 			video_set_lut (i, cte.red, cte.green, cte.blue);
904d5011762SAnatolij Gustschin 		}
905d5011762SAnatolij Gustschin 		break;
906d5011762SAnatolij Gustschin 	case GDF_15BIT_555RGB:
907d5011762SAnatolij Gustschin 	case GDF_16BIT_565RGB:
908d5011762SAnatolij Gustschin 		if (VIDEO_DATA_FORMAT == GDF_15BIT_555RGB) {
909d5011762SAnatolij Gustschin 			green_shift = 3;
910d5011762SAnatolij Gustschin 			red_off = 10;
911d5011762SAnatolij Gustschin 		} else {
912d5011762SAnatolij Gustschin 			green_shift = 2;
913d5011762SAnatolij Gustschin 			red_off = 11;
914d5011762SAnatolij Gustschin 		}
915d5011762SAnatolij Gustschin 		for (i = 0; i < ncolors; i++) {
916d5011762SAnatolij Gustschin 			cte = img->color_table[i];
917d5011762SAnatolij Gustschin 			p[i].ce.w = SWAP16((unsigned short)
918d5011762SAnatolij Gustschin 					   (((cte.red >> 3) << red_off) |
919d5011762SAnatolij Gustschin 					    ((cte.green >> green_shift) << 5) |
920d5011762SAnatolij Gustschin 					    cte.blue >> 3));
921d5011762SAnatolij Gustschin 		}
922d5011762SAnatolij Gustschin 		break;
923d5011762SAnatolij Gustschin 	case GDF_32BIT_X888RGB:
924d5011762SAnatolij Gustschin 		for (i = 0; i < ncolors; i++) {
925d5011762SAnatolij Gustschin 			cte = img->color_table[i];
926d5011762SAnatolij Gustschin 			p[i].ce.dw = SWAP32((cte.red << 16) | (cte.green << 8) |
927d5011762SAnatolij Gustschin 					     cte.blue);
928d5011762SAnatolij Gustschin 		}
929d5011762SAnatolij Gustschin 		break;
930d5011762SAnatolij Gustschin 	default:
931d5011762SAnatolij Gustschin 		printf("RLE Bitmap unsupported in video mode 0x%x\n",
932d5011762SAnatolij Gustschin 			VIDEO_DATA_FORMAT);
933d5011762SAnatolij Gustschin 		return -1;
934d5011762SAnatolij Gustschin 	}
935d5011762SAnatolij Gustschin 
936d5011762SAnatolij Gustschin 	while (decode) {
937d5011762SAnatolij Gustschin 		switch (bm[0]) {
938d5011762SAnatolij Gustschin 		case 0:
939d5011762SAnatolij Gustschin 			switch (bm[1]) {
940d5011762SAnatolij Gustschin 			case 0:
941d5011762SAnatolij Gustschin 				/* scan line end marker */
942d5011762SAnatolij Gustschin 				bm += 2;
943d5011762SAnatolij Gustschin 				x = 0;
944d5011762SAnatolij Gustschin 				y--;
945d5011762SAnatolij Gustschin 				fbp = (unsigned char *)
946d5011762SAnatolij Gustschin 					((unsigned int)video_fb_address +
947d5011762SAnatolij Gustschin 					 (((y + yoff) * VIDEO_COLS) +
948d5011762SAnatolij Gustschin 					  xoff) * bpp);
949d5011762SAnatolij Gustschin 				continue;
950d5011762SAnatolij Gustschin 			case 1:
951d5011762SAnatolij Gustschin 				/* end of bitmap data marker */
952d5011762SAnatolij Gustschin 				decode = 0;
953d5011762SAnatolij Gustschin 				break;
954d5011762SAnatolij Gustschin 			case 2:
955d5011762SAnatolij Gustschin 				/* run offset marker */
956d5011762SAnatolij Gustschin 				x += bm[2];
957d5011762SAnatolij Gustschin 				y -= bm[3];
958d5011762SAnatolij Gustschin 				fbp = (unsigned char *)
959d5011762SAnatolij Gustschin 					((unsigned int)video_fb_address +
960d5011762SAnatolij Gustschin 					 (((y + yoff) * VIDEO_COLS) +
961d5011762SAnatolij Gustschin 					  x + xoff) * bpp);
962d5011762SAnatolij Gustschin 				bm += 4;
963d5011762SAnatolij Gustschin 				break;
964d5011762SAnatolij Gustschin 			default:
965d5011762SAnatolij Gustschin 				/* unencoded run */
966d5011762SAnatolij Gustschin 				cnt = bm[1];
967d5011762SAnatolij Gustschin 				runlen = cnt;
96874446b63SAnatolij Gustschin 				pixels += cnt;
96974446b63SAnatolij Gustschin 				if (pixels > limit)
97074446b63SAnatolij Gustschin 					goto error;
97174446b63SAnatolij Gustschin 
972d5011762SAnatolij Gustschin 				bm += 2;
973d5011762SAnatolij Gustschin 				if (y < height) {
974d5011762SAnatolij Gustschin 					if (x >= width) {
975d5011762SAnatolij Gustschin 						x += runlen;
976d5011762SAnatolij Gustschin 						goto next_run;
977d5011762SAnatolij Gustschin 					}
978d5011762SAnatolij Gustschin 					if (x + runlen > width)
979d5011762SAnatolij Gustschin 						cnt = width - x;
980d5011762SAnatolij Gustschin 					draw_bitmap (&fbp, bm, p, cnt, 0);
981d5011762SAnatolij Gustschin 					x += runlen;
982d5011762SAnatolij Gustschin 				}
983d5011762SAnatolij Gustschin next_run:
984d5011762SAnatolij Gustschin 				bm += runlen;
985d5011762SAnatolij Gustschin 				if (runlen & 1)
986d5011762SAnatolij Gustschin 					bm++; /* 0 padding if length is odd */
987d5011762SAnatolij Gustschin 			}
988d5011762SAnatolij Gustschin 			break;
989d5011762SAnatolij Gustschin 		default:
990d5011762SAnatolij Gustschin 			/* encoded run */
991d5011762SAnatolij Gustschin 			cnt = bm[0];
992d5011762SAnatolij Gustschin 			runlen = cnt;
99374446b63SAnatolij Gustschin 			pixels += cnt;
99474446b63SAnatolij Gustschin 			if (pixels > limit)
99574446b63SAnatolij Gustschin 				goto error;
99674446b63SAnatolij Gustschin 
99774446b63SAnatolij Gustschin 			if (y < height) { /* only draw into visible area */
998d5011762SAnatolij Gustschin 				if (x >= width) {
999d5011762SAnatolij Gustschin 					x += runlen;
1000d5011762SAnatolij Gustschin 					bm += 2;
1001d5011762SAnatolij Gustschin 					continue;
1002d5011762SAnatolij Gustschin 				}
1003d5011762SAnatolij Gustschin 				if (x + runlen > width)
1004d5011762SAnatolij Gustschin 					cnt = width - x;
1005d5011762SAnatolij Gustschin 				draw_bitmap (&fbp, bm, p, cnt, 1);
1006d5011762SAnatolij Gustschin 				x += runlen;
1007d5011762SAnatolij Gustschin 			}
1008d5011762SAnatolij Gustschin 			bm += 2;
1009d5011762SAnatolij Gustschin 			break;
1010d5011762SAnatolij Gustschin 		}
1011d5011762SAnatolij Gustschin 	}
1012d5011762SAnatolij Gustschin 	return 0;
101374446b63SAnatolij Gustschin error:
101474446b63SAnatolij Gustschin 	printf("Error: Too much encoded pixel data, validate your bitmap\n");
101574446b63SAnatolij Gustschin 	return -1;
1016d5011762SAnatolij Gustschin }
1017d5011762SAnatolij Gustschin #endif
1018d5011762SAnatolij Gustschin 
1019d5011762SAnatolij Gustschin /*
1020352d2591SJean-Christophe PLAGNIOL-VILLARD  * Display the BMP file located at address bmp_image.
1021352d2591SJean-Christophe PLAGNIOL-VILLARD  */
1022352d2591SJean-Christophe PLAGNIOL-VILLARD int video_display_bitmap (ulong bmp_image, int x, int y)
1023352d2591SJean-Christophe PLAGNIOL-VILLARD {
1024352d2591SJean-Christophe PLAGNIOL-VILLARD 	ushort xcount, ycount;
1025352d2591SJean-Christophe PLAGNIOL-VILLARD 	uchar *fb;
1026352d2591SJean-Christophe PLAGNIOL-VILLARD 	bmp_image_t *bmp = (bmp_image_t *) bmp_image;
1027352d2591SJean-Christophe PLAGNIOL-VILLARD 	uchar *bmap;
1028352d2591SJean-Christophe PLAGNIOL-VILLARD 	ushort padded_line;
1029352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned long width, height, bpp;
1030352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned colors;
1031352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned long compression;
1032352d2591SJean-Christophe PLAGNIOL-VILLARD 	bmp_color_table_entry_t cte;
1033352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_GZIP
1034352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char *dst = NULL;
1035352d2591SJean-Christophe PLAGNIOL-VILLARD 	ulong len;
1036352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1037352d2591SJean-Christophe PLAGNIOL-VILLARD 
1038352d2591SJean-Christophe PLAGNIOL-VILLARD 	WATCHDOG_RESET ();
1039352d2591SJean-Christophe PLAGNIOL-VILLARD 
1040352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (!((bmp->header.signature[0] == 'B') &&
1041352d2591SJean-Christophe PLAGNIOL-VILLARD 	      (bmp->header.signature[1] == 'M'))) {
1042352d2591SJean-Christophe PLAGNIOL-VILLARD 
1043352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_GZIP
1044352d2591SJean-Christophe PLAGNIOL-VILLARD 		/*
1045352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * Could be a gzipped bmp image, try to decrompress...
1046352d2591SJean-Christophe PLAGNIOL-VILLARD 		 */
10476d0f6bcfSJean-Christophe PLAGNIOL-VILLARD 		len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
10486d0f6bcfSJean-Christophe PLAGNIOL-VILLARD 		dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
1049352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (dst == NULL) {
1050352d2591SJean-Christophe PLAGNIOL-VILLARD 			printf("Error: malloc in gunzip failed!\n");
1051352d2591SJean-Christophe PLAGNIOL-VILLARD 			return(1);
1052352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
10536d0f6bcfSJean-Christophe PLAGNIOL-VILLARD 		if (gunzip(dst, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE, (uchar *)bmp_image, &len) != 0) {
1054352d2591SJean-Christophe PLAGNIOL-VILLARD 			printf ("Error: no valid bmp or bmp.gz image at %lx\n", bmp_image);
1055352d2591SJean-Christophe PLAGNIOL-VILLARD 			free(dst);
1056352d2591SJean-Christophe PLAGNIOL-VILLARD 			return 1;
1057352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
10586d0f6bcfSJean-Christophe PLAGNIOL-VILLARD 		if (len == CONFIG_SYS_VIDEO_LOGO_MAX_SIZE) {
10596d0f6bcfSJean-Christophe PLAGNIOL-VILLARD 			printf("Image could be truncated (increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n");
1060352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1061352d2591SJean-Christophe PLAGNIOL-VILLARD 
1062352d2591SJean-Christophe PLAGNIOL-VILLARD 		/*
1063352d2591SJean-Christophe PLAGNIOL-VILLARD 		 * Set addr to decompressed image
1064352d2591SJean-Christophe PLAGNIOL-VILLARD 		 */
1065352d2591SJean-Christophe PLAGNIOL-VILLARD 		bmp = (bmp_image_t *)dst;
1066352d2591SJean-Christophe PLAGNIOL-VILLARD 
1067352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (!((bmp->header.signature[0] == 'B') &&
1068352d2591SJean-Christophe PLAGNIOL-VILLARD 		      (bmp->header.signature[1] == 'M'))) {
1069352d2591SJean-Christophe PLAGNIOL-VILLARD 			printf ("Error: no valid bmp.gz image at %lx\n", bmp_image);
1070a49e0d17SMatthias Fuchs 			free(dst);
1071352d2591SJean-Christophe PLAGNIOL-VILLARD 			return 1;
1072352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1073352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1074352d2591SJean-Christophe PLAGNIOL-VILLARD 		printf ("Error: no valid bmp image at %lx\n", bmp_image);
1075352d2591SJean-Christophe PLAGNIOL-VILLARD 		return 1;
1076352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VIDEO_BMP_GZIP */
1077352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1078352d2591SJean-Christophe PLAGNIOL-VILLARD 
1079352d2591SJean-Christophe PLAGNIOL-VILLARD 	width = le32_to_cpu (bmp->header.width);
1080352d2591SJean-Christophe PLAGNIOL-VILLARD 	height = le32_to_cpu (bmp->header.height);
1081352d2591SJean-Christophe PLAGNIOL-VILLARD 	bpp = le16_to_cpu (bmp->header.bit_count);
1082352d2591SJean-Christophe PLAGNIOL-VILLARD 	colors = le32_to_cpu (bmp->header.colors_used);
1083352d2591SJean-Christophe PLAGNIOL-VILLARD 	compression = le32_to_cpu (bmp->header.compression);
1084352d2591SJean-Christophe PLAGNIOL-VILLARD 
1085352d2591SJean-Christophe PLAGNIOL-VILLARD 	debug ("Display-bmp: %d x %d  with %d colors\n",
1086352d2591SJean-Christophe PLAGNIOL-VILLARD 	       width, height, colors);
1087352d2591SJean-Christophe PLAGNIOL-VILLARD 
1088d5011762SAnatolij Gustschin 	if (compression != BMP_BI_RGB
1089d5011762SAnatolij Gustschin #ifdef CONFIG_VIDEO_BMP_RLE8
1090d5011762SAnatolij Gustschin 	    && compression != BMP_BI_RLE8
1091d5011762SAnatolij Gustschin #endif
1092d5011762SAnatolij Gustschin 	   ) {
1093352d2591SJean-Christophe PLAGNIOL-VILLARD 		printf ("Error: compression type %ld not supported\n",
1094352d2591SJean-Christophe PLAGNIOL-VILLARD 			compression);
1095a49e0d17SMatthias Fuchs #ifdef CONFIG_VIDEO_BMP_GZIP
1096a49e0d17SMatthias Fuchs 		if (dst)
1097a49e0d17SMatthias Fuchs 			free(dst);
1098a49e0d17SMatthias Fuchs #endif
1099352d2591SJean-Christophe PLAGNIOL-VILLARD 		return 1;
1100352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1101352d2591SJean-Christophe PLAGNIOL-VILLARD 
1102352d2591SJean-Christophe PLAGNIOL-VILLARD 	padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3;
1103352d2591SJean-Christophe PLAGNIOL-VILLARD 
11041ca298ceSMatthias Weisser #ifdef CONFIG_SPLASH_SCREEN_ALIGN
11051ca298ceSMatthias Weisser 	if (x == BMP_ALIGN_CENTER)
11061ca298ceSMatthias Weisser 		x = max(0, (VIDEO_VISIBLE_COLS - width) / 2);
11071ca298ceSMatthias Weisser 	else if (x < 0)
11081ca298ceSMatthias Weisser 		x = max(0, VIDEO_VISIBLE_COLS - width + x + 1);
11091ca298ceSMatthias Weisser 
11101ca298ceSMatthias Weisser 	if (y == BMP_ALIGN_CENTER)
11111ca298ceSMatthias Weisser 		y = max(0, (VIDEO_VISIBLE_ROWS - height) / 2);
11121ca298ceSMatthias Weisser 	else if (y < 0)
11131ca298ceSMatthias Weisser 		y = max(0, VIDEO_VISIBLE_ROWS - height + y + 1);
11141ca298ceSMatthias Weisser #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
11151ca298ceSMatthias Weisser 
1116352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((x + width) > VIDEO_VISIBLE_COLS)
1117352d2591SJean-Christophe PLAGNIOL-VILLARD 		width = VIDEO_VISIBLE_COLS - x;
1118352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((y + height) > VIDEO_VISIBLE_ROWS)
1119352d2591SJean-Christophe PLAGNIOL-VILLARD 		height = VIDEO_VISIBLE_ROWS - y;
1120352d2591SJean-Christophe PLAGNIOL-VILLARD 
1121352d2591SJean-Christophe PLAGNIOL-VILLARD 	bmap = (uchar *) bmp + le32_to_cpu (bmp->header.data_offset);
1122352d2591SJean-Christophe PLAGNIOL-VILLARD 	fb = (uchar *) (video_fb_address +
1123352d2591SJean-Christophe PLAGNIOL-VILLARD 			((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) +
1124352d2591SJean-Christophe PLAGNIOL-VILLARD 			x * VIDEO_PIXEL_SIZE);
1125352d2591SJean-Christophe PLAGNIOL-VILLARD 
1126d5011762SAnatolij Gustschin #ifdef CONFIG_VIDEO_BMP_RLE8
1127d5011762SAnatolij Gustschin 	if (compression == BMP_BI_RLE8) {
1128d5011762SAnatolij Gustschin 		return display_rle8_bitmap(bmp,
1129d5011762SAnatolij Gustschin 					   x, y, width, height);
1130d5011762SAnatolij Gustschin 	}
1131d5011762SAnatolij Gustschin #endif
1132d5011762SAnatolij Gustschin 
113368f6618bSTimur Tabi 	/* We handle only 4, 8, or 24 bpp bitmaps */
1134352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (le16_to_cpu (bmp->header.bit_count)) {
113568f6618bSTimur Tabi 	case 4:
113668f6618bSTimur Tabi 		padded_line -= width / 2;
113768f6618bSTimur Tabi 		ycount = height;
113868f6618bSTimur Tabi 
113968f6618bSTimur Tabi 		switch (VIDEO_DATA_FORMAT) {
114068f6618bSTimur Tabi 		case GDF_32BIT_X888RGB:
114168f6618bSTimur Tabi 			while (ycount--) {
114268f6618bSTimur Tabi 				WATCHDOG_RESET ();
114368f6618bSTimur Tabi 				/*
114468f6618bSTimur Tabi 				 * Don't assume that 'width' is an
114568f6618bSTimur Tabi 				 * even number
114668f6618bSTimur Tabi 				 */
114768f6618bSTimur Tabi 				for (xcount = 0; xcount < width; xcount++) {
114868f6618bSTimur Tabi 					uchar idx;
114968f6618bSTimur Tabi 
115068f6618bSTimur Tabi 					if (xcount & 1) {
115168f6618bSTimur Tabi 						idx = *bmap & 0xF;
115268f6618bSTimur Tabi 						bmap++;
115368f6618bSTimur Tabi 					} else
115468f6618bSTimur Tabi 						idx = *bmap >> 4;
115568f6618bSTimur Tabi 					cte = bmp->color_table[idx];
115668f6618bSTimur Tabi 					FILL_32BIT_X888RGB(cte.red, cte.green,
115768f6618bSTimur Tabi 							   cte.blue);
115868f6618bSTimur Tabi 				}
115968f6618bSTimur Tabi 				bmap += padded_line;
116068f6618bSTimur Tabi 				fb -= (VIDEO_VISIBLE_COLS + width) *
116168f6618bSTimur Tabi 				      VIDEO_PIXEL_SIZE;
116268f6618bSTimur Tabi 			}
116368f6618bSTimur Tabi 			break;
116468f6618bSTimur Tabi 		default:
116568f6618bSTimur Tabi 			puts("4bpp bitmap unsupported with current "
116668f6618bSTimur Tabi 			     "video mode\n");
116768f6618bSTimur Tabi 			break;
116868f6618bSTimur Tabi 		}
116968f6618bSTimur Tabi 		break;
117068f6618bSTimur Tabi 
1171352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 8:
1172352d2591SJean-Christophe PLAGNIOL-VILLARD 		padded_line -= width;
1173352d2591SJean-Christophe PLAGNIOL-VILLARD 		if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
1174352d2591SJean-Christophe PLAGNIOL-VILLARD 			/* Copy colormap */
1175352d2591SJean-Christophe PLAGNIOL-VILLARD 			for (xcount = 0; xcount < colors; ++xcount) {
1176352d2591SJean-Christophe PLAGNIOL-VILLARD 				cte = bmp->color_table[xcount];
1177352d2591SJean-Christophe PLAGNIOL-VILLARD 				video_set_lut (xcount, cte.red, cte.green, cte.blue);
1178352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1179352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1180352d2591SJean-Christophe PLAGNIOL-VILLARD 		ycount = height;
1181352d2591SJean-Christophe PLAGNIOL-VILLARD 		switch (VIDEO_DATA_FORMAT) {
1182352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF__8BIT_INDEX:
1183352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1184352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET ();
1185352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1186352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1187352d2591SJean-Christophe PLAGNIOL-VILLARD 					*fb++ = *bmap++;
1188352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1189352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1190352d2591SJean-Christophe PLAGNIOL-VILLARD 				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
1191352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1192352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1193352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF__8BIT_332RGB:
1194352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1195352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET ();
1196352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1197352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1198352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
1199352d2591SJean-Christophe PLAGNIOL-VILLARD 					FILL_8BIT_332RGB (cte.red, cte.green, cte.blue);
1200352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1201352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1202352d2591SJean-Christophe PLAGNIOL-VILLARD 				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
1203352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1204352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1205352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_15BIT_555RGB:
1206352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1207e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1208e84d568fSAnatolij Gustschin 				int xpos = x;
1209e84d568fSAnatolij Gustschin #endif
1210352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET ();
1211352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1212352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1213352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
1214cc347801SAndrew Dyer #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1215e84d568fSAnatolij Gustschin 					fill_555rgb_pswap (fb, xpos++, cte.red,
1216e84d568fSAnatolij Gustschin 							   cte.green, cte.blue);
1217e84d568fSAnatolij Gustschin 					fb += 2;
1218cc347801SAndrew Dyer #else
1219cc347801SAndrew Dyer 					FILL_15BIT_555RGB (cte.red, cte.green, cte.blue);
1220e84d568fSAnatolij Gustschin #endif
1221352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1222352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1223352d2591SJean-Christophe PLAGNIOL-VILLARD 				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
1224352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1225352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1226352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_16BIT_565RGB:
1227352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1228352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET ();
1229352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1230352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1231352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
1232352d2591SJean-Christophe PLAGNIOL-VILLARD 					FILL_16BIT_565RGB (cte.red, cte.green, cte.blue);
1233352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1234352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1235352d2591SJean-Christophe PLAGNIOL-VILLARD 				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
1236352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1237352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1238352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_32BIT_X888RGB:
1239352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1240352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET ();
1241352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1242352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1243352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
1244352d2591SJean-Christophe PLAGNIOL-VILLARD 					FILL_32BIT_X888RGB (cte.red, cte.green, cte.blue);
1245352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1246352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1247352d2591SJean-Christophe PLAGNIOL-VILLARD 				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
1248352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1249352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1250352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_24BIT_888RGB:
1251352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1252352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET ();
1253352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1254352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1255352d2591SJean-Christophe PLAGNIOL-VILLARD 					cte = bmp->color_table[*bmap++];
1256352d2591SJean-Christophe PLAGNIOL-VILLARD 					FILL_24BIT_888RGB (cte.red, cte.green, cte.blue);
1257352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1258352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1259352d2591SJean-Christophe PLAGNIOL-VILLARD 				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
1260352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1261352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1262352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1263352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1264352d2591SJean-Christophe PLAGNIOL-VILLARD 	case 24:
1265352d2591SJean-Christophe PLAGNIOL-VILLARD 		padded_line -= 3 * width;
1266352d2591SJean-Christophe PLAGNIOL-VILLARD 		ycount = height;
1267352d2591SJean-Christophe PLAGNIOL-VILLARD 		switch (VIDEO_DATA_FORMAT) {
1268352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF__8BIT_332RGB:
1269352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1270352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET ();
1271352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1272352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1273352d2591SJean-Christophe PLAGNIOL-VILLARD 					FILL_8BIT_332RGB (bmap[2], bmap[1], bmap[0]);
1274352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1275352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1276352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1277352d2591SJean-Christophe PLAGNIOL-VILLARD 				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
1278352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1279352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1280352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_15BIT_555RGB:
1281352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1282e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1283e84d568fSAnatolij Gustschin 				int xpos = x;
1284e84d568fSAnatolij Gustschin #endif
1285352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET ();
1286352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1287352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1288cc347801SAndrew Dyer #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1289e84d568fSAnatolij Gustschin 					fill_555rgb_pswap (fb, xpos++, bmap[2],
1290e84d568fSAnatolij Gustschin 							   bmap[1], bmap[0]);
1291e84d568fSAnatolij Gustschin 					fb += 2;
1292cc347801SAndrew Dyer #else
1293cc347801SAndrew Dyer 					FILL_15BIT_555RGB (bmap[2], bmap[1], bmap[0]);
1294e84d568fSAnatolij Gustschin #endif
1295352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1296352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1297352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1298352d2591SJean-Christophe PLAGNIOL-VILLARD 				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
1299352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1300352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1301352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_16BIT_565RGB:
1302352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1303352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET ();
1304352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1305352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1306352d2591SJean-Christophe PLAGNIOL-VILLARD 					FILL_16BIT_565RGB (bmap[2], bmap[1], bmap[0]);
1307352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1308352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1309352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1310352d2591SJean-Christophe PLAGNIOL-VILLARD 				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
1311352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1312352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1313352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_32BIT_X888RGB:
1314352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1315352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET ();
1316352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1317352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1318352d2591SJean-Christophe PLAGNIOL-VILLARD 					FILL_32BIT_X888RGB (bmap[2], bmap[1], bmap[0]);
1319352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1320352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1321352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1322352d2591SJean-Christophe PLAGNIOL-VILLARD 				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
1323352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1324352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1325352d2591SJean-Christophe PLAGNIOL-VILLARD 		case GDF_24BIT_888RGB:
1326352d2591SJean-Christophe PLAGNIOL-VILLARD 			while (ycount--) {
1327352d2591SJean-Christophe PLAGNIOL-VILLARD 				WATCHDOG_RESET ();
1328352d2591SJean-Christophe PLAGNIOL-VILLARD 				xcount = width;
1329352d2591SJean-Christophe PLAGNIOL-VILLARD 				while (xcount--) {
1330352d2591SJean-Christophe PLAGNIOL-VILLARD 					FILL_24BIT_888RGB (bmap[2], bmap[1], bmap[0]);
1331352d2591SJean-Christophe PLAGNIOL-VILLARD 					bmap += 3;
1332352d2591SJean-Christophe PLAGNIOL-VILLARD 				}
1333352d2591SJean-Christophe PLAGNIOL-VILLARD 				bmap += padded_line;
1334352d2591SJean-Christophe PLAGNIOL-VILLARD 				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
1335352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1336352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1337352d2591SJean-Christophe PLAGNIOL-VILLARD 		default:
1338352d2591SJean-Christophe PLAGNIOL-VILLARD 			printf ("Error: 24 bits/pixel bitmap incompatible with current video mode\n");
1339352d2591SJean-Christophe PLAGNIOL-VILLARD 			break;
1340352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1341352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1342352d2591SJean-Christophe PLAGNIOL-VILLARD 	default:
1343352d2591SJean-Christophe PLAGNIOL-VILLARD 		printf ("Error: %d bit/pixel bitmaps not supported by U-Boot\n",
1344352d2591SJean-Christophe PLAGNIOL-VILLARD 			le16_to_cpu (bmp->header.bit_count));
1345352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1346352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1347352d2591SJean-Christophe PLAGNIOL-VILLARD 
1348352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_GZIP
1349352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (dst) {
1350352d2591SJean-Christophe PLAGNIOL-VILLARD 		free(dst);
1351352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1352352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1353352d2591SJean-Christophe PLAGNIOL-VILLARD 
1354352d2591SJean-Christophe PLAGNIOL-VILLARD 	return (0);
1355352d2591SJean-Christophe PLAGNIOL-VILLARD }
1356352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1357352d2591SJean-Christophe PLAGNIOL-VILLARD 
1358352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
1359352d2591SJean-Christophe PLAGNIOL-VILLARD 
1360352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_LOGO
1361352d2591SJean-Christophe PLAGNIOL-VILLARD void logo_plot (void *screen, int width, int x, int y)
1362352d2591SJean-Christophe PLAGNIOL-VILLARD {
1363352d2591SJean-Christophe PLAGNIOL-VILLARD 
1364352d2591SJean-Christophe PLAGNIOL-VILLARD 	int xcount, i;
1365352d2591SJean-Christophe PLAGNIOL-VILLARD 	int skip   = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE;
1366be129aa7SMatthias Weisser 	int ycount = video_logo_height;
1367352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char r, g, b, *logo_red, *logo_blue, *logo_green;
1368352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char *source;
1369d9015f6aSAnatolij Gustschin 	unsigned char *dest = (unsigned char *)screen +
1370d9015f6aSAnatolij Gustschin 			      ((y * width * VIDEO_PIXEL_SIZE) +
1371d9015f6aSAnatolij Gustschin 			       x * VIDEO_PIXEL_SIZE);
1372352d2591SJean-Christophe PLAGNIOL-VILLARD 
1373352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_LOGO
1374352d2591SJean-Christophe PLAGNIOL-VILLARD 	source = bmp_logo_bitmap;
1375352d2591SJean-Christophe PLAGNIOL-VILLARD 
1376352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Allocate temporary space for computing colormap */
1377352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_red = malloc (BMP_LOGO_COLORS);
1378352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_green = malloc (BMP_LOGO_COLORS);
1379352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_blue = malloc (BMP_LOGO_COLORS);
1380352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Compute color map */
1381352d2591SJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
1382352d2591SJean-Christophe PLAGNIOL-VILLARD 		logo_red[i] = (bmp_logo_palette[i] & 0x0f00) >> 4;
1383352d2591SJean-Christophe PLAGNIOL-VILLARD 		logo_green[i] = (bmp_logo_palette[i] & 0x00f0);
1384352d2591SJean-Christophe PLAGNIOL-VILLARD 		logo_blue[i] = (bmp_logo_palette[i] & 0x000f) << 4;
1385352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1386352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1387352d2591SJean-Christophe PLAGNIOL-VILLARD 	source = linux_logo;
1388352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_red = linux_logo_red;
1389352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_green = linux_logo_green;
1390352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_blue = linux_logo_blue;
1391352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1392352d2591SJean-Christophe PLAGNIOL-VILLARD 
1393352d2591SJean-Christophe PLAGNIOL-VILLARD 	if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
1394352d2591SJean-Christophe PLAGNIOL-VILLARD 		for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
1395352d2591SJean-Christophe PLAGNIOL-VILLARD 			video_set_lut (i + VIDEO_LOGO_LUT_OFFSET,
1396352d2591SJean-Christophe PLAGNIOL-VILLARD 				       logo_red[i], logo_green[i], logo_blue[i]);
1397352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1398352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1399352d2591SJean-Christophe PLAGNIOL-VILLARD 
1400352d2591SJean-Christophe PLAGNIOL-VILLARD 	while (ycount--) {
1401e84d568fSAnatolij Gustschin #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1402e84d568fSAnatolij Gustschin 		int xpos = x;
1403e84d568fSAnatolij Gustschin #endif
1404352d2591SJean-Christophe PLAGNIOL-VILLARD 		xcount = VIDEO_LOGO_WIDTH;
1405352d2591SJean-Christophe PLAGNIOL-VILLARD 		while (xcount--) {
1406352d2591SJean-Christophe PLAGNIOL-VILLARD 			r = logo_red[*source - VIDEO_LOGO_LUT_OFFSET];
1407352d2591SJean-Christophe PLAGNIOL-VILLARD 			g = logo_green[*source - VIDEO_LOGO_LUT_OFFSET];
1408352d2591SJean-Christophe PLAGNIOL-VILLARD 			b = logo_blue[*source - VIDEO_LOGO_LUT_OFFSET];
1409352d2591SJean-Christophe PLAGNIOL-VILLARD 
1410352d2591SJean-Christophe PLAGNIOL-VILLARD 			switch (VIDEO_DATA_FORMAT) {
1411352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF__8BIT_INDEX:
1412352d2591SJean-Christophe PLAGNIOL-VILLARD 				*dest = *source;
1413352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1414352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF__8BIT_332RGB:
1415352d2591SJean-Christophe PLAGNIOL-VILLARD 				*dest = ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
1416352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1417352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_15BIT_555RGB:
1418cc347801SAndrew Dyer #if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
1419cc347801SAndrew Dyer 				fill_555rgb_pswap (dest, xpos++, r, g, b);
1420cc347801SAndrew Dyer #else
1421352d2591SJean-Christophe PLAGNIOL-VILLARD 				*(unsigned short *) dest =
1422352d2591SJean-Christophe PLAGNIOL-VILLARD 					SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3)));
1423bed53753SAnatolij Gustschin #endif
1424352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1425352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_16BIT_565RGB:
1426352d2591SJean-Christophe PLAGNIOL-VILLARD 				*(unsigned short *) dest =
1427352d2591SJean-Christophe PLAGNIOL-VILLARD 					SWAP16 ((unsigned short) (((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)));
1428352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1429352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_32BIT_X888RGB:
1430352d2591SJean-Christophe PLAGNIOL-VILLARD 				*(unsigned long *) dest =
1431352d2591SJean-Christophe PLAGNIOL-VILLARD 					SWAP32 ((unsigned long) ((r << 16) | (g << 8) | b));
1432352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1433352d2591SJean-Christophe PLAGNIOL-VILLARD 			case GDF_24BIT_888RGB:
1434352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef VIDEO_FB_LITTLE_ENDIAN
1435352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[0] = b;
1436352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[1] = g;
1437352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[2] = r;
1438352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1439352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[0] = r;
1440352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[1] = g;
1441352d2591SJean-Christophe PLAGNIOL-VILLARD 				dest[2] = b;
1442352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1443352d2591SJean-Christophe PLAGNIOL-VILLARD 				break;
1444352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1445352d2591SJean-Christophe PLAGNIOL-VILLARD 			source++;
1446352d2591SJean-Christophe PLAGNIOL-VILLARD 			dest += VIDEO_PIXEL_SIZE;
1447352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1448352d2591SJean-Christophe PLAGNIOL-VILLARD 		dest += skip;
1449352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1450352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_BMP_LOGO
1451352d2591SJean-Christophe PLAGNIOL-VILLARD 	free (logo_red);
1452352d2591SJean-Christophe PLAGNIOL-VILLARD 	free (logo_green);
1453352d2591SJean-Christophe PLAGNIOL-VILLARD 	free (logo_blue);
1454352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1455352d2591SJean-Christophe PLAGNIOL-VILLARD }
1456352d2591SJean-Christophe PLAGNIOL-VILLARD 
1457352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
1458352d2591SJean-Christophe PLAGNIOL-VILLARD 
1459352d2591SJean-Christophe PLAGNIOL-VILLARD static void *video_logo (void)
1460352d2591SJean-Christophe PLAGNIOL-VILLARD {
1461352d2591SJean-Christophe PLAGNIOL-VILLARD 	char info[128];
14623dcbe628SAnatolij Gustschin 	int space, len, y_off = 0;
1463352d2591SJean-Christophe PLAGNIOL-VILLARD 
1464352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SPLASH_SCREEN
1465352d2591SJean-Christophe PLAGNIOL-VILLARD 	char *s;
1466352d2591SJean-Christophe PLAGNIOL-VILLARD 	ulong addr;
1467352d2591SJean-Christophe PLAGNIOL-VILLARD 
1468352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((s = getenv ("splashimage")) != NULL) {
14691ca298ceSMatthias Weisser 		int x = 0, y = 0;
1470352d2591SJean-Christophe PLAGNIOL-VILLARD 
14711ca298ceSMatthias Weisser 		addr = simple_strtoul (s, NULL, 16);
14721ca298ceSMatthias Weisser #ifdef CONFIG_SPLASH_SCREEN_ALIGN
14731ca298ceSMatthias Weisser 		if ((s = getenv ("splashpos")) != NULL) {
14741ca298ceSMatthias Weisser 			if (s[0] == 'm')
14751ca298ceSMatthias Weisser 				x = BMP_ALIGN_CENTER;
14761ca298ceSMatthias Weisser 			else
14771ca298ceSMatthias Weisser 				x = simple_strtol (s, NULL, 0);
14781ca298ceSMatthias Weisser 
14791ca298ceSMatthias Weisser 			if ((s = strchr (s + 1, ',')) != NULL) {
14801ca298ceSMatthias Weisser 				if (s[1] == 'm')
14811ca298ceSMatthias Weisser 					y = BMP_ALIGN_CENTER;
14821ca298ceSMatthias Weisser 				else
14831ca298ceSMatthias Weisser 					y = simple_strtol (s + 1, NULL, 0);
14841ca298ceSMatthias Weisser 			}
14851ca298ceSMatthias Weisser 		}
14861ca298ceSMatthias Weisser #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
14871ca298ceSMatthias Weisser 
14881ca298ceSMatthias Weisser 		if (video_display_bitmap (addr, x, y) == 0) {
1489be129aa7SMatthias Weisser 			video_logo_height = 0;
1490352d2591SJean-Christophe PLAGNIOL-VILLARD 			return ((void *) (video_fb_address));
1491352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
1492352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1493352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_SPLASH_SCREEN */
1494352d2591SJean-Christophe PLAGNIOL-VILLARD 
1495352d2591SJean-Christophe PLAGNIOL-VILLARD 	logo_plot (video_fb_address, VIDEO_COLS, 0, 0);
1496352d2591SJean-Christophe PLAGNIOL-VILLARD 
1497*ce0f709bSAndreas Bießmann 	sprintf (info, " %s", version_string);
14983dcbe628SAnatolij Gustschin 
14993dcbe628SAnatolij Gustschin 	space = (VIDEO_LINE_LEN / 2 - VIDEO_INFO_X) / VIDEO_FONT_WIDTH;
15003dcbe628SAnatolij Gustschin 	len = strlen(info);
15013dcbe628SAnatolij Gustschin 
15023dcbe628SAnatolij Gustschin 	if (len > space) {
15033dcbe628SAnatolij Gustschin 		video_drawchars (VIDEO_INFO_X, VIDEO_INFO_Y,
15043dcbe628SAnatolij Gustschin 				 (uchar *)info, space);
15053dcbe628SAnatolij Gustschin 		video_drawchars (VIDEO_INFO_X + VIDEO_FONT_WIDTH,
15063dcbe628SAnatolij Gustschin 				 VIDEO_INFO_Y + VIDEO_FONT_HEIGHT,
15073dcbe628SAnatolij Gustschin 				 (uchar *)info + space, len - space);
15083dcbe628SAnatolij Gustschin 		y_off = 1;
15093dcbe628SAnatolij Gustschin 	} else
1510352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *)info);
1511352d2591SJean-Christophe PLAGNIOL-VILLARD 
1512352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_CONSOLE_EXTRA_INFO
1513352d2591SJean-Christophe PLAGNIOL-VILLARD 	{
1514be129aa7SMatthias Weisser 		int i, n = ((video_logo_height - VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT);
1515352d2591SJean-Christophe PLAGNIOL-VILLARD 
1516352d2591SJean-Christophe PLAGNIOL-VILLARD 		for (i = 1; i < n; i++) {
1517352d2591SJean-Christophe PLAGNIOL-VILLARD 			video_get_info_str (i, info);
15183dcbe628SAnatolij Gustschin 			if (!*info)
15193dcbe628SAnatolij Gustschin 				continue;
15203dcbe628SAnatolij Gustschin 
15213dcbe628SAnatolij Gustschin 			len = strlen(info);
15223dcbe628SAnatolij Gustschin 			if (len > space) {
15233dcbe628SAnatolij Gustschin 				video_drawchars (VIDEO_INFO_X,
15243dcbe628SAnatolij Gustschin 						 VIDEO_INFO_Y +
15253dcbe628SAnatolij Gustschin 						 (i + y_off) * VIDEO_FONT_HEIGHT,
15263dcbe628SAnatolij Gustschin 						 (uchar *)info, space);
15273dcbe628SAnatolij Gustschin 				y_off++;
15283dcbe628SAnatolij Gustschin 				video_drawchars (VIDEO_INFO_X + VIDEO_FONT_WIDTH,
15293dcbe628SAnatolij Gustschin 						 VIDEO_INFO_Y +
15303dcbe628SAnatolij Gustschin 						 (i + y_off) * VIDEO_FONT_HEIGHT,
15313dcbe628SAnatolij Gustschin 						 (uchar *)info + space,
15323dcbe628SAnatolij Gustschin 						 len - space);
15333dcbe628SAnatolij Gustschin 			} else {
1534352d2591SJean-Christophe PLAGNIOL-VILLARD 				video_drawstring (VIDEO_INFO_X,
15353dcbe628SAnatolij Gustschin 						  VIDEO_INFO_Y +
15363dcbe628SAnatolij Gustschin 						  (i + y_off) * VIDEO_FONT_HEIGHT,
1537352d2591SJean-Christophe PLAGNIOL-VILLARD 						  (uchar *)info);
1538352d2591SJean-Christophe PLAGNIOL-VILLARD 			}
1539352d2591SJean-Christophe PLAGNIOL-VILLARD 		}
15403dcbe628SAnatolij Gustschin 	}
1541352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1542352d2591SJean-Christophe PLAGNIOL-VILLARD 
1543be129aa7SMatthias Weisser 	return (video_fb_address + video_logo_height * VIDEO_LINE_LEN);
1544352d2591SJean-Christophe PLAGNIOL-VILLARD }
1545352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1546352d2591SJean-Christophe PLAGNIOL-VILLARD 
1547352d2591SJean-Christophe PLAGNIOL-VILLARD 
1548352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
1549352d2591SJean-Christophe PLAGNIOL-VILLARD 
1550352d2591SJean-Christophe PLAGNIOL-VILLARD static int video_init (void)
1551352d2591SJean-Christophe PLAGNIOL-VILLARD {
1552352d2591SJean-Christophe PLAGNIOL-VILLARD 	unsigned char color8;
1553352d2591SJean-Christophe PLAGNIOL-VILLARD 
1554352d2591SJean-Christophe PLAGNIOL-VILLARD 	if ((pGD = video_hw_init ()) == NULL)
1555352d2591SJean-Christophe PLAGNIOL-VILLARD 		return -1;
1556352d2591SJean-Christophe PLAGNIOL-VILLARD 
1557352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_fb_address = (void *) VIDEO_FB_ADRS;
1558352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_HW_CURSOR
1559352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_init_hw_cursor (VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
1560352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1561352d2591SJean-Christophe PLAGNIOL-VILLARD 
1562352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Init drawing pats */
1563352d2591SJean-Christophe PLAGNIOL-VILLARD 	switch (VIDEO_DATA_FORMAT) {
1564352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_INDEX:
1565352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_set_lut (0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
1566352d2591SJean-Christophe PLAGNIOL-VILLARD 		video_set_lut (0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL);
1567352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = 0x01010101;
1568352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = 0x00000000;
1569352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1570352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF__8BIT_332RGB:
1571352d2591SJean-Christophe PLAGNIOL-VILLARD 		color8 = ((CONSOLE_FG_COL & 0xe0) |
1572352d2591SJean-Christophe PLAGNIOL-VILLARD 			  ((CONSOLE_FG_COL >> 3) & 0x1c) | CONSOLE_FG_COL >> 6);
1573352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8;
1574352d2591SJean-Christophe PLAGNIOL-VILLARD 		color8 = ((CONSOLE_BG_COL & 0xe0) |
1575352d2591SJean-Christophe PLAGNIOL-VILLARD 			  ((CONSOLE_BG_COL >> 3) & 0x1c) | CONSOLE_BG_COL >> 6);
1576352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8;
1577352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1578352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_15BIT_555RGB:
1579352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = (((CONSOLE_FG_COL >> 3) << 26) |
1580352d2591SJean-Christophe PLAGNIOL-VILLARD 		       ((CONSOLE_FG_COL >> 3) << 21) | ((CONSOLE_FG_COL >> 3) << 16) |
1581352d2591SJean-Christophe PLAGNIOL-VILLARD 		       ((CONSOLE_FG_COL >> 3) << 10) | ((CONSOLE_FG_COL >> 3) << 5) |
1582352d2591SJean-Christophe PLAGNIOL-VILLARD 		       (CONSOLE_FG_COL >> 3));
1583352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = (((CONSOLE_BG_COL >> 3) << 26) |
1584352d2591SJean-Christophe PLAGNIOL-VILLARD 		       ((CONSOLE_BG_COL >> 3) << 21) | ((CONSOLE_BG_COL >> 3) << 16) |
1585352d2591SJean-Christophe PLAGNIOL-VILLARD 		       ((CONSOLE_BG_COL >> 3) << 10) | ((CONSOLE_BG_COL >> 3) << 5) |
1586352d2591SJean-Christophe PLAGNIOL-VILLARD 		       (CONSOLE_BG_COL >> 3));
1587352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1588352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_16BIT_565RGB:
1589352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = (((CONSOLE_FG_COL >> 3) << 27) |
1590352d2591SJean-Christophe PLAGNIOL-VILLARD 		       ((CONSOLE_FG_COL >> 2) << 21) | ((CONSOLE_FG_COL >> 3) << 16) |
1591352d2591SJean-Christophe PLAGNIOL-VILLARD 		       ((CONSOLE_FG_COL >> 3) << 11) | ((CONSOLE_FG_COL >> 2) << 5) |
1592352d2591SJean-Christophe PLAGNIOL-VILLARD 		       (CONSOLE_FG_COL >> 3));
1593352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = (((CONSOLE_BG_COL >> 3) << 27) |
1594352d2591SJean-Christophe PLAGNIOL-VILLARD 		       ((CONSOLE_BG_COL >> 2) << 21) | ((CONSOLE_BG_COL >> 3) << 16) |
1595352d2591SJean-Christophe PLAGNIOL-VILLARD 		       ((CONSOLE_BG_COL >> 3) << 11) | ((CONSOLE_BG_COL >> 2) << 5) |
1596352d2591SJean-Christophe PLAGNIOL-VILLARD 		       (CONSOLE_BG_COL >> 3));
1597352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1598352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_32BIT_X888RGB:
1599352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = (CONSOLE_FG_COL << 16) | (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL;
1600352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = (CONSOLE_BG_COL << 16) | (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL;
1601352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1602352d2591SJean-Christophe PLAGNIOL-VILLARD 	case GDF_24BIT_888RGB:
1603352d2591SJean-Christophe PLAGNIOL-VILLARD 		fgx = (CONSOLE_FG_COL << 24) | (CONSOLE_FG_COL << 16) |
1604352d2591SJean-Christophe PLAGNIOL-VILLARD 			(CONSOLE_FG_COL << 8) | CONSOLE_FG_COL;
1605352d2591SJean-Christophe PLAGNIOL-VILLARD 		bgx = (CONSOLE_BG_COL << 24) | (CONSOLE_BG_COL << 16) |
1606352d2591SJean-Christophe PLAGNIOL-VILLARD 			(CONSOLE_BG_COL << 8) | CONSOLE_BG_COL;
1607352d2591SJean-Christophe PLAGNIOL-VILLARD 		break;
1608352d2591SJean-Christophe PLAGNIOL-VILLARD 	}
1609352d2591SJean-Christophe PLAGNIOL-VILLARD 	eorx = fgx ^ bgx;
1610352d2591SJean-Christophe PLAGNIOL-VILLARD 
1611352d2591SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_VIDEO_LOGO
1612352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Plot the logo and get start point of console */
1613352d2591SJean-Christophe PLAGNIOL-VILLARD 	PRINTD ("Video: Drawing the logo ...\n");
1614352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_console_address = video_logo ();
1615352d2591SJean-Christophe PLAGNIOL-VILLARD #else
1616352d2591SJean-Christophe PLAGNIOL-VILLARD 	video_console_address = video_fb_address;
1617352d2591SJean-Christophe PLAGNIOL-VILLARD #endif
1618352d2591SJean-Christophe PLAGNIOL-VILLARD 
1619352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Initialize the console */
1620352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_col = 0;
1621352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_row = 0;
1622352d2591SJean-Christophe PLAGNIOL-VILLARD 
1623352d2591SJean-Christophe PLAGNIOL-VILLARD 	return 0;
1624352d2591SJean-Christophe PLAGNIOL-VILLARD }
1625352d2591SJean-Christophe PLAGNIOL-VILLARD 
1626352d2591SJean-Christophe PLAGNIOL-VILLARD 
1627352d2591SJean-Christophe PLAGNIOL-VILLARD /*****************************************************************************/
1628352d2591SJean-Christophe PLAGNIOL-VILLARD 
16296cc7ba9eSWolfgang Denk /*
16306cc7ba9eSWolfgang Denk  * Implement a weak default function for boards that optionally
16316cc7ba9eSWolfgang Denk  * need to skip the video initialization.
16326cc7ba9eSWolfgang Denk  */
16336cc7ba9eSWolfgang Denk int __board_video_skip(void)
16346cc7ba9eSWolfgang Denk {
16356cc7ba9eSWolfgang Denk 	/* As default, don't skip test */
16366cc7ba9eSWolfgang Denk 	return 0;
16376cc7ba9eSWolfgang Denk }
16386cc7ba9eSWolfgang Denk int board_video_skip(void) __attribute__((weak, alias("__board_video_skip")));
16396cc7ba9eSWolfgang Denk 
1640352d2591SJean-Christophe PLAGNIOL-VILLARD int drv_video_init (void)
1641352d2591SJean-Christophe PLAGNIOL-VILLARD {
1642352d2591SJean-Christophe PLAGNIOL-VILLARD 	int skip_dev_init;
164352cb4d4fSJean-Christophe PLAGNIOL-VILLARD 	struct stdio_dev console_dev;
1644352d2591SJean-Christophe PLAGNIOL-VILLARD 
16456cc7ba9eSWolfgang Denk 	/* Check if video initialization should be skipped */
16466cc7ba9eSWolfgang Denk 	if (board_video_skip())
16476cc7ba9eSWolfgang Denk 		return 0;
16486cc7ba9eSWolfgang Denk 
1649352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Init video chip - returns with framebuffer cleared */
1650f62f6469SWolfgang Denk 	skip_dev_init = (video_init () == -1);
1651352d2591SJean-Christophe PLAGNIOL-VILLARD 
1652f62f6469SWolfgang Denk #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
1653f62f6469SWolfgang Denk 	PRINTD ("KBD: Keyboard init ...\n");
1654f62f6469SWolfgang Denk 	skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
1655f62f6469SWolfgang Denk #endif
1656f62f6469SWolfgang Denk 
1657f62f6469SWolfgang Denk 	if (skip_dev_init)
1658f62f6469SWolfgang Denk 		return 0;
1659f62f6469SWolfgang Denk 
1660352d2591SJean-Christophe PLAGNIOL-VILLARD 	/* Init vga device */
1661352d2591SJean-Christophe PLAGNIOL-VILLARD 	memset (&console_dev, 0, sizeof (console_dev));
1662352d2591SJean-Christophe PLAGNIOL-VILLARD 	strcpy (console_dev.name, "vga");
1663352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.ext = DEV_EXT_VIDEO;	/* Video extensions */
1664352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
1665352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.putc = video_putc;	/* 'putc' function */
1666352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.puts = video_puts;	/* 'puts' function */
1667352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.tstc = NULL;	/* 'tstc' function */
1668352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.getc = NULL;	/* 'getc' function */
1669352d2591SJean-Christophe PLAGNIOL-VILLARD 
1670f62f6469SWolfgang Denk #if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
1671f62f6469SWolfgang Denk 	/* Also init console device */
1672f62f6469SWolfgang Denk 	console_dev.flags |= DEV_FLAGS_INPUT;
1673352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.tstc = VIDEO_TSTC_FCT;	/* 'tstc' function */
1674352d2591SJean-Christophe PLAGNIOL-VILLARD 	console_dev.getc = VIDEO_GETC_FCT;	/* 'getc' function */
1675352d2591SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
1676f62f6469SWolfgang Denk 
167752cb4d4fSJean-Christophe PLAGNIOL-VILLARD 	if (stdio_register (&console_dev) != 0)
1678352d2591SJean-Christophe PLAGNIOL-VILLARD 		return 0;
1679f62f6469SWolfgang Denk 
1680f62f6469SWolfgang Denk 	/* Return success */
1681f62f6469SWolfgang Denk 	return 1;
1682352d2591SJean-Christophe PLAGNIOL-VILLARD }
1683