#include <common.h>
#include <version.h>
#include <malloc.h>
+#include <linux/compiler.h>
/*
* Console device defines with SMI graphic
#endif
#endif
+/*
+ * Defines for the i.MX31 driver (mx3fb.c)
+ */
+#if defined(CONFIG_VIDEO_MX3) || defined(CONFIG_VIDEO_MX5)
+#define VIDEO_FB_16BPP_WORD_SWAP
+#endif
+
/*
* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc.
*/
#include <linux/types.h>
#include <stdio_dev.h>
#include <video_font.h>
+#include <video_font_data.h>
#if defined(CONFIG_CMD_DATE)
#include <rtc.h>
#define CURSOR_SET
#endif
-#ifdef CONFIG_CONSOLE_CURSOR
-#ifdef CURSOR_ON
+#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
+#if defined(CURSOR_ON) || \
+ (defined(CONFIG_CONSOLE_CURSOR) && defined(CONFIG_VIDEO_SW_CURSOR))
#error only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \
or CONFIG_VIDEO_HW_CURSOR can be defined
#endif
#define CURSOR_ON console_cursor(1)
#define CURSOR_OFF console_cursor(0)
-#define CURSOR_SET
+#define CURSOR_SET video_set_cursor()
+#endif /* CONFIG_CONSOLE_CURSOR || CONFIG_VIDEO_SW_CURSOR */
+
+#ifdef CONFIG_CONSOLE_CURSOR
+#ifndef CONFIG_CONSOLE_TIME
+#error CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME
+#endif
#ifndef CONFIG_I8042_KBD
#warning Cursor drawing on/off needs timer function s.a. drivers/input/i8042.c
#endif
-#else
-#ifdef CONFIG_CONSOLE_TIME
-#error CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME
-#endif
#endif /* CONFIG_CONSOLE_CURSOR */
-#ifdef CONFIG_VIDEO_SW_CURSOR
-#ifdef CURSOR_ON
-#error only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \
- or CONFIG_VIDEO_HW_CURSOR can be defined
-#endif
-#define CURSOR_ON
-#define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\
- console_row * VIDEO_FONT_HEIGHT, ' ')
-#define CURSOR_SET video_set_cursor()
-#endif /* CONFIG_VIDEO_SW_CURSOR */
-
#ifdef CONFIG_VIDEO_HW_CURSOR
#ifdef CURSOR_ON
#ifdef CONFIG_VIDEO_LOGO
#ifdef CONFIG_VIDEO_BMP_LOGO
#include <bmp_logo.h>
+#include <bmp_logo_data.h>
#define VIDEO_LOGO_WIDTH BMP_LOGO_WIDTH
#define VIDEO_LOGO_HEIGHT BMP_LOGO_HEIGHT
#define VIDEO_LOGO_LUT_OFFSET BMP_LOGO_OFFSET
extern void video_get_info_str(int line_number, char *info);
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
/* Locals */
static GraphicDevice *pGD; /* Pointer to Graphic array */
static int video_logo_height = VIDEO_LOGO_HEIGHT;
-static int console_col = 0; /* cursor col */
-static int console_row = 0; /* cursor row */
+static int __maybe_unused cursor_state;
+static int __maybe_unused old_col;
+static int __maybe_unused old_row;
+
+static int console_col; /* cursor col */
+static int console_row; /* cursor row */
static u32 eorx, fgx, bgx; /* color pats */
+static int cfb_do_flush_cache;
+
static const int video_font_draw_table8[] = {
0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
{0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff}
};
-
static void video_drawchars(int xx, int yy, unsigned char *s, int count)
{
u8 *cdat, *dest, *dest0;
SWAP32((video_font_draw_table32
[bits & 15][3] & eorx) ^ bgx);
}
+ if (cfb_do_flush_cache)
+ flush_cache((ulong)dest0, 32);
dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
s++;
}
#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
static void video_set_cursor(void)
{
- /* swap drawing colors */
- eorx = fgx;
- fgx = bgx;
- bgx = eorx;
- eorx = fgx ^ bgx;
- /* draw cursor */
- video_putchar(console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT, ' ');
- /* restore drawing colors */
- eorx = fgx;
- fgx = bgx;
- bgx = eorx;
- eorx = fgx ^ bgx;
+ if (cursor_state)
+ console_cursor(0);
+ console_cursor(1);
}
-#endif
-#ifdef CONFIG_CONSOLE_CURSOR
-void console_cursor(int state)
+static void video_invertchar(int xx, int yy)
{
- static int last_state = 0;
+ int firstx = xx * VIDEO_PIXEL_SIZE;
+ int lastx = (xx + VIDEO_FONT_WIDTH) * VIDEO_PIXEL_SIZE;
+ int firsty = yy * VIDEO_LINE_LEN;
+ int lasty = (yy + VIDEO_FONT_HEIGHT) * VIDEO_LINE_LEN;
+ int x, y;
+ for (y = firsty; y < lasty; y += VIDEO_LINE_LEN) {
+ for (x = firstx; x < lastx; x++) {
+ u8 *dest = (u8 *)(video_fb_address) + x + y;
+ *dest = ~*dest;
+ if (cfb_do_flush_cache)
+ flush_cache((ulong)dest, 4);
+ }
+ }
+}
+void console_cursor(int state)
+{
#ifdef CONFIG_CONSOLE_TIME
struct rtc_time tm;
char info[16];
}
#endif
- if (state && (last_state != state)) {
- video_set_cursor();
- }
-
- if (!state && (last_state != state)) {
- /* clear cursor */
- video_putchar(console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT, ' ');
+ if (cursor_state != state) {
+ if (cursor_state) {
+ /* turn off the cursor */
+ video_invertchar(old_col * VIDEO_FONT_WIDTH,
+ old_row * VIDEO_FONT_HEIGHT +
+ video_logo_height);
+ } else {
+ /* turn off the cursor and record where it is */
+ video_invertchar(console_col * VIDEO_FONT_WIDTH,
+ console_row * VIDEO_FONT_HEIGHT +
+ video_logo_height);
+ old_col = console_col;
+ old_row = console_row;
+ }
+ cursor_state = state;
}
-
- last_state = state;
}
#endif
}
#endif
+static void console_clear_line(int line, int begin, int end)
+{
+#ifdef VIDEO_HW_RECTFILL
+ video_hw_rectfill(VIDEO_PIXEL_SIZE, /* bytes per pixel */
+ VIDEO_FONT_WIDTH * begin, /* dest pos x */
+ video_logo_height +
+ VIDEO_FONT_HEIGHT * line, /* dest pos y */
+ VIDEO_FONT_WIDTH * (end - begin + 1), /* fr. width */
+ VIDEO_FONT_HEIGHT, /* frame height */
+ bgx /* fill color */
+ );
+#else
+ if (begin == 0 && (end + 1) == CONSOLE_COLS) {
+ memsetl(CONSOLE_ROW_FIRST +
+ CONSOLE_ROW_SIZE * line, /* offset of row */
+ CONSOLE_ROW_SIZE >> 2, /* length of row */
+ bgx /* fill color */
+ );
+ } else {
+ void *offset;
+ int i, size;
+
+ offset = CONSOLE_ROW_FIRST +
+ CONSOLE_ROW_SIZE * line + /* offset of row */
+ VIDEO_FONT_WIDTH *
+ VIDEO_PIXEL_SIZE * begin; /* offset of col */
+ size = VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE * (end - begin + 1);
+ size >>= 2; /* length to end for memsetl() */
+ /* fill at col offset of i'th line using bgx as fill color */
+ for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
+ memsetl(offset + i * VIDEO_LINE_LEN, size, bgx);
+ }
+#endif
+ if (cfb_do_flush_cache)
+ flush_cache((ulong)CONSOLE_ROW_FIRST, CONSOLE_SIZE);
+}
+
static void console_scrollup(void)
{
/* copy up rows ignoring the first one */
memcpyl(CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND,
CONSOLE_SCROLL_SIZE >> 2);
#endif
-
/* clear the last one */
-#ifdef VIDEO_HW_RECTFILL
- video_hw_rectfill(VIDEO_PIXEL_SIZE, /* bytes per pixel */
- 0, /* dest pos x */
- VIDEO_VISIBLE_ROWS
- - VIDEO_FONT_HEIGHT, /* dest pos y */
- VIDEO_VISIBLE_COLS, /* frame width */
- VIDEO_FONT_HEIGHT, /* frame height */
- CONSOLE_BG_COL /* fill color */
- );
-#else
- memsetl(CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
-#endif
+ console_clear_line(CONSOLE_ROWS - 1, 0, CONSOLE_COLS - 1);
}
static void console_back(void)
{
- CURSOR_OFF;
console_col--;
if (console_col < 0) {
if (console_row < 0)
console_row = 0;
}
- video_putchar(console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT, ' ');
}
static void console_newline(void)
{
- /* Check if last character in the line was just drawn. If so, cursor was
- overwriten and need not to be cleared. Cursor clearing without this
- check causes overwriting the 1st character of the line if line lenght
- is >= CONSOLE_COLS
- */
- if (console_col < CONSOLE_COLS)
- CURSOR_OFF;
console_row++;
console_col = 0;
static void console_cr(void)
{
- CURSOR_OFF;
console_col = 0;
}
{
static int nl = 1;
+ CURSOR_OFF;
+
switch (c) {
case 13: /* back to first column */
console_cr();
break;
case 9: /* tab 8 */
- CURSOR_OFF;
console_col |= 0x0008;
console_col &= ~0x0007;
console_back();
break;
+ case 7: /* bell */
+ break; /* ignored */
+
default: /* draw the char */
video_putchar(console_col * VIDEO_FONT_WIDTH,
console_row * VIDEO_FONT_HEIGHT, c);
colors = le32_to_cpu(bmp->header.colors_used);
compression = le32_to_cpu(bmp->header.compression);
- debug("Display-bmp: %d x %d with %d colors\n",
+ debug("Display-bmp: %ld x %ld with %d colors\n",
width, height, colors);
if (compression != BMP_BI_RGB
static void *video_logo(void)
{
char info[128];
- int space, len, y_off = 0;
+ int space, len;
+ __maybe_unused int y_off = 0;
#ifdef CONFIG_SPLASH_SCREEN
char *s;
ulong addr;
- if ((s = getenv("splashimage")) != NULL) {
+ s = getenv("splashimage");
+ if (s != NULL) {
int x = 0, y = 0;
addr = simple_strtoul(s, NULL, 16);
#ifdef CONFIG_SPLASH_SCREEN_ALIGN
- if ((s = getenv("splashpos")) != NULL) {
+ s = getenv("splashpos");
+ if (s != NULL) {
if (s[0] == 'm')
x = BMP_ALIGN_CENTER;
else
x = simple_strtol(s, NULL, 0);
- if ((s = strchr(s + 1, ',')) != NULL) {
+ s = strchr(s + 1, ',');
+ if (s != NULL) {
if (s[1] == 'm')
y = BMP_ALIGN_CENTER;
else
}
#endif
+static int cfb_fb_is_in_dram(void)
+{
+ bd_t *bd = gd->bd;
+#if defined(CONFIG_ARM) || defined(CONFIG_AVR32) || defined(COFNIG_NDS32) || \
+defined(CONFIG_SANDBOX) || defined(CONFIG_X86)
+ ulong start, end;
+ int i;
+
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) {
+ start = bd->bi_dram[i].start;
+ end = bd->bi_dram[i].start + bd->bi_dram[i].size - 1;
+ if ((ulong)video_fb_address >= start &&
+ (ulong)video_fb_address < end)
+ return 1;
+ }
+#else
+ if ((ulong)video_fb_address >= bd->bi_memstart &&
+ (ulong)video_fb_address < bd->bi_memstart + bd->bi_memsize)
+ return 1;
+#endif
+ return 0;
+}
+
static int video_init(void)
{
unsigned char color8;
- if ((pGD = video_hw_init()) == NULL)
+ pGD = video_hw_init();
+ if (pGD == NULL)
return -1;
video_fb_address = (void *) VIDEO_FB_ADRS;
video_init_hw_cursor(VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
#endif
+ cfb_do_flush_cache = cfb_fb_is_in_dram() && dcache_status();
+
/* Init drawing pats */
switch (VIDEO_DATA_FORMAT) {
case GDF__8BIT_INDEX: