]>
Commit | Line | Data |
---|---|---|
c609719b WD |
1 | /* |
2 | * (C) Copyright 2002 ELTEC Elektronik AG | |
3 | * Frank Gottschling <[email protected]> | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
4b248f3f | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
c609719b WD |
16 | * GNU General Public License for more details. |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | /* | |
25 | * cfb_console.c | |
26 | * | |
27 | * Color Framebuffer Console driver for 8/15/16/24/32 bits per pixel. | |
28 | * | |
29 | * At the moment only the 8x16 font is tested and the font fore- and | |
30 | * background color is limited to black/white/gray colors. The Linux | |
31 | * logo can be placed in the upper left corner and additional board | |
32 | * information strings (that normaly goes to serial port) can be drawed. | |
33 | * | |
34 | * The console driver can use the standard PC keyboard interface (i8042) | |
35 | * for character input. Character output goes to a memory mapped video | |
36 | * framebuffer with little or big-endian organisation. | |
37 | * With environment setting 'console=serial' the console i/o can be | |
38 | * forced to serial port. | |
39 | ||
40 | The driver uses graphic specific defines/parameters/functions: | |
41 | ||
42 | (for SMI LynxE graphic chip) | |
43 | ||
44 | CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810 | |
4b248f3f WD |
45 | VIDEO_FB_LITTLE_ENDIAN - framebuffer organisation default: big endian |
46 | VIDEO_HW_RECTFILL - graphic driver supports hardware rectangle fill | |
47 | VIDEO_HW_BITBLT - graphic driver supports hardware bit blt | |
c609719b WD |
48 | |
49 | Console Parameters are set by graphic drivers global struct: | |
50 | ||
4b248f3f WD |
51 | VIDEO_VISIBLE_COLS - x resolution |
52 | VIDEO_VISIBLE_ROWS - y resolution | |
53 | VIDEO_PIXEL_SIZE - storage size in byte per pixel | |
54 | VIDEO_DATA_FORMAT - graphical data format GDF | |
55 | VIDEO_FB_ADRS - start of video memory | |
c609719b | 56 | |
4b248f3f WD |
57 | CONFIG_I8042_KBD - AT Keyboard driver for i8042 |
58 | VIDEO_KBD_INIT_FCT - init function for keyboard | |
59 | VIDEO_TSTC_FCT - keyboard_tstc function | |
60 | VIDEO_GETC_FCT - keyboard_getc function | |
c609719b | 61 | |
4b248f3f | 62 | CONFIG_CONSOLE_CURSOR - on/off drawing cursor is done with delay |
8bde7f77 | 63 | loop in VIDEO_TSTC_FCT (i8042) |
c609719b | 64 | CFG_CONSOLE_BLINK_COUNT - value for delay loop - blink rate |
4b248f3f | 65 | CONFIG_CONSOLE_TIME - display time/date in upper right corner, |
ddb5d86f | 66 | needs CONFIG_CMD_DATE and CONFIG_CONSOLE_CURSOR |
4b248f3f WD |
67 | CONFIG_VIDEO_LOGO - display Linux Logo in upper left corner |
68 | CONFIG_VIDEO_BMP_LOGO - use bmp_logo instead of linux_logo | |
c609719b | 69 | CONFIG_CONSOLE_EXTRA_INFO - display additional board information strings |
8bde7f77 WD |
70 | that normaly goes to serial port. This define |
71 | requires a board specific function: | |
72 | video_drawstring (VIDEO_INFO_X, | |
73 | VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT, | |
74 | info); | |
75 | that fills a info buffer at i=row. | |
76 | s.a: board/eltec/bab7xx. | |
c609719b | 77 | CONFIG_VGA_AS_SINGLE_DEVICE - If set the framebuffer device will be initialised |
8bde7f77 WD |
78 | as an output only device. The Keyboard driver |
79 | will not be set-up. This may be used, if you | |
80 | have none or more than one Keyboard devices | |
81 | (USB Keyboard, AT Keyboard). | |
c609719b | 82 | |
4b248f3f | 83 | CONFIG_VIDEO_SW_CURSOR: - Draws a cursor after the last character. No |
8bde7f77 WD |
84 | blinking is provided. Uses the macros CURSOR_SET |
85 | and CURSOR_OFF. | |
4b248f3f | 86 | CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the |
8bde7f77 WD |
87 | graphic chip. Uses the macro CURSOR_SET. |
88 | ATTENTION: If booting an OS, the display driver | |
89 | must disable the hardware register of the graphic | |
90 | chip. Otherwise a blinking field is displayed | |
c609719b WD |
91 | */ |
92 | ||
93 | #include <common.h> | |
94 | ||
95 | #ifdef CONFIG_CFB_CONSOLE | |
96 | ||
a6c7ad2f WD |
97 | #include <malloc.h> |
98 | ||
c609719b | 99 | /*****************************************************************************/ |
4b248f3f WD |
100 | /* Console device defines with SMI graphic */ |
101 | /* Any other graphic must change this section */ | |
c609719b WD |
102 | /*****************************************************************************/ |
103 | ||
4b248f3f | 104 | #ifdef CONFIG_VIDEO_SMI_LYNXEM |
c609719b WD |
105 | |
106 | #define VIDEO_FB_LITTLE_ENDIAN | |
107 | #define VIDEO_HW_RECTFILL | |
108 | #define VIDEO_HW_BITBLT | |
109 | #endif | |
110 | ||
111 | /*****************************************************************************/ | |
4b248f3f | 112 | /* Defines for the CT69000 driver */ |
c609719b | 113 | /*****************************************************************************/ |
4b248f3f | 114 | #ifdef CONFIG_VIDEO_CT69000 |
c609719b WD |
115 | |
116 | #define VIDEO_FB_LITTLE_ENDIAN | |
117 | #define VIDEO_HW_RECTFILL | |
118 | #define VIDEO_HW_BITBLT | |
119 | #endif | |
120 | ||
a6c7ad2f | 121 | /*****************************************************************************/ |
4b248f3f | 122 | /* Defines for the SED13806 driver */ |
a6c7ad2f WD |
123 | /*****************************************************************************/ |
124 | #ifdef CONFIG_VIDEO_SED13806 | |
125 | ||
89394047 | 126 | #ifndef CONFIG_TOTAL5200 |
a6c7ad2f | 127 | #define VIDEO_FB_LITTLE_ENDIAN |
89394047 | 128 | #endif |
a6c7ad2f WD |
129 | #define VIDEO_HW_RECTFILL |
130 | #define VIDEO_HW_BITBLT | |
131 | #endif | |
132 | ||
98f4a3df SR |
133 | /*****************************************************************************/ |
134 | /* Defines for the SED13806 driver */ | |
135 | /*****************************************************************************/ | |
136 | #ifdef CONFIG_VIDEO_SM501 | |
137 | ||
138 | #ifdef CONFIG_HH405 | |
139 | #define VIDEO_FB_LITTLE_ENDIAN | |
140 | #endif | |
141 | #endif | |
142 | ||
c609719b | 143 | /*****************************************************************************/ |
4b248f3f | 144 | /* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc */ |
c609719b WD |
145 | /*****************************************************************************/ |
146 | #include <video_fb.h> | |
147 | ||
148 | /*****************************************************************************/ | |
4b248f3f | 149 | /* some Macros */ |
c609719b | 150 | /*****************************************************************************/ |
4b248f3f WD |
151 | #define VIDEO_VISIBLE_COLS (pGD->winSizeX) |
152 | #define VIDEO_VISIBLE_ROWS (pGD->winSizeY) | |
153 | #define VIDEO_PIXEL_SIZE (pGD->gdfBytesPP) | |
154 | #define VIDEO_DATA_FORMAT (pGD->gdfIndex) | |
155 | #define VIDEO_FB_ADRS (pGD->frameAdrs) | |
c609719b WD |
156 | |
157 | /*****************************************************************************/ | |
4b248f3f WD |
158 | /* Console device defines with i8042 keyboard controller */ |
159 | /* Any other keyboard controller must change this section */ | |
c609719b WD |
160 | /*****************************************************************************/ |
161 | ||
4b248f3f | 162 | #ifdef CONFIG_I8042_KBD |
c609719b WD |
163 | #include <i8042.h> |
164 | ||
4b248f3f WD |
165 | #define VIDEO_KBD_INIT_FCT i8042_kbd_init() |
166 | #define VIDEO_TSTC_FCT i8042_tstc | |
167 | #define VIDEO_GETC_FCT i8042_getc | |
c609719b WD |
168 | #endif |
169 | ||
170 | /*****************************************************************************/ | |
4b248f3f | 171 | /* Console device */ |
c609719b WD |
172 | /*****************************************************************************/ |
173 | ||
174 | #include <version.h> | |
175 | #include <linux/types.h> | |
176 | #include <devices.h> | |
177 | #include <video_font.h> | |
c609719b | 178 | |
ddb5d86f JL |
179 | #if defined(CONFIG_CMD_DATE) |
180 | #include <rtc.h> | |
c609719b WD |
181 | #endif |
182 | ||
07d38a17 | 183 | #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) |
4b248f3f WD |
184 | #include <watchdog.h> |
185 | #include <bmp_layout.h> | |
07d38a17 | 186 | #endif |
4b248f3f | 187 | |
c609719b | 188 | /*****************************************************************************/ |
4b248f3f | 189 | /* Cursor definition: */ |
7817cb20 MZ |
190 | /* CONFIG_CONSOLE_CURSOR: Uses a timer function (see drivers/input/i8042.c) */ |
191 | /* to let the cursor blink. Uses the macros */ | |
192 | /* CURSOR_OFF and CURSOR_ON. */ | |
4b248f3f WD |
193 | /* CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No */ |
194 | /* blinking is provided. Uses the macros CURSOR_SET */ | |
195 | /* and CURSOR_OFF. */ | |
196 | /* CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the */ | |
197 | /* graphic chip. Uses the macro CURSOR_SET. */ | |
198 | /* ATTENTION: If booting an OS, the display driver */ | |
199 | /* must disable the hardware register of the graphic */ | |
200 | /* chip. Otherwise a blinking field is displayed */ | |
c609719b WD |
201 | /*****************************************************************************/ |
202 | #if !defined(CONFIG_CONSOLE_CURSOR) && \ | |
203 | !defined(CONFIG_VIDEO_SW_CURSOR) && \ | |
204 | !defined(CONFIG_VIDEO_HW_CURSOR) | |
205 | /* no Cursor defined */ | |
206 | #define CURSOR_ON | |
207 | #define CURSOR_OFF | |
208 | #define CURSOR_SET | |
209 | #endif | |
210 | ||
4b248f3f WD |
211 | #ifdef CONFIG_CONSOLE_CURSOR |
212 | #ifdef CURSOR_ON | |
213 | #error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined | |
c609719b | 214 | #endif |
4b248f3f | 215 | void console_cursor (int state); |
c609719b WD |
216 | #define CURSOR_ON console_cursor(1); |
217 | #define CURSOR_OFF console_cursor(0); | |
218 | #define CURSOR_SET | |
219 | #ifndef CONFIG_I8042_KBD | |
7817cb20 | 220 | #warning Cursor drawing on/off needs timer function s.a. drivers/input/i8042.c |
c609719b WD |
221 | #endif |
222 | #else | |
4b248f3f WD |
223 | #ifdef CONFIG_CONSOLE_TIME |
224 | #error CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME | |
c609719b WD |
225 | #endif |
226 | #endif /* CONFIG_CONSOLE_CURSOR */ | |
227 | ||
4b248f3f WD |
228 | #ifdef CONFIG_VIDEO_SW_CURSOR |
229 | #ifdef CURSOR_ON | |
230 | #error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined | |
c609719b WD |
231 | #endif |
232 | #define CURSOR_ON | |
233 | #define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\ | |
8bde7f77 | 234 | console_row * VIDEO_FONT_HEIGHT, ' '); |
c609719b WD |
235 | #define CURSOR_SET video_set_cursor(); |
236 | #endif /* CONFIG_VIDEO_SW_CURSOR */ | |
237 | ||
238 | ||
239 | #ifdef CONFIG_VIDEO_HW_CURSOR | |
4b248f3f WD |
240 | #ifdef CURSOR_ON |
241 | #error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined | |
c609719b WD |
242 | #endif |
243 | #define CURSOR_ON | |
244 | #define CURSOR_OFF | |
245 | #define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \ | |
8bde7f77 | 246 | (console_row * VIDEO_FONT_HEIGHT) + VIDEO_LOGO_HEIGHT); |
4b248f3f | 247 | #endif /* CONFIG_VIDEO_HW_CURSOR */ |
c609719b | 248 | |
4b248f3f WD |
249 | #ifdef CONFIG_VIDEO_LOGO |
250 | #ifdef CONFIG_VIDEO_BMP_LOGO | |
a6c7ad2f | 251 | #include <bmp_logo.h> |
4b248f3f WD |
252 | #define VIDEO_LOGO_WIDTH BMP_LOGO_WIDTH |
253 | #define VIDEO_LOGO_HEIGHT BMP_LOGO_HEIGHT | |
254 | #define VIDEO_LOGO_LUT_OFFSET BMP_LOGO_OFFSET | |
255 | #define VIDEO_LOGO_COLORS BMP_LOGO_COLORS | |
256 | ||
257 | #else /* CONFIG_VIDEO_BMP_LOGO */ | |
258 | #define LINUX_LOGO_WIDTH 80 | |
259 | #define LINUX_LOGO_HEIGHT 80 | |
260 | #define LINUX_LOGO_COLORS 214 | |
261 | #define LINUX_LOGO_LUT_OFFSET 0x20 | |
c609719b WD |
262 | #define __initdata |
263 | #include <linux_logo.h> | |
4b248f3f WD |
264 | #define VIDEO_LOGO_WIDTH LINUX_LOGO_WIDTH |
265 | #define VIDEO_LOGO_HEIGHT LINUX_LOGO_HEIGHT | |
266 | #define VIDEO_LOGO_LUT_OFFSET LINUX_LOGO_LUT_OFFSET | |
267 | #define VIDEO_LOGO_COLORS LINUX_LOGO_COLORS | |
268 | #endif /* CONFIG_VIDEO_BMP_LOGO */ | |
269 | #define VIDEO_INFO_X (VIDEO_LOGO_WIDTH) | |
270 | #define VIDEO_INFO_Y (VIDEO_FONT_HEIGHT/2) | |
271 | #else /* CONFIG_VIDEO_LOGO */ | |
272 | #define VIDEO_LOGO_WIDTH 0 | |
273 | #define VIDEO_LOGO_HEIGHT 0 | |
274 | #endif /* CONFIG_VIDEO_LOGO */ | |
275 | ||
276 | #define VIDEO_COLS VIDEO_VISIBLE_COLS | |
277 | #define VIDEO_ROWS VIDEO_VISIBLE_ROWS | |
278 | #define VIDEO_SIZE (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE) | |
279 | #define VIDEO_PIX_BLOCKS (VIDEO_SIZE >> 2) | |
280 | #define VIDEO_LINE_LEN (VIDEO_COLS*VIDEO_PIXEL_SIZE) | |
281 | #define VIDEO_BURST_LEN (VIDEO_COLS/8) | |
282 | ||
283 | #ifdef CONFIG_VIDEO_LOGO | |
284 | #define CONSOLE_ROWS ((VIDEO_ROWS - VIDEO_LOGO_HEIGHT) / VIDEO_FONT_HEIGHT) | |
c609719b | 285 | #else |
4b248f3f | 286 | #define CONSOLE_ROWS (VIDEO_ROWS / VIDEO_FONT_HEIGHT) |
c609719b WD |
287 | #endif |
288 | ||
4b248f3f WD |
289 | #define CONSOLE_COLS (VIDEO_COLS / VIDEO_FONT_WIDTH) |
290 | #define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN) | |
291 | #define CONSOLE_ROW_FIRST (video_console_address) | |
292 | #define CONSOLE_ROW_SECOND (video_console_address + CONSOLE_ROW_SIZE) | |
293 | #define CONSOLE_ROW_LAST (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE) | |
294 | #define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS) | |
295 | #define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE) | |
c609719b WD |
296 | |
297 | /* Macros */ | |
4b248f3f WD |
298 | #ifdef VIDEO_FB_LITTLE_ENDIAN |
299 | #define SWAP16(x) ((((x) & 0x00ff) << 8) | ( (x) >> 8)) | |
300 | #define SWAP32(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\ | |
8bde7f77 | 301 | (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) ) |
4b248f3f | 302 | #define SHORTSWAP32(x) ((((x) & 0x000000ff) << 8) | (((x) & 0x0000ff00) >> 8)|\ |
8bde7f77 | 303 | (((x) & 0x00ff0000) << 8) | (((x) & 0xff000000) >> 8) ) |
c609719b | 304 | #else |
4b248f3f WD |
305 | #define SWAP16(x) (x) |
306 | #define SWAP32(x) (x) | |
307 | #define SHORTSWAP32(x) (x) | |
c609719b WD |
308 | #endif |
309 | ||
310 | #if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE) | |
4b248f3f | 311 | #define PRINTD(x) printf(x) |
c609719b WD |
312 | #else |
313 | #define PRINTD(x) | |
314 | #endif | |
315 | ||
316 | ||
317 | #ifdef CONFIG_CONSOLE_EXTRA_INFO | |
318 | extern void video_get_info_str ( /* setup a board string: type, speed, etc. */ | |
4b248f3f WD |
319 | int line_number, /* location to place info string beside logo */ |
320 | char *info /* buffer for info string */ | |
c609719b WD |
321 | ); |
322 | ||
323 | #endif | |
324 | ||
325 | /* Locals */ | |
326 | static GraphicDevice *pGD; /* Pointer to Graphic array */ | |
327 | ||
4b248f3f WD |
328 | static void *video_fb_address; /* frame buffer address */ |
329 | static void *video_console_address; /* console buffer start address */ | |
c609719b WD |
330 | |
331 | static int console_col = 0; /* cursor col */ | |
332 | static int console_row = 0; /* cursor row */ | |
333 | ||
334 | static u32 eorx, fgx, bgx; /* color pats */ | |
335 | ||
336 | static const int video_font_draw_table8[] = { | |
8bde7f77 WD |
337 | 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff, |
338 | 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff, | |
339 | 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff, | |
340 | 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff }; | |
c609719b WD |
341 | |
342 | static const int video_font_draw_table15[] = { | |
8bde7f77 | 343 | 0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff }; |
c609719b WD |
344 | |
345 | static const int video_font_draw_table16[] = { | |
8bde7f77 | 346 | 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff }; |
c609719b WD |
347 | |
348 | static const int video_font_draw_table24[16][3] = { | |
8bde7f77 WD |
349 | { 0x00000000, 0x00000000, 0x00000000 }, |
350 | { 0x00000000, 0x00000000, 0x00ffffff }, | |
351 | { 0x00000000, 0x0000ffff, 0xff000000 }, | |
352 | { 0x00000000, 0x0000ffff, 0xffffffff }, | |
353 | { 0x000000ff, 0xffff0000, 0x00000000 }, | |
354 | { 0x000000ff, 0xffff0000, 0x00ffffff }, | |
355 | { 0x000000ff, 0xffffffff, 0xff000000 }, | |
356 | { 0x000000ff, 0xffffffff, 0xffffffff }, | |
357 | { 0xffffff00, 0x00000000, 0x00000000 }, | |
358 | { 0xffffff00, 0x00000000, 0x00ffffff }, | |
359 | { 0xffffff00, 0x0000ffff, 0xff000000 }, | |
360 | { 0xffffff00, 0x0000ffff, 0xffffffff }, | |
361 | { 0xffffffff, 0xffff0000, 0x00000000 }, | |
362 | { 0xffffffff, 0xffff0000, 0x00ffffff }, | |
363 | { 0xffffffff, 0xffffffff, 0xff000000 }, | |
364 | { 0xffffffff, 0xffffffff, 0xffffffff } }; | |
c609719b WD |
365 | |
366 | static const int video_font_draw_table32[16][4] = { | |
8bde7f77 WD |
367 | { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, |
368 | { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff }, | |
369 | { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 }, | |
370 | { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff }, | |
371 | { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 }, | |
372 | { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff }, | |
373 | { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 }, | |
374 | { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff }, | |
375 | { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 }, | |
376 | { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff }, | |
377 | { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 }, | |
378 | { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff }, | |
379 | { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 }, | |
380 | { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff }, | |
381 | { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 }, | |
382 | { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } }; | |
c609719b WD |
383 | |
384 | ||
98f4a3df SR |
385 | int gunzip(void *, int, unsigned char *, unsigned long *); |
386 | ||
c609719b WD |
387 | /******************************************************************************/ |
388 | ||
c609719b WD |
389 | static void video_drawchars (int xx, int yy, unsigned char *s, int count) |
390 | { | |
4b248f3f WD |
391 | u8 *cdat, *dest, *dest0; |
392 | int rows, offset, c; | |
393 | ||
394 | offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE; | |
395 | dest0 = video_fb_address + offset; | |
396 | ||
397 | switch (VIDEO_DATA_FORMAT) { | |
398 | case GDF__8BIT_INDEX: | |
399 | case GDF__8BIT_332RGB: | |
400 | while (count--) { | |
401 | c = *s; | |
402 | cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; | |
403 | for (rows = VIDEO_FONT_HEIGHT, dest = dest0; | |
404 | rows--; | |
405 | dest += VIDEO_LINE_LEN) { | |
406 | u8 bits = *cdat++; | |
407 | ||
408 | ((u32 *) dest)[0] = (video_font_draw_table8[bits >> 4] & eorx) ^ bgx; | |
409 | ((u32 *) dest)[1] = (video_font_draw_table8[bits & 15] & eorx) ^ bgx; | |
410 | } | |
411 | dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; | |
412 | s++; | |
413 | } | |
414 | break; | |
c609719b | 415 | |
4b248f3f WD |
416 | case GDF_15BIT_555RGB: |
417 | while (count--) { | |
418 | c = *s; | |
419 | cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; | |
420 | for (rows = VIDEO_FONT_HEIGHT, dest = dest0; | |
421 | rows--; | |
422 | dest += VIDEO_LINE_LEN) { | |
423 | u8 bits = *cdat++; | |
424 | ||
425 | ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 6] & eorx) ^ bgx); | |
426 | ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 4 & 3] & eorx) ^ bgx); | |
427 | ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 2 & 3] & eorx) ^ bgx); | |
428 | ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table15 [bits & 3] & eorx) ^ bgx); | |
429 | } | |
430 | dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; | |
431 | s++; | |
432 | } | |
433 | break; | |
c609719b | 434 | |
4b248f3f WD |
435 | case GDF_16BIT_565RGB: |
436 | while (count--) { | |
437 | c = *s; | |
438 | cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; | |
439 | for (rows = VIDEO_FONT_HEIGHT, dest = dest0; | |
440 | rows--; | |
441 | dest += VIDEO_LINE_LEN) { | |
442 | u8 bits = *cdat++; | |
443 | ||
444 | ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 6] & eorx) ^ bgx); | |
445 | ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 4 & 3] & eorx) ^ bgx); | |
446 | ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 2 & 3] & eorx) ^ bgx); | |
447 | ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table16 [bits & 3] & eorx) ^ bgx); | |
448 | } | |
449 | dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; | |
450 | s++; | |
451 | } | |
452 | break; | |
c609719b | 453 | |
4b248f3f WD |
454 | case GDF_32BIT_X888RGB: |
455 | while (count--) { | |
456 | c = *s; | |
457 | cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; | |
458 | for (rows = VIDEO_FONT_HEIGHT, dest = dest0; | |
459 | rows--; | |
460 | dest += VIDEO_LINE_LEN) { | |
461 | u8 bits = *cdat++; | |
462 | ||
463 | ((u32 *) dest)[0] = SWAP32 ((video_font_draw_table32 [bits >> 4][0] & eorx) ^ bgx); | |
464 | ((u32 *) dest)[1] = SWAP32 ((video_font_draw_table32 [bits >> 4][1] & eorx) ^ bgx); | |
465 | ((u32 *) dest)[2] = SWAP32 ((video_font_draw_table32 [bits >> 4][2] & eorx) ^ bgx); | |
466 | ((u32 *) dest)[3] = SWAP32 ((video_font_draw_table32 [bits >> 4][3] & eorx) ^ bgx); | |
467 | ((u32 *) dest)[4] = SWAP32 ((video_font_draw_table32 [bits & 15][0] & eorx) ^ bgx); | |
468 | ((u32 *) dest)[5] = SWAP32 ((video_font_draw_table32 [bits & 15][1] & eorx) ^ bgx); | |
469 | ((u32 *) dest)[6] = SWAP32 ((video_font_draw_table32 [bits & 15][2] & eorx) ^ bgx); | |
470 | ((u32 *) dest)[7] = SWAP32 ((video_font_draw_table32 [bits & 15][3] & eorx) ^ bgx); | |
471 | } | |
472 | dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; | |
473 | s++; | |
474 | } | |
475 | break; | |
c609719b | 476 | |
4b248f3f WD |
477 | case GDF_24BIT_888RGB: |
478 | while (count--) { | |
479 | c = *s; | |
480 | cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; | |
481 | for (rows = VIDEO_FONT_HEIGHT, dest = dest0; | |
482 | rows--; | |
483 | dest += VIDEO_LINE_LEN) { | |
484 | u8 bits = *cdat++; | |
485 | ||
486 | ((u32 *) dest)[0] = (video_font_draw_table24[bits >> 4][0] & eorx) ^ bgx; | |
487 | ((u32 *) dest)[1] = (video_font_draw_table24[bits >> 4][1] & eorx) ^ bgx; | |
488 | ((u32 *) dest)[2] = (video_font_draw_table24[bits >> 4][2] & eorx) ^ bgx; | |
489 | ((u32 *) dest)[3] = (video_font_draw_table24[bits & 15][0] & eorx) ^ bgx; | |
490 | ((u32 *) dest)[4] = (video_font_draw_table24[bits & 15][1] & eorx) ^ bgx; | |
491 | ((u32 *) dest)[5] = (video_font_draw_table24[bits & 15][2] & eorx) ^ bgx; | |
492 | } | |
493 | dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; | |
494 | s++; | |
495 | } | |
496 | break; | |
8bde7f77 | 497 | } |
c609719b WD |
498 | } |
499 | ||
500 | /*****************************************************************************/ | |
501 | ||
4b248f3f | 502 | static inline void video_drawstring (int xx, int yy, unsigned char *s) |
c609719b | 503 | { |
77ddac94 | 504 | video_drawchars (xx, yy, s, strlen ((char *)s)); |
c609719b WD |
505 | } |
506 | ||
507 | /*****************************************************************************/ | |
508 | ||
4b248f3f | 509 | static void video_putchar (int xx, int yy, unsigned char c) |
c609719b | 510 | { |
4b248f3f | 511 | video_drawchars (xx, yy + VIDEO_LOGO_HEIGHT, &c, 1); |
c609719b WD |
512 | } |
513 | ||
514 | /*****************************************************************************/ | |
515 | #if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR) | |
4b248f3f | 516 | static void video_set_cursor (void) |
c609719b | 517 | { |
4b248f3f WD |
518 | /* swap drawing colors */ |
519 | eorx = fgx; | |
520 | fgx = bgx; | |
521 | bgx = eorx; | |
522 | eorx = fgx ^ bgx; | |
523 | /* draw cursor */ | |
524 | video_putchar (console_col * VIDEO_FONT_WIDTH, | |
525 | console_row * VIDEO_FONT_HEIGHT, | |
526 | ' '); | |
527 | /* restore drawing colors */ | |
528 | eorx = fgx; | |
529 | fgx = bgx; | |
530 | bgx = eorx; | |
531 | eorx = fgx ^ bgx; | |
c609719b WD |
532 | } |
533 | #endif | |
534 | /*****************************************************************************/ | |
535 | #ifdef CONFIG_CONSOLE_CURSOR | |
536 | void console_cursor (int state) | |
537 | { | |
4b248f3f WD |
538 | static int last_state = 0; |
539 | ||
c609719b | 540 | #ifdef CONFIG_CONSOLE_TIME |
4b248f3f WD |
541 | struct rtc_time tm; |
542 | char info[16]; | |
543 | ||
544 | /* time update only if cursor is on (faster scroll) */ | |
545 | if (state) { | |
546 | rtc_get (&tm); | |
547 | ||
548 | sprintf (info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min, | |
549 | tm.tm_sec); | |
550 | video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH, | |
77ddac94 | 551 | VIDEO_INFO_Y, (uchar *)info); |
4b248f3f WD |
552 | |
553 | sprintf (info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon, | |
554 | tm.tm_year); | |
555 | video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH, | |
77ddac94 | 556 | VIDEO_INFO_Y + 1 * VIDEO_FONT_HEIGHT, (uchar *)info); |
4b248f3f | 557 | } |
c609719b WD |
558 | #endif |
559 | ||
4b248f3f WD |
560 | if (state && (last_state != state)) { |
561 | video_set_cursor (); | |
562 | } | |
c609719b | 563 | |
4b248f3f WD |
564 | if (!state && (last_state != state)) { |
565 | /* clear cursor */ | |
566 | video_putchar (console_col * VIDEO_FONT_WIDTH, | |
567 | console_row * VIDEO_FONT_HEIGHT, | |
568 | ' '); | |
569 | } | |
c609719b | 570 | |
4b248f3f | 571 | last_state = state; |
c609719b WD |
572 | } |
573 | #endif | |
574 | ||
575 | /*****************************************************************************/ | |
576 | ||
577 | #ifndef VIDEO_HW_RECTFILL | |
578 | static void memsetl (int *p, int c, int v) | |
579 | { | |
4b248f3f WD |
580 | while (c--) |
581 | *(p++) = v; | |
c609719b WD |
582 | } |
583 | #endif | |
584 | ||
585 | /*****************************************************************************/ | |
586 | ||
587 | #ifndef VIDEO_HW_BITBLT | |
588 | static void memcpyl (int *d, int *s, int c) | |
589 | { | |
4b248f3f WD |
590 | while (c--) |
591 | *(d++) = *(s++); | |
c609719b WD |
592 | } |
593 | #endif | |
594 | ||
595 | /*****************************************************************************/ | |
596 | ||
597 | static void console_scrollup (void) | |
598 | { | |
4b248f3f | 599 | /* copy up rows ignoring the first one */ |
c609719b WD |
600 | |
601 | #ifdef VIDEO_HW_BITBLT | |
4b248f3f WD |
602 | video_hw_bitblt (VIDEO_PIXEL_SIZE, /* bytes per pixel */ |
603 | 0, /* source pos x */ | |
604 | VIDEO_LOGO_HEIGHT + VIDEO_FONT_HEIGHT, /* source pos y */ | |
605 | 0, /* dest pos x */ | |
606 | VIDEO_LOGO_HEIGHT, /* dest pos y */ | |
607 | VIDEO_VISIBLE_COLS, /* frame width */ | |
608 | VIDEO_VISIBLE_ROWS - VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT /* frame height */ | |
609 | ); | |
c609719b | 610 | #else |
4b248f3f WD |
611 | memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, |
612 | CONSOLE_SCROLL_SIZE >> 2); | |
c609719b WD |
613 | #endif |
614 | ||
4b248f3f | 615 | /* clear the last one */ |
c609719b | 616 | #ifdef VIDEO_HW_RECTFILL |
4b248f3f WD |
617 | video_hw_rectfill (VIDEO_PIXEL_SIZE, /* bytes per pixel */ |
618 | 0, /* dest pos x */ | |
619 | VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT, /* dest pos y */ | |
620 | VIDEO_VISIBLE_COLS, /* frame width */ | |
621 | VIDEO_FONT_HEIGHT, /* frame height */ | |
622 | CONSOLE_BG_COL /* fill color */ | |
623 | ); | |
c609719b | 624 | #else |
4b248f3f | 625 | memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL); |
c609719b WD |
626 | #endif |
627 | } | |
628 | ||
629 | /*****************************************************************************/ | |
630 | ||
631 | static void console_back (void) | |
632 | { | |
4b248f3f WD |
633 | CURSOR_OFF console_col--; |
634 | ||
635 | if (console_col < 0) { | |
636 | console_col = CONSOLE_COLS - 1; | |
637 | console_row--; | |
638 | if (console_row < 0) | |
639 | console_row = 0; | |
640 | } | |
641 | video_putchar (console_col * VIDEO_FONT_WIDTH, | |
642 | console_row * VIDEO_FONT_HEIGHT, | |
643 | ' '); | |
c609719b WD |
644 | } |
645 | ||
646 | /*****************************************************************************/ | |
647 | ||
648 | static void console_newline (void) | |
649 | { | |
4b248f3f WD |
650 | CURSOR_OFF console_row++; |
651 | console_col = 0; | |
652 | ||
653 | /* Check if we need to scroll the terminal */ | |
654 | if (console_row >= CONSOLE_ROWS) { | |
655 | /* Scroll everything up */ | |
656 | console_scrollup (); | |
657 | ||
658 | /* Decrement row number */ | |
659 | console_row--; | |
660 | } | |
c609719b WD |
661 | } |
662 | ||
663 | /*****************************************************************************/ | |
664 | ||
665 | void video_putc (const char c) | |
666 | { | |
4b248f3f WD |
667 | switch (c) { |
668 | case 13: /* ignore */ | |
669 | break; | |
c609719b | 670 | |
4b248f3f WD |
671 | case '\n': /* next line */ |
672 | console_newline (); | |
673 | break; | |
674 | ||
675 | case 9: /* tab 8 */ | |
676 | CURSOR_OFF console_col |= 0x0008; | |
677 | console_col &= ~0x0007; | |
c609719b | 678 | |
4b248f3f WD |
679 | if (console_col >= CONSOLE_COLS) |
680 | console_newline (); | |
681 | break; | |
c609719b | 682 | |
4b248f3f WD |
683 | case 8: /* backspace */ |
684 | console_back (); | |
685 | break; | |
c609719b | 686 | |
4b248f3f WD |
687 | default: /* draw the char */ |
688 | video_putchar (console_col * VIDEO_FONT_WIDTH, | |
689 | console_row * VIDEO_FONT_HEIGHT, | |
690 | c); | |
691 | console_col++; | |
c609719b | 692 | |
4b248f3f WD |
693 | /* check for newline */ |
694 | if (console_col >= CONSOLE_COLS) | |
695 | console_newline (); | |
696 | } | |
697 | CURSOR_SET} | |
c609719b WD |
698 | |
699 | ||
c609719b WD |
700 | /*****************************************************************************/ |
701 | ||
702 | void video_puts (const char *s) | |
703 | { | |
4b248f3f WD |
704 | int count = strlen (s); |
705 | ||
706 | while (count--) | |
707 | video_putc (*s++); | |
708 | } | |
709 | ||
710 | /*****************************************************************************/ | |
711 | ||
07d38a17 | 712 | #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) |
4b248f3f WD |
713 | |
714 | #define FILL_8BIT_332RGB(r,g,b) { \ | |
715 | *fb = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6); \ | |
716 | fb ++; \ | |
717 | } | |
718 | ||
719 | #define FILL_15BIT_555RGB(r,g,b) { \ | |
720 | *(unsigned short *)fb = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \ | |
721 | fb += 2; \ | |
722 | } | |
723 | ||
724 | #define FILL_16BIT_565RGB(r,g,b) { \ | |
725 | *(unsigned short *)fb = SWAP16((unsigned short)((((r)>>3)<<11) | (((g)>>2)<<5) | ((b)>>3))); \ | |
726 | fb += 2; \ | |
727 | } | |
728 | ||
729 | #define FILL_32BIT_X888RGB(r,g,b) { \ | |
730 | *(unsigned long *)fb = SWAP32((unsigned long)(((r<<16) | (g<<8) | b))); \ | |
731 | fb += 4; \ | |
732 | } | |
733 | ||
734 | #ifdef VIDEO_FB_LITTLE_ENDIAN | |
735 | #define FILL_24BIT_888RGB(r,g,b) { \ | |
736 | fb[0] = b; \ | |
737 | fb[1] = g; \ | |
738 | fb[2] = r; \ | |
739 | fb += 3; \ | |
740 | } | |
741 | #else | |
742 | #define FILL_24BIT_888RGB(r,g,b) { \ | |
743 | fb[0] = r; \ | |
744 | fb[1] = g; \ | |
745 | fb[2] = b; \ | |
746 | fb += 3; \ | |
747 | } | |
748 | #endif | |
749 | ||
750 | ||
751 | /* | |
752 | * Display the BMP file located at address bmp_image. | |
753 | * Only uncompressed | |
754 | */ | |
755 | int video_display_bitmap (ulong bmp_image, int x, int y) | |
756 | { | |
757 | ushort xcount, ycount; | |
758 | uchar *fb; | |
759 | bmp_image_t *bmp = (bmp_image_t *) bmp_image; | |
760 | uchar *bmap; | |
761 | ushort padded_line; | |
762 | unsigned long width, height, bpp; | |
763 | unsigned colors; | |
764 | unsigned long compression; | |
765 | bmp_color_table_entry_t cte; | |
98f4a3df SR |
766 | #ifdef CONFIG_VIDEO_BMP_GZIP |
767 | unsigned char *dst = NULL; | |
768 | ulong len; | |
769 | #endif | |
4b248f3f WD |
770 | |
771 | WATCHDOG_RESET (); | |
772 | ||
773 | if (!((bmp->header.signature[0] == 'B') && | |
774 | (bmp->header.signature[1] == 'M'))) { | |
98f4a3df SR |
775 | |
776 | #ifdef CONFIG_VIDEO_BMP_GZIP | |
777 | /* | |
778 | * Could be a gzipped bmp image, try to decrompress... | |
779 | */ | |
780 | len = CFG_VIDEO_LOGO_MAX_SIZE; | |
781 | dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE); | |
c29ab9d7 SR |
782 | if (dst == NULL) { |
783 | printf("Error: malloc in gunzip failed!\n"); | |
784 | return(1); | |
785 | } | |
98f4a3df SR |
786 | if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)bmp_image, &len) != 0) { |
787 | printf ("Error: no valid bmp or bmp.gz image at %lx\n", bmp_image); | |
788 | free(dst); | |
789 | return 1; | |
790 | } | |
c29ab9d7 SR |
791 | if (len == CFG_VIDEO_LOGO_MAX_SIZE) { |
792 | printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n"); | |
793 | } | |
98f4a3df SR |
794 | |
795 | /* | |
796 | * Set addr to decompressed image | |
797 | */ | |
798 | bmp = (bmp_image_t *)dst; | |
799 | ||
800 | if (!((bmp->header.signature[0] == 'B') && | |
801 | (bmp->header.signature[1] == 'M'))) { | |
802 | printf ("Error: no valid bmp.gz image at %lx\n", bmp_image); | |
803 | return 1; | |
804 | } | |
805 | #else | |
4b248f3f WD |
806 | printf ("Error: no valid bmp image at %lx\n", bmp_image); |
807 | return 1; | |
98f4a3df | 808 | #endif /* CONFIG_VIDEO_BMP_GZIP */ |
4b248f3f WD |
809 | } |
810 | ||
811 | width = le32_to_cpu (bmp->header.width); | |
812 | height = le32_to_cpu (bmp->header.height); | |
813 | bpp = le16_to_cpu (bmp->header.bit_count); | |
814 | colors = le32_to_cpu (bmp->header.colors_used); | |
815 | compression = le32_to_cpu (bmp->header.compression); | |
c609719b | 816 | |
4b248f3f WD |
817 | debug ("Display-bmp: %d x %d with %d colors\n", |
818 | width, height, colors); | |
819 | ||
820 | if (compression != BMP_BI_RGB) { | |
821 | printf ("Error: compression type %ld not supported\n", | |
822 | compression); | |
823 | return 1; | |
824 | } | |
825 | ||
826 | padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3; | |
827 | ||
828 | if ((x + width) > VIDEO_VISIBLE_COLS) | |
829 | width = VIDEO_VISIBLE_COLS - x; | |
830 | if ((y + height) > VIDEO_VISIBLE_ROWS) | |
831 | height = VIDEO_VISIBLE_ROWS - y; | |
832 | ||
833 | bmap = (uchar *) bmp + le32_to_cpu (bmp->header.data_offset); | |
834 | fb = (uchar *) (video_fb_address + | |
835 | ((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) + | |
836 | x * VIDEO_PIXEL_SIZE); | |
837 | ||
838 | /* We handle only 8bpp or 24 bpp bitmap */ | |
839 | switch (le16_to_cpu (bmp->header.bit_count)) { | |
840 | case 8: | |
841 | padded_line -= width; | |
842 | if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) { | |
843 | /* Copy colormap */ | |
844 | for (xcount = 0; xcount < colors; ++xcount) { | |
845 | cte = bmp->color_table[xcount]; | |
846 | video_set_lut (xcount, cte.red, cte.green, cte.blue); | |
847 | } | |
848 | } | |
849 | ycount = height; | |
850 | switch (VIDEO_DATA_FORMAT) { | |
851 | case GDF__8BIT_INDEX: | |
852 | while (ycount--) { | |
853 | WATCHDOG_RESET (); | |
854 | xcount = width; | |
855 | while (xcount--) { | |
856 | *fb++ = *bmap++; | |
857 | } | |
858 | bmap += padded_line; | |
859 | fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; | |
860 | } | |
861 | break; | |
862 | case GDF__8BIT_332RGB: | |
863 | while (ycount--) { | |
864 | WATCHDOG_RESET (); | |
865 | xcount = width; | |
866 | while (xcount--) { | |
867 | cte = bmp->color_table[*bmap++]; | |
868 | FILL_8BIT_332RGB (cte.red, cte.green, cte.blue); | |
869 | } | |
870 | bmap += padded_line; | |
871 | fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; | |
872 | } | |
873 | break; | |
874 | case GDF_15BIT_555RGB: | |
875 | while (ycount--) { | |
876 | WATCHDOG_RESET (); | |
877 | xcount = width; | |
878 | while (xcount--) { | |
879 | cte = bmp->color_table[*bmap++]; | |
880 | FILL_15BIT_555RGB (cte.red, cte.green, cte.blue); | |
881 | } | |
882 | bmap += padded_line; | |
883 | fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; | |
884 | } | |
885 | break; | |
886 | case GDF_16BIT_565RGB: | |
887 | while (ycount--) { | |
888 | WATCHDOG_RESET (); | |
889 | xcount = width; | |
890 | while (xcount--) { | |
891 | cte = bmp->color_table[*bmap++]; | |
892 | FILL_16BIT_565RGB (cte.red, cte.green, cte.blue); | |
893 | } | |
894 | bmap += padded_line; | |
895 | fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; | |
896 | } | |
897 | break; | |
898 | case GDF_32BIT_X888RGB: | |
899 | while (ycount--) { | |
900 | WATCHDOG_RESET (); | |
901 | xcount = width; | |
902 | while (xcount--) { | |
903 | cte = bmp->color_table[*bmap++]; | |
904 | FILL_32BIT_X888RGB (cte.red, cte.green, cte.blue); | |
905 | } | |
906 | bmap += padded_line; | |
907 | fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; | |
908 | } | |
909 | break; | |
910 | case GDF_24BIT_888RGB: | |
911 | while (ycount--) { | |
912 | WATCHDOG_RESET (); | |
913 | xcount = width; | |
914 | while (xcount--) { | |
915 | cte = bmp->color_table[*bmap++]; | |
916 | FILL_24BIT_888RGB (cte.red, cte.green, cte.blue); | |
917 | } | |
918 | bmap += padded_line; | |
919 | fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; | |
920 | } | |
921 | break; | |
922 | } | |
923 | break; | |
924 | case 24: | |
925 | padded_line -= 3 * width; | |
926 | ycount = height; | |
927 | switch (VIDEO_DATA_FORMAT) { | |
928 | case GDF__8BIT_332RGB: | |
929 | while (ycount--) { | |
930 | WATCHDOG_RESET (); | |
931 | xcount = width; | |
932 | while (xcount--) { | |
933 | FILL_8BIT_332RGB (bmap[2], bmap[1], bmap[0]); | |
934 | bmap += 3; | |
935 | } | |
936 | bmap += padded_line; | |
937 | fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; | |
938 | } | |
939 | break; | |
940 | case GDF_15BIT_555RGB: | |
941 | while (ycount--) { | |
942 | WATCHDOG_RESET (); | |
943 | xcount = width; | |
944 | while (xcount--) { | |
945 | FILL_15BIT_555RGB (bmap[2], bmap[1], bmap[0]); | |
946 | bmap += 3; | |
947 | } | |
948 | bmap += padded_line; | |
949 | fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; | |
950 | } | |
951 | break; | |
952 | case GDF_16BIT_565RGB: | |
953 | while (ycount--) { | |
954 | WATCHDOG_RESET (); | |
955 | xcount = width; | |
956 | while (xcount--) { | |
957 | FILL_16BIT_565RGB (bmap[2], bmap[1], bmap[0]); | |
958 | bmap += 3; | |
959 | } | |
960 | bmap += padded_line; | |
961 | fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; | |
962 | } | |
963 | break; | |
964 | case GDF_32BIT_X888RGB: | |
965 | while (ycount--) { | |
966 | WATCHDOG_RESET (); | |
967 | xcount = width; | |
968 | while (xcount--) { | |
969 | FILL_32BIT_X888RGB (bmap[2], bmap[1], bmap[0]); | |
970 | bmap += 3; | |
971 | } | |
972 | bmap += padded_line; | |
973 | fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; | |
974 | } | |
975 | break; | |
976 | case GDF_24BIT_888RGB: | |
977 | while (ycount--) { | |
978 | WATCHDOG_RESET (); | |
979 | xcount = width; | |
980 | while (xcount--) { | |
981 | FILL_24BIT_888RGB (bmap[2], bmap[1], bmap[0]); | |
982 | bmap += 3; | |
983 | } | |
984 | bmap += padded_line; | |
985 | fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; | |
986 | } | |
987 | break; | |
988 | default: | |
989 | printf ("Error: 24 bits/pixel bitmap incompatible with current video mode\n"); | |
990 | break; | |
991 | } | |
992 | break; | |
993 | default: | |
994 | printf ("Error: %d bit/pixel bitmaps not supported by U-Boot\n", | |
995 | le16_to_cpu (bmp->header.bit_count)); | |
996 | break; | |
997 | } | |
98f4a3df SR |
998 | |
999 | #ifdef CONFIG_VIDEO_BMP_GZIP | |
1000 | if (dst) { | |
1001 | free(dst); | |
1002 | } | |
1003 | #endif | |
1004 | ||
4b248f3f | 1005 | return (0); |
c609719b | 1006 | } |
07d38a17 | 1007 | #endif |
c609719b WD |
1008 | |
1009 | /*****************************************************************************/ | |
1010 | ||
1011 | #ifdef CONFIG_VIDEO_LOGO | |
1012 | void logo_plot (void *screen, int width, int x, int y) | |
1013 | { | |
a6c7ad2f | 1014 | |
4b248f3f WD |
1015 | int xcount, i; |
1016 | int skip = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE; | |
1017 | int ycount = VIDEO_LOGO_HEIGHT; | |
1018 | unsigned char r, g, b, *logo_red, *logo_blue, *logo_green; | |
1019 | unsigned char *source; | |
1020 | unsigned char *dest = (unsigned char *)screen + ((y * width * VIDEO_PIXEL_SIZE) + x); | |
a6c7ad2f WD |
1021 | |
1022 | #ifdef CONFIG_VIDEO_BMP_LOGO | |
4b248f3f WD |
1023 | source = bmp_logo_bitmap; |
1024 | ||
1025 | /* Allocate temporary space for computing colormap */ | |
1026 | logo_red = malloc (BMP_LOGO_COLORS); | |
1027 | logo_green = malloc (BMP_LOGO_COLORS); | |
1028 | logo_blue = malloc (BMP_LOGO_COLORS); | |
1029 | /* Compute color map */ | |
1030 | for (i = 0; i < VIDEO_LOGO_COLORS; i++) { | |
1031 | logo_red[i] = (bmp_logo_palette[i] & 0x0f00) >> 4; | |
1032 | logo_green[i] = (bmp_logo_palette[i] & 0x00f0); | |
1033 | logo_blue[i] = (bmp_logo_palette[i] & 0x000f) << 4; | |
1034 | } | |
a6c7ad2f | 1035 | #else |
4b248f3f WD |
1036 | source = linux_logo; |
1037 | logo_red = linux_logo_red; | |
1038 | logo_green = linux_logo_green; | |
1039 | logo_blue = linux_logo_blue; | |
a6c7ad2f | 1040 | #endif |
8bde7f77 | 1041 | |
4b248f3f WD |
1042 | if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) { |
1043 | for (i = 0; i < VIDEO_LOGO_COLORS; i++) { | |
1044 | video_set_lut (i + VIDEO_LOGO_LUT_OFFSET, | |
1045 | logo_red[i], logo_green[i], logo_blue[i]); | |
1046 | } | |
8bde7f77 | 1047 | } |
c609719b | 1048 | |
4b248f3f WD |
1049 | while (ycount--) { |
1050 | xcount = VIDEO_LOGO_WIDTH; | |
1051 | while (xcount--) { | |
1052 | r = logo_red[*source - VIDEO_LOGO_LUT_OFFSET]; | |
1053 | g = logo_green[*source - VIDEO_LOGO_LUT_OFFSET]; | |
1054 | b = logo_blue[*source - VIDEO_LOGO_LUT_OFFSET]; | |
1055 | ||
1056 | switch (VIDEO_DATA_FORMAT) { | |
1057 | case GDF__8BIT_INDEX: | |
1058 | *dest = *source; | |
1059 | break; | |
1060 | case GDF__8BIT_332RGB: | |
1061 | *dest = ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6); | |
1062 | break; | |
1063 | case GDF_15BIT_555RGB: | |
1064 | *(unsigned short *) dest = | |
1065 | SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3))); | |
1066 | break; | |
1067 | case GDF_16BIT_565RGB: | |
1068 | *(unsigned short *) dest = | |
1069 | SWAP16 ((unsigned short) (((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3))); | |
1070 | break; | |
1071 | case GDF_32BIT_X888RGB: | |
1072 | *(unsigned long *) dest = | |
1073 | SWAP32 ((unsigned long) ((r << 16) | (g << 8) | b)); | |
1074 | break; | |
1075 | case GDF_24BIT_888RGB: | |
c609719b | 1076 | #ifdef VIDEO_FB_LITTLE_ENDIAN |
4b248f3f WD |
1077 | dest[0] = b; |
1078 | dest[1] = g; | |
1079 | dest[2] = r; | |
c609719b | 1080 | #else |
4b248f3f WD |
1081 | dest[0] = r; |
1082 | dest[1] = g; | |
1083 | dest[2] = b; | |
c609719b | 1084 | #endif |
4b248f3f WD |
1085 | break; |
1086 | } | |
1087 | source++; | |
1088 | dest += VIDEO_PIXEL_SIZE; | |
1089 | } | |
1090 | dest += skip; | |
8bde7f77 | 1091 | } |
a6c7ad2f | 1092 | #ifdef CONFIG_VIDEO_BMP_LOGO |
4b248f3f WD |
1093 | free (logo_red); |
1094 | free (logo_green); | |
1095 | free (logo_blue); | |
a6c7ad2f | 1096 | #endif |
c609719b WD |
1097 | } |
1098 | ||
c609719b WD |
1099 | /*****************************************************************************/ |
1100 | ||
1101 | static void *video_logo (void) | |
1102 | { | |
4b248f3f WD |
1103 | char info[128]; |
1104 | extern char version_string; | |
1105 | ||
1106 | #ifdef CONFIG_SPLASH_SCREEN | |
1107 | char *s; | |
1108 | ulong addr; | |
1109 | ||
1110 | if ((s = getenv ("splashimage")) != NULL) { | |
1111 | addr = simple_strtoul (s, NULL, 16); | |
1112 | ||
1113 | if (video_display_bitmap (addr, 0, 0) == 0) { | |
1114 | return ((void *) (video_fb_address)); | |
1115 | } | |
1116 | } | |
1117 | #endif /* CONFIG_SPLASH_SCREEN */ | |
c609719b | 1118 | |
4b248f3f WD |
1119 | logo_plot (video_fb_address, VIDEO_COLS, 0, 0); |
1120 | ||
1121 | sprintf (info, " %s", &version_string); | |
77ddac94 | 1122 | video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *)info); |
c609719b WD |
1123 | |
1124 | #ifdef CONFIG_CONSOLE_EXTRA_INFO | |
4b248f3f WD |
1125 | { |
1126 | int i, n = ((VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT); | |
1127 | ||
1128 | for (i = 1; i < n; i++) { | |
1129 | video_get_info_str (i, info); | |
1130 | if (*info) | |
1131 | video_drawstring (VIDEO_INFO_X, | |
1132 | VIDEO_INFO_Y + i * VIDEO_FONT_HEIGHT, | |
77ddac94 | 1133 | (uchar *)info); |
4b248f3f WD |
1134 | } |
1135 | } | |
c609719b WD |
1136 | #endif |
1137 | ||
4b248f3f | 1138 | return (video_fb_address + VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN); |
c609719b WD |
1139 | } |
1140 | #endif | |
1141 | ||
1142 | ||
1143 | /*****************************************************************************/ | |
1144 | ||
4b248f3f | 1145 | static int video_init (void) |
c609719b | 1146 | { |
4b248f3f | 1147 | unsigned char color8; |
c609719b | 1148 | |
4b248f3f WD |
1149 | if ((pGD = video_hw_init ()) == NULL) |
1150 | return -1; | |
c609719b | 1151 | |
4b248f3f | 1152 | video_fb_address = (void *) VIDEO_FB_ADRS; |
c609719b | 1153 | #ifdef CONFIG_VIDEO_HW_CURSOR |
4b248f3f | 1154 | video_init_hw_cursor (VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT); |
c609719b WD |
1155 | #endif |
1156 | ||
4b248f3f WD |
1157 | /* Init drawing pats */ |
1158 | switch (VIDEO_DATA_FORMAT) { | |
1159 | case GDF__8BIT_INDEX: | |
1160 | video_set_lut (0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL); | |
1161 | video_set_lut (0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL); | |
1162 | fgx = 0x01010101; | |
1163 | bgx = 0x00000000; | |
1164 | break; | |
1165 | case GDF__8BIT_332RGB: | |
1166 | color8 = ((CONSOLE_FG_COL & 0xe0) | | |
1167 | ((CONSOLE_FG_COL >> 3) & 0x1c) | CONSOLE_FG_COL >> 6); | |
1168 | fgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8; | |
1169 | color8 = ((CONSOLE_BG_COL & 0xe0) | | |
1170 | ((CONSOLE_BG_COL >> 3) & 0x1c) | CONSOLE_BG_COL >> 6); | |
1171 | bgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8; | |
1172 | break; | |
1173 | case GDF_15BIT_555RGB: | |
1174 | fgx = (((CONSOLE_FG_COL >> 3) << 26) | | |
1175 | ((CONSOLE_FG_COL >> 3) << 21) | ((CONSOLE_FG_COL >> 3) << 16) | | |
1176 | ((CONSOLE_FG_COL >> 3) << 10) | ((CONSOLE_FG_COL >> 3) << 5) | | |
1177 | (CONSOLE_FG_COL >> 3)); | |
1178 | bgx = (((CONSOLE_BG_COL >> 3) << 26) | | |
1179 | ((CONSOLE_BG_COL >> 3) << 21) | ((CONSOLE_BG_COL >> 3) << 16) | | |
1180 | ((CONSOLE_BG_COL >> 3) << 10) | ((CONSOLE_BG_COL >> 3) << 5) | | |
1181 | (CONSOLE_BG_COL >> 3)); | |
1182 | break; | |
1183 | case GDF_16BIT_565RGB: | |
1184 | fgx = (((CONSOLE_FG_COL >> 3) << 27) | | |
1185 | ((CONSOLE_FG_COL >> 2) << 21) | ((CONSOLE_FG_COL >> 3) << 16) | | |
1186 | ((CONSOLE_FG_COL >> 3) << 11) | ((CONSOLE_FG_COL >> 2) << 5) | | |
1187 | (CONSOLE_FG_COL >> 3)); | |
1188 | bgx = (((CONSOLE_BG_COL >> 3) << 27) | | |
1189 | ((CONSOLE_BG_COL >> 2) << 21) | ((CONSOLE_BG_COL >> 3) << 16) | | |
1190 | ((CONSOLE_BG_COL >> 3) << 11) | ((CONSOLE_BG_COL >> 2) << 5) | | |
1191 | (CONSOLE_BG_COL >> 3)); | |
1192 | break; | |
1193 | case GDF_32BIT_X888RGB: | |
1194 | fgx = (CONSOLE_FG_COL << 16) | (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL; | |
1195 | bgx = (CONSOLE_BG_COL << 16) | (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL; | |
1196 | break; | |
1197 | case GDF_24BIT_888RGB: | |
1198 | fgx = (CONSOLE_FG_COL << 24) | (CONSOLE_FG_COL << 16) | | |
1199 | (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL; | |
1200 | bgx = (CONSOLE_BG_COL << 24) | (CONSOLE_BG_COL << 16) | | |
1201 | (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL; | |
1202 | break; | |
1203 | } | |
1204 | eorx = fgx ^ bgx; | |
c609719b WD |
1205 | |
1206 | #ifdef CONFIG_VIDEO_LOGO | |
4b248f3f WD |
1207 | /* Plot the logo and get start point of console */ |
1208 | PRINTD ("Video: Drawing the logo ...\n"); | |
1209 | video_console_address = video_logo (); | |
c609719b | 1210 | #else |
4b248f3f | 1211 | video_console_address = video_fb_address; |
c609719b WD |
1212 | #endif |
1213 | ||
4b248f3f WD |
1214 | /* Initialize the console */ |
1215 | console_col = 0; | |
1216 | console_row = 0; | |
c609719b | 1217 | |
4b248f3f | 1218 | return 0; |
c609719b WD |
1219 | } |
1220 | ||
1221 | ||
1222 | /*****************************************************************************/ | |
1223 | ||
1224 | int drv_video_init (void) | |
1225 | { | |
4b248f3f WD |
1226 | int skip_dev_init; |
1227 | device_t console_dev; | |
c609719b | 1228 | |
4b248f3f | 1229 | skip_dev_init = 0; |
c609719b | 1230 | |
81050926 WD |
1231 | /* Init video chip - returns with framebuffer cleared */ |
1232 | if (video_init () == -1) | |
1233 | skip_dev_init = 1; | |
1234 | ||
c609719b | 1235 | #ifdef CONFIG_VGA_AS_SINGLE_DEVICE |
4b248f3f WD |
1236 | /* Devices VGA and Keyboard will be assigned seperately */ |
1237 | /* Init vga device */ | |
1238 | if (!skip_dev_init) { | |
1239 | memset (&console_dev, 0, sizeof (console_dev)); | |
1240 | strcpy (console_dev.name, "vga"); | |
1241 | console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */ | |
1242 | console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM; | |
1243 | console_dev.putc = video_putc; /* 'putc' function */ | |
1244 | console_dev.puts = video_puts; /* 'puts' function */ | |
1245 | console_dev.tstc = NULL; /* 'tstc' function */ | |
1246 | console_dev.getc = NULL; /* 'getc' function */ | |
1247 | ||
1248 | if (device_register (&console_dev) == 0) | |
1249 | return 1; | |
1250 | } | |
c609719b | 1251 | #else |
4b248f3f WD |
1252 | PRINTD ("KBD: Keyboard init ...\n"); |
1253 | if (VIDEO_KBD_INIT_FCT == -1) | |
1254 | skip_dev_init = 1; | |
1255 | ||
1256 | /* Init console device */ | |
1257 | if (!skip_dev_init) { | |
1258 | memset (&console_dev, 0, sizeof (console_dev)); | |
b9283e2d | 1259 | strcpy (console_dev.name, "vga"); |
4b248f3f WD |
1260 | console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */ |
1261 | console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; | |
1262 | console_dev.putc = video_putc; /* 'putc' function */ | |
1263 | console_dev.puts = video_puts; /* 'puts' function */ | |
1264 | console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */ | |
1265 | console_dev.getc = VIDEO_GETC_FCT; /* 'getc' function */ | |
1266 | ||
1267 | if (device_register (&console_dev) == 0) | |
1268 | return 1; | |
1269 | } | |
c609719b | 1270 | #endif /* CONFIG_VGA_AS_SINGLE_DEVICE */ |
4b248f3f WD |
1271 | /* No console dev available */ |
1272 | return 0; | |
c609719b | 1273 | } |
c609719b | 1274 | #endif /* CONFIG_CFB_CONSOLE */ |