cfb_console.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955
  1. /*
  2. * (C) Copyright 2002 ELTEC Elektronik AG
  3. * Frank Gottschling <fgottschling@eltec.de>
  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
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  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. * cfb_console.c
  25. *
  26. * Color Framebuffer Console driver for 8/15/16/24/32 bits per pixel.
  27. *
  28. * At the moment only the 8x16 font is tested and the font fore- and
  29. * background color is limited to black/white/gray colors. The Linux
  30. * logo can be placed in the upper left corner and additional board
  31. * information strings (that normaly goes to serial port) can be drawed.
  32. *
  33. * The console driver can use the standard PC keyboard interface (i8042)
  34. * for character input. Character output goes to a memory mapped video
  35. * framebuffer with little or big-endian organisation.
  36. * With environment setting 'console=serial' the console i/o can be
  37. * forced to serial port.
  38. The driver uses graphic specific defines/parameters/functions:
  39. (for SMI LynxE graphic chip)
  40. CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810
  41. VIDEO_FB_LITTLE_ENDIAN - framebuffer organisation default: big endian
  42. VIDEO_HW_RECTFILL - graphic driver supports hardware rectangle fill
  43. VIDEO_HW_BITBLT - graphic driver supports hardware bit blt
  44. Console Parameters are set by graphic drivers global struct:
  45. VIDEO_VISIBLE_COLS - x resolution
  46. VIDEO_VISIBLE_ROWS - y resolution
  47. VIDEO_PIXEL_SIZE - storage size in byte per pixel
  48. VIDEO_DATA_FORMAT - graphical data format GDF
  49. VIDEO_FB_ADRS - start of video memory
  50. CONFIG_I8042_KBD - AT Keyboard driver for i8042
  51. VIDEO_KBD_INIT_FCT - init function for keyboard
  52. VIDEO_TSTC_FCT - keyboard_tstc function
  53. VIDEO_GETC_FCT - keyboard_getc function
  54. CONFIG_CONSOLE_CURSOR - on/off drawing cursor is done with delay
  55. loop in VIDEO_TSTC_FCT (i8042)
  56. CFG_CONSOLE_BLINK_COUNT - value for delay loop - blink rate
  57. CONFIG_CONSOLE_TIME - display time/date in upper right corner,
  58. needs CFG_CMD_DATE and CONFIG_CONSOLE_CURSOR
  59. CONFIG_VIDEO_LOGO - display Linux Logo in upper left corner
  60. CONFIG_VIDEO_BMP_LOGO - use bmp_logo instead of linux_logo
  61. CONFIG_CONSOLE_EXTRA_INFO - display additional board information strings
  62. that normaly goes to serial port. This define
  63. requires a board specific function:
  64. video_drawstring (VIDEO_INFO_X,
  65. VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
  66. info);
  67. that fills a info buffer at i=row.
  68. s.a: board/eltec/bab7xx.
  69. CONFIG_VGA_AS_SINGLE_DEVICE - If set the framebuffer device will be initialised
  70. as an output only device. The Keyboard driver
  71. will not be set-up. This may be used, if you
  72. have none or more than one Keyboard devices
  73. (USB Keyboard, AT Keyboard).
  74. CONFIG_VIDEO_SW_CURSOR: - Draws a cursor after the last character. No
  75. blinking is provided. Uses the macros CURSOR_SET
  76. and CURSOR_OFF.
  77. CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
  78. graphic chip. Uses the macro CURSOR_SET.
  79. ATTENTION: If booting an OS, the display driver
  80. must disable the hardware register of the graphic
  81. chip. Otherwise a blinking field is displayed
  82. */
  83. #include <common.h>
  84. #ifdef CONFIG_CFB_CONSOLE
  85. #include <malloc.h>
  86. /*****************************************************************************/
  87. /* Console device defines with SMI graphic */
  88. /* Any other graphic must change this section */
  89. /*****************************************************************************/
  90. #ifdef CONFIG_VIDEO_SMI_LYNXEM
  91. #define VIDEO_FB_LITTLE_ENDIAN
  92. #define VIDEO_HW_RECTFILL
  93. #define VIDEO_HW_BITBLT
  94. #endif
  95. /*****************************************************************************/
  96. /* Defines for the CT69000 driver */
  97. /*****************************************************************************/
  98. #ifdef CONFIG_VIDEO_CT69000
  99. #define VIDEO_FB_LITTLE_ENDIAN
  100. #define VIDEO_HW_RECTFILL
  101. #define VIDEO_HW_BITBLT
  102. #endif
  103. /*****************************************************************************/
  104. /* Defines for the SED13806 driver */
  105. /*****************************************************************************/
  106. #ifdef CONFIG_VIDEO_SED13806
  107. #define VIDEO_FB_LITTLE_ENDIAN
  108. #define VIDEO_HW_RECTFILL
  109. #define VIDEO_HW_BITBLT
  110. #endif
  111. /*****************************************************************************/
  112. /* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc */
  113. /*****************************************************************************/
  114. #include <video_fb.h>
  115. /*****************************************************************************/
  116. /* some Macros */
  117. /*****************************************************************************/
  118. #define VIDEO_VISIBLE_COLS (pGD->winSizeX)
  119. #define VIDEO_VISIBLE_ROWS (pGD->winSizeY)
  120. #define VIDEO_PIXEL_SIZE (pGD->gdfBytesPP)
  121. #define VIDEO_DATA_FORMAT (pGD->gdfIndex)
  122. #define VIDEO_FB_ADRS (pGD->frameAdrs)
  123. /*****************************************************************************/
  124. /* Console device defines with i8042 keyboard controller */
  125. /* Any other keyboard controller must change this section */
  126. /*****************************************************************************/
  127. #ifdef CONFIG_I8042_KBD
  128. #include <i8042.h>
  129. #define VIDEO_KBD_INIT_FCT i8042_kbd_init()
  130. #define VIDEO_TSTC_FCT i8042_tstc
  131. #define VIDEO_GETC_FCT i8042_getc
  132. #endif
  133. /*****************************************************************************/
  134. /* Console device */
  135. /*****************************************************************************/
  136. #include <version.h>
  137. #include <linux/types.h>
  138. #include <devices.h>
  139. #include <video_font.h>
  140. #ifdef CFG_CMD_DATE
  141. #include <rtc.h>
  142. #endif
  143. /*****************************************************************************/
  144. /* Cursor definition: */
  145. /* CONFIG_CONSOLE_CURSOR: Uses a timer function (see drivers/i8042.c) to */
  146. /* let the cursor blink. Uses the macros CURSOR_OFF */
  147. /* and CURSOR_ON. */
  148. /* CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No */
  149. /* blinking is provided. Uses the macros CURSOR_SET */
  150. /* and CURSOR_OFF. */
  151. /* CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the */
  152. /* graphic chip. Uses the macro CURSOR_SET. */
  153. /* ATTENTION: If booting an OS, the display driver */
  154. /* must disable the hardware register of the graphic */
  155. /* chip. Otherwise a blinking field is displayed */
  156. /*****************************************************************************/
  157. #if !defined(CONFIG_CONSOLE_CURSOR) && \
  158. !defined(CONFIG_VIDEO_SW_CURSOR) && \
  159. !defined(CONFIG_VIDEO_HW_CURSOR)
  160. /* no Cursor defined */
  161. #define CURSOR_ON
  162. #define CURSOR_OFF
  163. #define CURSOR_SET
  164. #endif
  165. #ifdef CONFIG_CONSOLE_CURSOR
  166. #ifdef CURSOR_ON
  167. #error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
  168. #endif
  169. void console_cursor (int state);
  170. #define CURSOR_ON console_cursor(1);
  171. #define CURSOR_OFF console_cursor(0);
  172. #define CURSOR_SET
  173. #ifndef CONFIG_I8042_KBD
  174. #warning Cursor drawing on/off needs timer function s.a. drivers/i8042.c
  175. #endif
  176. #else
  177. #ifdef CONFIG_CONSOLE_TIME
  178. #error CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME
  179. #endif
  180. #endif /* CONFIG_CONSOLE_CURSOR */
  181. #ifdef CONFIG_VIDEO_SW_CURSOR
  182. #ifdef CURSOR_ON
  183. #error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
  184. #endif
  185. #define CURSOR_ON
  186. #define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\
  187. console_row * VIDEO_FONT_HEIGHT, ' ');
  188. #define CURSOR_SET video_set_cursor();
  189. #endif /* CONFIG_VIDEO_SW_CURSOR */
  190. #ifdef CONFIG_VIDEO_HW_CURSOR
  191. #ifdef CURSOR_ON
  192. #error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
  193. #endif
  194. #define CURSOR_ON
  195. #define CURSOR_OFF
  196. #define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \
  197. (console_row * VIDEO_FONT_HEIGHT) + VIDEO_LOGO_HEIGHT);
  198. #endif /* CONFIG_VIDEO_HW_CURSOR */
  199. #ifdef CONFIG_VIDEO_LOGO
  200. #ifdef CONFIG_VIDEO_BMP_LOGO
  201. #include <bmp_logo.h>
  202. #define VIDEO_LOGO_WIDTH BMP_LOGO_WIDTH
  203. #define VIDEO_LOGO_HEIGHT BMP_LOGO_HEIGHT
  204. #define VIDEO_LOGO_LUT_OFFSET BMP_LOGO_OFFSET
  205. #define VIDEO_LOGO_COLORS BMP_LOGO_COLORS
  206. #else /* CONFIG_VIDEO_BMP_LOGO */
  207. #define LINUX_LOGO_WIDTH 80
  208. #define LINUX_LOGO_HEIGHT 80
  209. #define LINUX_LOGO_COLORS 214
  210. #define LINUX_LOGO_LUT_OFFSET 0x20
  211. #define __initdata
  212. #include <linux_logo.h>
  213. #define VIDEO_LOGO_WIDTH LINUX_LOGO_WIDTH
  214. #define VIDEO_LOGO_HEIGHT LINUX_LOGO_HEIGHT
  215. #define VIDEO_LOGO_LUT_OFFSET LINUX_LOGO_LUT_OFFSET
  216. #define VIDEO_LOGO_COLORS LINUX_LOGO_COLORS
  217. #endif /* CONFIG_VIDEO_BMP_LOGO */
  218. #define VIDEO_INFO_X (VIDEO_LOGO_WIDTH)
  219. #define VIDEO_INFO_Y (VIDEO_FONT_HEIGHT/2)
  220. #else /* CONFIG_VIDEO_LOGO */
  221. #define VIDEO_LOGO_WIDTH 0
  222. #define VIDEO_LOGO_HEIGHT 0
  223. #endif /* CONFIG_VIDEO_LOGO */
  224. #define VIDEO_COLS VIDEO_VISIBLE_COLS
  225. #define VIDEO_ROWS VIDEO_VISIBLE_ROWS
  226. #define VIDEO_SIZE (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE)
  227. #define VIDEO_PIX_BLOCKS (VIDEO_SIZE >> 2)
  228. #define VIDEO_LINE_LEN (VIDEO_COLS*VIDEO_PIXEL_SIZE)
  229. #define VIDEO_BURST_LEN (VIDEO_COLS/8)
  230. #ifdef CONFIG_VIDEO_LOGO
  231. #define CONSOLE_ROWS ((VIDEO_ROWS - VIDEO_LOGO_HEIGHT) / VIDEO_FONT_HEIGHT)
  232. #else
  233. #define CONSOLE_ROWS (VIDEO_ROWS / VIDEO_FONT_HEIGHT)
  234. #endif
  235. #define CONSOLE_COLS (VIDEO_COLS / VIDEO_FONT_WIDTH)
  236. #define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN)
  237. #define CONSOLE_ROW_FIRST (video_console_address)
  238. #define CONSOLE_ROW_SECOND (video_console_address + CONSOLE_ROW_SIZE)
  239. #define CONSOLE_ROW_LAST (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
  240. #define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
  241. #define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
  242. /* Macros */
  243. #ifdef VIDEO_FB_LITTLE_ENDIAN
  244. #define SWAP16(x) ((((x) & 0x00ff) << 8) | ( (x) >> 8))
  245. #define SWAP32(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
  246. (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) )
  247. #define SHORTSWAP32(x) ((((x) & 0x000000ff) << 8) | (((x) & 0x0000ff00) >> 8)|\
  248. (((x) & 0x00ff0000) << 8) | (((x) & 0xff000000) >> 8) )
  249. #else
  250. #define SWAP16(x) (x)
  251. #define SWAP32(x) (x)
  252. #define SHORTSWAP32(x) (x)
  253. #endif
  254. #if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
  255. #define PRINTD(x) printf(x)
  256. #else
  257. #define PRINTD(x)
  258. #endif
  259. #ifdef CONFIG_CONSOLE_EXTRA_INFO
  260. extern void video_get_info_str ( /* setup a board string: type, speed, etc. */
  261. int line_number, /* location to place info string beside logo */
  262. char *info /* buffer for info string */
  263. );
  264. #endif
  265. /* Locals */
  266. static GraphicDevice *pGD; /* Pointer to Graphic array */
  267. static void *video_fb_address; /* frame buffer address */
  268. static void *video_console_address; /* console buffer start address */
  269. static int console_col = 0; /* cursor col */
  270. static int console_row = 0; /* cursor row */
  271. static u32 eorx, fgx, bgx; /* color pats */
  272. static const int video_font_draw_table8[] = {
  273. 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
  274. 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
  275. 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
  276. 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff };
  277. static const int video_font_draw_table15[] = {
  278. 0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff };
  279. static const int video_font_draw_table16[] = {
  280. 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff };
  281. static const int video_font_draw_table24[16][3] = {
  282. { 0x00000000, 0x00000000, 0x00000000 },
  283. { 0x00000000, 0x00000000, 0x00ffffff },
  284. { 0x00000000, 0x0000ffff, 0xff000000 },
  285. { 0x00000000, 0x0000ffff, 0xffffffff },
  286. { 0x000000ff, 0xffff0000, 0x00000000 },
  287. { 0x000000ff, 0xffff0000, 0x00ffffff },
  288. { 0x000000ff, 0xffffffff, 0xff000000 },
  289. { 0x000000ff, 0xffffffff, 0xffffffff },
  290. { 0xffffff00, 0x00000000, 0x00000000 },
  291. { 0xffffff00, 0x00000000, 0x00ffffff },
  292. { 0xffffff00, 0x0000ffff, 0xff000000 },
  293. { 0xffffff00, 0x0000ffff, 0xffffffff },
  294. { 0xffffffff, 0xffff0000, 0x00000000 },
  295. { 0xffffffff, 0xffff0000, 0x00ffffff },
  296. { 0xffffffff, 0xffffffff, 0xff000000 },
  297. { 0xffffffff, 0xffffffff, 0xffffffff } };
  298. static const int video_font_draw_table32[16][4] = {
  299. { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
  300. { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
  301. { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
  302. { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
  303. { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
  304. { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
  305. { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
  306. { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
  307. { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
  308. { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
  309. { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
  310. { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
  311. { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
  312. { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
  313. { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
  314. { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } };
  315. /******************************************************************************/
  316. static void video_drawchars (int xx, int yy, unsigned char *s, int count)
  317. {
  318. u8 *cdat, *dest, *dest0;
  319. int rows, offset, c;
  320. offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE;
  321. dest0 = video_fb_address + offset;
  322. switch (VIDEO_DATA_FORMAT)
  323. {
  324. case GDF__8BIT_INDEX:
  325. case GDF__8BIT_332RGB:
  326. while (count--)
  327. {
  328. c = *s ;
  329. cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
  330. for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
  331. {
  332. u8 bits = *cdat++;
  333. ((u32 *)dest)[0] = (video_font_draw_table8[bits >> 4] & eorx) ^ bgx;
  334. ((u32 *)dest)[1] = (video_font_draw_table8[bits & 15] & eorx) ^ bgx;
  335. }
  336. dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
  337. s++;
  338. }
  339. break;
  340. case GDF_15BIT_555RGB:
  341. while (count--)
  342. {
  343. c = *s ;
  344. cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
  345. for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
  346. {
  347. u8 bits = *cdat++;
  348. ((u32 *)dest)[0] = SHORTSWAP32((video_font_draw_table15[bits >> 6] & eorx) ^ bgx);
  349. ((u32 *)dest)[1] = SHORTSWAP32((video_font_draw_table15[bits >> 4 & 3] & eorx) ^ bgx);
  350. ((u32 *)dest)[2] = SHORTSWAP32((video_font_draw_table15[bits >> 2 & 3] & eorx) ^ bgx);
  351. ((u32 *)dest)[3] = SHORTSWAP32((video_font_draw_table15[bits & 3] & eorx) ^ bgx);
  352. }
  353. dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
  354. s++ ;
  355. }
  356. break;
  357. case GDF_16BIT_565RGB:
  358. while (count--)
  359. {
  360. c = *s ;
  361. cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
  362. for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
  363. {
  364. u8 bits = *cdat++;
  365. ((u32 *)dest)[0] = SHORTSWAP32((video_font_draw_table16[bits >> 6] & eorx) ^ bgx);
  366. ((u32 *)dest)[1] = SHORTSWAP32((video_font_draw_table16[bits >> 4 & 3] & eorx) ^ bgx);
  367. ((u32 *)dest)[2] = SHORTSWAP32((video_font_draw_table16[bits >> 2 & 3] & eorx) ^ bgx);
  368. ((u32 *)dest)[3] = SHORTSWAP32((video_font_draw_table16[bits & 3] & eorx) ^ bgx);
  369. }
  370. dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
  371. s++ ;
  372. }
  373. break;
  374. case GDF_32BIT_X888RGB:
  375. while (count--)
  376. {
  377. c = *s ;
  378. cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
  379. for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
  380. {
  381. u8 bits = *cdat++;
  382. ((u32 *)dest)[0] = SWAP32((video_font_draw_table32[bits >> 4][0] & eorx) ^ bgx);
  383. ((u32 *)dest)[1] = SWAP32((video_font_draw_table32[bits >> 4][1] & eorx) ^ bgx);
  384. ((u32 *)dest)[2] = SWAP32((video_font_draw_table32[bits >> 4][2] & eorx) ^ bgx);
  385. ((u32 *)dest)[3] = SWAP32((video_font_draw_table32[bits >> 4][3] & eorx) ^ bgx);
  386. ((u32 *)dest)[4] = SWAP32((video_font_draw_table32[bits & 15][0] & eorx) ^ bgx);
  387. ((u32 *)dest)[5] = SWAP32((video_font_draw_table32[bits & 15][1] & eorx) ^ bgx);
  388. ((u32 *)dest)[6] = SWAP32((video_font_draw_table32[bits & 15][2] & eorx) ^ bgx);
  389. ((u32 *)dest)[7] = SWAP32((video_font_draw_table32[bits & 15][3] & eorx) ^ bgx);
  390. }
  391. dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
  392. s++ ;
  393. }
  394. break;
  395. case GDF_24BIT_888RGB:
  396. while (count--)
  397. {
  398. c = *s ;
  399. cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
  400. for (rows = VIDEO_FONT_HEIGHT, dest = dest0; rows--; dest += VIDEO_LINE_LEN)
  401. {
  402. u8 bits = *cdat++;
  403. ((u32 *)dest)[0] = (video_font_draw_table24[bits >> 4][0] & eorx) ^ bgx;
  404. ((u32 *)dest)[1] = (video_font_draw_table24[bits >> 4][1] & eorx) ^ bgx;
  405. ((u32 *)dest)[2] = (video_font_draw_table24[bits >> 4][2] & eorx) ^ bgx;
  406. ((u32 *)dest)[3] = (video_font_draw_table24[bits & 15][0] & eorx) ^ bgx;
  407. ((u32 *)dest)[4] = (video_font_draw_table24[bits & 15][1] & eorx) ^ bgx;
  408. ((u32 *)dest)[5] = (video_font_draw_table24[bits & 15][2] & eorx) ^ bgx;
  409. }
  410. dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
  411. s++ ;
  412. }
  413. break;
  414. }
  415. }
  416. /*****************************************************************************/
  417. static inline void video_drawstring(int xx, int yy, unsigned char *s)
  418. {
  419. video_drawchars (xx, yy, s, strlen(s));
  420. }
  421. /*****************************************************************************/
  422. static void video_putchar(int xx, int yy, unsigned char c)
  423. {
  424. video_drawchars (xx, yy + VIDEO_LOGO_HEIGHT, &c, 1);
  425. }
  426. /*****************************************************************************/
  427. #if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
  428. static void video_set_cursor(void)
  429. {
  430. /* swap drawing colors */
  431. eorx = fgx;
  432. fgx = bgx;
  433. bgx = eorx;
  434. eorx = fgx ^ bgx;
  435. /* draw cursor */
  436. video_putchar (console_col * VIDEO_FONT_WIDTH,
  437. console_row * VIDEO_FONT_HEIGHT, ' ');
  438. /* restore drawing colors */
  439. eorx = fgx;
  440. fgx = bgx;
  441. bgx = eorx;
  442. eorx = fgx ^ bgx;
  443. }
  444. #endif
  445. /*****************************************************************************/
  446. #ifdef CONFIG_CONSOLE_CURSOR
  447. void console_cursor (int state)
  448. {
  449. static int last_state = 0;
  450. #ifdef CONFIG_CONSOLE_TIME
  451. struct rtc_time tm;
  452. char info[16];
  453. /* time update only if cursor is on (faster scroll) */
  454. if (state)
  455. {
  456. rtc_get (&tm);
  457. sprintf(info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min, tm.tm_sec);
  458. video_drawstring(VIDEO_VISIBLE_COLS-10*VIDEO_FONT_WIDTH,
  459. VIDEO_INFO_Y, info);
  460. sprintf(info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon, tm.tm_year);
  461. video_drawstring(VIDEO_VISIBLE_COLS-10*VIDEO_FONT_WIDTH,
  462. VIDEO_INFO_Y+1*VIDEO_FONT_HEIGHT, info);
  463. }
  464. #endif
  465. if (state && (last_state != state))
  466. {
  467. video_set_cursor();
  468. }
  469. if (!state && (last_state != state))
  470. {
  471. /* clear cursor */
  472. video_putchar (console_col * VIDEO_FONT_WIDTH,
  473. console_row * VIDEO_FONT_HEIGHT, ' ');
  474. }
  475. last_state = state;
  476. }
  477. #endif
  478. /*****************************************************************************/
  479. #ifndef VIDEO_HW_RECTFILL
  480. static void memsetl (int *p, int c, int v)
  481. {
  482. while (c--)
  483. *(p++) = v;
  484. }
  485. #endif
  486. /*****************************************************************************/
  487. #ifndef VIDEO_HW_BITBLT
  488. static void memcpyl (int *d, int *s, int c)
  489. {
  490. while (c--)
  491. *(d++) = *(s++);
  492. }
  493. #endif
  494. /*****************************************************************************/
  495. static void console_scrollup (void)
  496. {
  497. /* copy up rows ignoring the first one */
  498. #ifdef VIDEO_HW_BITBLT
  499. video_hw_bitblt (
  500. VIDEO_PIXEL_SIZE, /* bytes per pixel */
  501. 0, /* source pos x */
  502. VIDEO_LOGO_HEIGHT + VIDEO_FONT_HEIGHT, /* source pos y */
  503. 0, /* dest pos x */
  504. VIDEO_LOGO_HEIGHT, /* dest pos y */
  505. VIDEO_VISIBLE_COLS, /* frame width */
  506. VIDEO_VISIBLE_ROWS - VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT /* frame height */
  507. );
  508. #else
  509. memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE >> 2);
  510. #endif
  511. /* clear the last one */
  512. #ifdef VIDEO_HW_RECTFILL
  513. video_hw_rectfill (
  514. VIDEO_PIXEL_SIZE, /* bytes per pixel */
  515. 0, /* dest pos x */
  516. VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT, /* dest pos y */
  517. VIDEO_VISIBLE_COLS, /* frame width */
  518. VIDEO_FONT_HEIGHT, /* frame height */
  519. CONSOLE_BG_COL /* fill color */
  520. );
  521. #else
  522. memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
  523. #endif
  524. }
  525. /*****************************************************************************/
  526. static void console_back (void)
  527. {
  528. CURSOR_OFF
  529. console_col--;
  530. if (console_col < 0)
  531. {
  532. console_col = CONSOLE_COLS - 1;
  533. console_row--;
  534. if (console_row < 0)
  535. console_row = 0;
  536. }
  537. video_putchar (console_col * VIDEO_FONT_WIDTH,
  538. console_row * VIDEO_FONT_HEIGHT, ' ');
  539. }
  540. /*****************************************************************************/
  541. static void console_newline (void)
  542. {
  543. CURSOR_OFF
  544. console_row++;
  545. console_col = 0;
  546. /* Check if we need to scroll the terminal */
  547. if (console_row >= CONSOLE_ROWS)
  548. {
  549. /* Scroll everything up */
  550. console_scrollup ();
  551. /* Decrement row number */
  552. console_row--;
  553. }
  554. }
  555. /*****************************************************************************/
  556. void video_putc (const char c)
  557. {
  558. switch (c)
  559. {
  560. case 13: /* ignore */
  561. break;
  562. case '\n': /* next line */
  563. console_newline();
  564. break;
  565. case 9: /* tab 8 */
  566. CURSOR_OFF
  567. console_col |= 0x0008;
  568. console_col &= ~0x0007;
  569. if (console_col >= CONSOLE_COLS)
  570. console_newline();
  571. break;
  572. case 8: /* backspace */
  573. console_back();
  574. break;
  575. default: /* draw the char */
  576. video_putchar (console_col * VIDEO_FONT_WIDTH,
  577. console_row * VIDEO_FONT_HEIGHT, c);
  578. console_col++ ;
  579. /* check for newline */
  580. if (console_col >= CONSOLE_COLS)
  581. console_newline();
  582. }
  583. CURSOR_SET
  584. }
  585. /*****************************************************************************/
  586. void video_puts (const char *s)
  587. {
  588. int count = strlen(s);
  589. while(count--)
  590. video_putc(*s++);
  591. }
  592. /*****************************************************************************/
  593. #ifdef CONFIG_VIDEO_LOGO
  594. void logo_plot (void *screen, int width, int x, int y)
  595. {
  596. int skip = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE,
  597. xcount, i,
  598. ycount = VIDEO_LOGO_HEIGHT;
  599. unsigned char
  600. *source,
  601. *dest = (unsigned char *) screen + ((y * width * VIDEO_PIXEL_SIZE) + x),
  602. r, g, b, *logo_red, *logo_blue, *logo_green;
  603. #ifdef CONFIG_VIDEO_BMP_LOGO
  604. source = bmp_logo_bitmap;
  605. /* Allocate temporary space for computing colormap */
  606. logo_red = malloc (BMP_LOGO_COLORS);
  607. logo_green = malloc (BMP_LOGO_COLORS);
  608. logo_blue = malloc (BMP_LOGO_COLORS);
  609. /* Compute color map */
  610. for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
  611. logo_red [i] = (bmp_logo_palette [i] & 0x0f00) >> 4;
  612. logo_green [i] = (bmp_logo_palette [i] & 0x00f0);
  613. logo_blue [i] = (bmp_logo_palette [i] & 0x000f) << 4;
  614. }
  615. #else
  616. source = linux_logo;
  617. logo_red = linux_logo_red;
  618. logo_green = linux_logo_green;
  619. logo_blue = linux_logo_blue;
  620. #endif
  621. if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX)
  622. {
  623. for (i = 0; i < VIDEO_LOGO_COLORS; i++)
  624. {
  625. video_set_lut (i + VIDEO_LOGO_LUT_OFFSET,
  626. logo_red [i], logo_green [i], logo_blue [i]);
  627. }
  628. }
  629. while (ycount--)
  630. {
  631. xcount = VIDEO_LOGO_WIDTH;
  632. while (xcount--)
  633. {
  634. r = logo_red [*source - VIDEO_LOGO_LUT_OFFSET];
  635. g = logo_green [*source - VIDEO_LOGO_LUT_OFFSET];
  636. b = logo_blue [*source - VIDEO_LOGO_LUT_OFFSET];
  637. switch (VIDEO_DATA_FORMAT)
  638. {
  639. case GDF__8BIT_INDEX:
  640. *dest = *source;
  641. break;
  642. case GDF__8BIT_332RGB:
  643. *dest = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6);
  644. break;
  645. case GDF_15BIT_555RGB:
  646. *(unsigned short *)dest =
  647. SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3)));
  648. break;
  649. case GDF_16BIT_565RGB:
  650. *(unsigned short *)dest =
  651. SWAP16((unsigned short)(((r>>3)<<11) | ((g>>2)<<5) | (b>>3)));
  652. break;
  653. case GDF_32BIT_X888RGB:
  654. *(unsigned long *)dest =
  655. SWAP32((unsigned long)((r<<16) | (g<<8) | b));
  656. break;
  657. case GDF_24BIT_888RGB:
  658. #ifdef VIDEO_FB_LITTLE_ENDIAN
  659. dest[0] = b;
  660. dest[1] = g;
  661. dest[2] = r;
  662. #else
  663. dest[0] = r;
  664. dest[1] = g;
  665. dest[2] = b;
  666. #endif
  667. break;
  668. }
  669. source++;
  670. dest += VIDEO_PIXEL_SIZE;
  671. }
  672. dest += skip;
  673. }
  674. #ifdef CONFIG_VIDEO_BMP_LOGO
  675. free (logo_red);
  676. free (logo_green);
  677. free (logo_blue);
  678. #endif
  679. }
  680. /*****************************************************************************/
  681. static void *video_logo (void)
  682. {
  683. char info[128];
  684. extern char version_string;
  685. logo_plot (video_fb_address, VIDEO_COLS, 0, 0);
  686. sprintf(info, " %s", &version_string);
  687. video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, info);
  688. #ifdef CONFIG_CONSOLE_EXTRA_INFO
  689. {
  690. int i, n = ((VIDEO_LOGO_HEIGHT-VIDEO_FONT_HEIGHT)/VIDEO_FONT_HEIGHT);
  691. for (i = 1; i < n; i++)
  692. {
  693. video_get_info_str (i, info);
  694. if (*info)
  695. video_drawstring (VIDEO_INFO_X,
  696. VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT, info);
  697. }
  698. }
  699. #endif
  700. return (video_fb_address + VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN);
  701. }
  702. #endif
  703. /*****************************************************************************/
  704. static int video_init(void)
  705. {
  706. unsigned char color8;
  707. if ((pGD=video_hw_init()) == NULL)
  708. return -1;
  709. video_fb_address = (void*)VIDEO_FB_ADRS;
  710. #ifdef CONFIG_VIDEO_HW_CURSOR
  711. video_init_hw_cursor(VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
  712. #endif
  713. /* Init drawing pats */
  714. switch (VIDEO_DATA_FORMAT)
  715. {
  716. case GDF__8BIT_INDEX:
  717. video_set_lut (0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
  718. video_set_lut (0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL);
  719. fgx = 0x01010101;
  720. bgx = 0x00000000;
  721. break;
  722. case GDF__8BIT_332RGB:
  723. color8 = ((CONSOLE_FG_COL & 0xe0) | ((CONSOLE_FG_COL>>3) & 0x1c) | CONSOLE_FG_COL>>6);
  724. fgx = (color8<<24) | (color8<<16) | (color8<<8) | color8;
  725. color8 = ((CONSOLE_BG_COL & 0xe0) | ((CONSOLE_BG_COL>>3) & 0x1c) | CONSOLE_BG_COL>>6);
  726. bgx = (color8<<24) | (color8<<16) | (color8<<8) | color8;
  727. break;
  728. case GDF_15BIT_555RGB:
  729. fgx = (((CONSOLE_FG_COL>>3)<<26) | ((CONSOLE_FG_COL>>3)<<21) | ((CONSOLE_FG_COL>>3)<<16) |
  730. ((CONSOLE_FG_COL>>3)<<10) | ((CONSOLE_FG_COL>>3)<<5) | (CONSOLE_FG_COL>>3));
  731. bgx = (((CONSOLE_BG_COL>>3)<<26) | ((CONSOLE_BG_COL>>3)<<21) | ((CONSOLE_BG_COL>>3)<<16) |
  732. ((CONSOLE_BG_COL>>3)<<10) | ((CONSOLE_BG_COL>>3)<<5) | (CONSOLE_BG_COL>>3));
  733. break;
  734. case GDF_16BIT_565RGB:
  735. fgx = (((CONSOLE_FG_COL>>3)<<27) | ((CONSOLE_FG_COL>>2)<<21) | ((CONSOLE_FG_COL>>3)<<16) |
  736. ((CONSOLE_FG_COL>>3)<<11) | ((CONSOLE_FG_COL>>2)<<5) | (CONSOLE_FG_COL>>3));
  737. bgx = (((CONSOLE_BG_COL>>3)<<27) | ((CONSOLE_BG_COL>>2)<<21) | ((CONSOLE_BG_COL>>3)<<16) |
  738. ((CONSOLE_BG_COL>>3)<<11) | ((CONSOLE_BG_COL>>2)<<5) | (CONSOLE_BG_COL>>3));
  739. break;
  740. case GDF_32BIT_X888RGB:
  741. fgx = (CONSOLE_FG_COL<<16) | (CONSOLE_FG_COL<<8) | CONSOLE_FG_COL;
  742. bgx = (CONSOLE_BG_COL<<16) | (CONSOLE_BG_COL<<8) | CONSOLE_BG_COL;
  743. break;
  744. case GDF_24BIT_888RGB:
  745. fgx = (CONSOLE_FG_COL<<24) | (CONSOLE_FG_COL<<16) | (CONSOLE_FG_COL<<8) | CONSOLE_FG_COL;
  746. bgx = (CONSOLE_BG_COL<<24) | (CONSOLE_BG_COL<<16) | (CONSOLE_BG_COL<<8) | CONSOLE_BG_COL;
  747. break;
  748. }
  749. eorx = fgx ^ bgx;
  750. #ifdef CONFIG_VIDEO_LOGO
  751. /* Plot the logo and get start point of console */
  752. PRINTD("Video: Drawing the logo ...\n");
  753. video_console_address = video_logo();
  754. #else
  755. video_console_address = video_fb_address;
  756. #endif
  757. /* Initialize the console */
  758. console_col = 0;
  759. console_row = 0;
  760. return 0 ;
  761. }
  762. /*****************************************************************************/
  763. int drv_video_init (void)
  764. {
  765. int skip_dev_init;
  766. device_t console_dev;
  767. char *penv;
  768. skip_dev_init = 0;
  769. /* Force console i/o to serial ? */
  770. if ((penv = getenv ("console")) != NULL)
  771. if (strcmp (penv, "serial") == 0)
  772. return 0;
  773. /* Init video chip - returns with framebuffer cleared */
  774. if (video_init() == -1)
  775. skip_dev_init = 1;
  776. #ifdef CONFIG_VGA_AS_SINGLE_DEVICE
  777. /* Devices VGA and Keyboard will be assigned seperately */
  778. /* Init vga device */
  779. if (!skip_dev_init)
  780. {
  781. memset (&console_dev, 0, sizeof(console_dev));
  782. strcpy(console_dev.name, "vga");
  783. console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */
  784. console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
  785. console_dev.putc = video_putc; /* 'putc' function */
  786. console_dev.puts = video_puts; /* 'puts' function */
  787. console_dev.tstc = NULL; /* 'tstc' function */
  788. console_dev.getc = NULL; /* 'getc' function */
  789. if (device_register (&console_dev) == 0)
  790. return 1;
  791. }
  792. #else
  793. PRINTD("KBD: Keyboard init ...\n");
  794. if (VIDEO_KBD_INIT_FCT == -1)
  795. skip_dev_init = 1;
  796. /* Init console device */
  797. if (!skip_dev_init)
  798. {
  799. memset (&console_dev, 0, sizeof(console_dev));
  800. strcpy(console_dev.name, "console");
  801. console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */
  802. console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
  803. console_dev.putc = video_putc; /* 'putc' function */
  804. console_dev.puts = video_puts; /* 'puts' function */
  805. console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */
  806. console_dev.getc = VIDEO_GETC_FCT; /* 'getc' function */
  807. if (device_register (&console_dev) == 0)
  808. return 1;
  809. }
  810. #endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
  811. /* No console dev available */
  812. return 0;
  813. }
  814. #endif /* CONFIG_CFB_CONSOLE */