Blame view

common/lcd.c 17.4 KB
83d290c56   Tom Rini   SPDX: Convert all...
1
  // SPDX-License-Identifier: GPL-2.0+
8655b6f86   wdenk   * Clean up tools/...
2
  /*
c8d2febcc   Nikita Kiryanov   lcd: various clea...
3
   * Common LCD routines
8655b6f86   wdenk   * Clean up tools/...
4
5
6
   *
   * (C) Copyright 2001-2002
   * Wolfgang Denk, DENX Software Engineering -- wd@denx.de
8655b6f86   wdenk   * Clean up tools/...
7
   */
8655b6f86   wdenk   * Clean up tools/...
8
  /* #define DEBUG */
8655b6f86   wdenk   * Clean up tools/...
9
10
11
  #include <config.h>
  #include <common.h>
  #include <command.h>
1eb69ae49   Simon Glass   common: Move ARM ...
12
  #include <cpu_func.h>
c08804853   Nikita Kiryanov   lcd: implement a ...
13
  #include <env_callback.h>
8655b6f86   wdenk   * Clean up tools/...
14
  #include <linux/types.h>
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
15
  #include <stdio_dev.h>
8655b6f86   wdenk   * Clean up tools/...
16
  #include <lcd.h>
0eb25b619   Joe Hershberger   common: Make sure...
17
  #include <mapmem.h>
8b0bfc680   wdenk   * Patch by Yuli B...
18
  #include <watchdog.h>
dca2a1c18   Przemyslaw Marczak   common: lcd.c: fi...
19
  #include <asm/unaligned.h>
dd4425e85   Robert Winkler   video: lcd: Add C...
20
  #include <splash.h>
7d95f2a32   Simon Glass   sandbox: Add LCD ...
21
22
  #include <asm/io.h>
  #include <asm/unaligned.h>
c8d2febcc   Nikita Kiryanov   lcd: various clea...
23
  #include <video_font.h>
dd4425e85   Robert Winkler   video: lcd: Add C...
24

88804d19e   wdenk   * Patch by Detlev...
25
  #ifdef CONFIG_LCD_LOGO
c8d2febcc   Nikita Kiryanov   lcd: various clea...
26
27
28
29
30
  #include <bmp_logo.h>
  #include <bmp_logo_data.h>
  #if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP != LCD_COLOR16)
  #error Default Color Map overlaps with Logo Color Map
  #endif
88804d19e   wdenk   * Patch by Detlev...
31
  #endif
8655b6f86   wdenk   * Clean up tools/...
32

676d319ef   Simon Glass   lcd: Add CONFIG_L...
33
34
35
  #ifndef CONFIG_LCD_ALIGNMENT
  #define CONFIG_LCD_ALIGNMENT PAGE_SIZE
  #endif
d87080b72   Wolfgang Denk   GCC-4.x fixes: cl...
36
  DECLARE_GLOBAL_DATA_PTR;
8655b6f86   wdenk   * Clean up tools/...
37

8f47d917c   Nikita Kiryanov   common lcd: minor...
38
  static int lcd_init(void *lcdbase);
7bf71d1f5   Nikita Kiryanov   lcd: split splash...
39
  static void lcd_logo(void);
8f47d917c   Nikita Kiryanov   common lcd: minor...
40
41
  static void lcd_setfgcolor(int color);
  static void lcd_setbgcolor(int color);
8655b6f86   wdenk   * Clean up tools/...
42

46d1d5dd4   Wolfgang Denk   common/lcd.c: cle...
43
44
  static int lcd_color_fg;
  static int lcd_color_bg;
f1d205a19   Jeroen Hofstee   common/lcd.c: cle...
45
  int lcd_line_length;
8655b6f86   wdenk   * Clean up tools/...
46
  char lcd_is_enabled = 0;
00a0ca598   Jeroen Hofstee   common/lcd.c: rem...
47
  static void *lcd_base;			/* Start of framebuffer memory	*/
9a8efc460   Simon Glass   lcd: Add support ...
48
  static char lcd_flush_dcache;	/* 1 to flush dcache after each lcd update */
8655b6f86   wdenk   * Clean up tools/...
49

9a8efc460   Simon Glass   lcd: Add support ...
50
51
52
53
54
55
56
57
  /* Flush LCD activity to the caches */
  void lcd_sync(void)
  {
  	/*
  	 * flush_dcache_range() is declared in common.h but it seems that some
  	 * architectures do not actually implement it. Is there a way to find
  	 * out whether it exists? For now, ARM is safe.
  	 */
100150254   Trevor Woerner   CONFIG_SPL_SYS_[D...
58
  #if defined(CONFIG_ARM) && !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
9a8efc460   Simon Glass   lcd: Add support ...
59
60
61
  	int line_length;
  
  	if (lcd_flush_dcache)
f8f58fbb0   Alexander Graf   lcd: Fix compile ...
62
63
  		flush_dcache_range((ulong)lcd_base,
  			(ulong)(lcd_base + lcd_get_size(&line_length)));
9a8efc460   Simon Glass   lcd: Add support ...
64
65
66
67
68
69
70
  #endif
  }
  
  void lcd_set_flush_dcache(int flush)
  {
  	lcd_flush_dcache = (flush != 0);
  }
709ea543b   Simon Glass   stdio: Pass devic...
71
72
73
74
  static void lcd_stub_putc(struct stdio_dev *dev, const char c)
  {
  	lcd_putc(c);
  }
709ea543b   Simon Glass   stdio: Pass devic...
75
76
77
78
  static void lcd_stub_puts(struct stdio_dev *dev, const char *s)
  {
  	lcd_puts(s);
  }
c8d2febcc   Nikita Kiryanov   lcd: various clea...
79
  /* Small utility to check that you got the colours right */
8655b6f86   wdenk   * Clean up tools/...
80
  #ifdef LCD_TEST_PATTERN
e32951b52   Andreas Neubacher   lcd: fix the colo...
81
  #if LCD_BPP == LCD_COLOR8
8655b6f86   wdenk   * Clean up tools/...
82
83
  #define	N_BLK_VERT	2
  #define	N_BLK_HOR	3
6b035141f   Jeroen Hofstee   common/lcd: cosme...
84
  static int test_colors[N_BLK_HOR * N_BLK_VERT] = {
8655b6f86   wdenk   * Clean up tools/...
85
86
  	CONSOLE_COLOR_RED,	CONSOLE_COLOR_GREEN,	CONSOLE_COLOR_YELLOW,
  	CONSOLE_COLOR_BLUE,	CONSOLE_COLOR_MAGENTA,	CONSOLE_COLOR_CYAN,
e32951b52   Andreas Neubacher   lcd: fix the colo...
87
88
89
90
91
92
93
94
95
  }; /*LCD_BPP == LCD_COLOR8 */
  
  #elif LCD_BPP == LCD_COLOR16
  #define	N_BLK_VERT	2
  #define	N_BLK_HOR	4
  
  static int test_colors[N_BLK_HOR * N_BLK_VERT] = {
  	CONSOLE_COLOR_RED,	CONSOLE_COLOR_GREEN,	CONSOLE_COLOR_YELLOW,	CONSOLE_COLOR_BLUE,
  	CONSOLE_COLOR_MAGENTA,	CONSOLE_COLOR_CYAN,	CONSOLE_COLOR_GREY,	CONSOLE_COLOR_WHITE,
8655b6f86   wdenk   * Clean up tools/...
96
  };
e32951b52   Andreas Neubacher   lcd: fix the colo...
97
  #endif /*LCD_BPP == LCD_COLOR16 */
8655b6f86   wdenk   * Clean up tools/...
98

8f47d917c   Nikita Kiryanov   common lcd: minor...
99
  static void test_pattern(void)
8655b6f86   wdenk   * Clean up tools/...
100
101
102
103
104
105
  {
  	ushort v_max  = panel_info.vl_row;
  	ushort h_max  = panel_info.vl_col;
  	ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT;
  	ushort h_step = (h_max + N_BLK_HOR  - 1) / N_BLK_HOR;
  	ushort v, h;
e32951b52   Andreas Neubacher   lcd: fix the colo...
106
  #if LCD_BPP == LCD_COLOR8
8655b6f86   wdenk   * Clean up tools/...
107
  	uchar *pix = (uchar *)lcd_base;
e32951b52   Andreas Neubacher   lcd: fix the colo...
108
109
110
  #elif LCD_BPP == LCD_COLOR16
  	ushort *pix = (ushort *)lcd_base;
  #endif
8655b6f86   wdenk   * Clean up tools/...
111

8f47d917c   Nikita Kiryanov   common lcd: minor...
112
113
  	printf("[LCD] Test Pattern: %d x %d [%d x %d]
  ",
8655b6f86   wdenk   * Clean up tools/...
114
  		h_max, v_max, h_step, v_step);
8f47d917c   Nikita Kiryanov   common lcd: minor...
115
  	for (v = 0; v < v_max; ++v) {
8655b6f86   wdenk   * Clean up tools/...
116
  		uchar iy = v / v_step;
8f47d917c   Nikita Kiryanov   common lcd: minor...
117
  		for (h = 0; h < h_max; ++h) {
6b035141f   Jeroen Hofstee   common/lcd: cosme...
118
  			uchar ix = N_BLK_HOR * iy + h / h_step;
8655b6f86   wdenk   * Clean up tools/...
119
120
121
122
123
  			*pix++ = test_colors[ix];
  		}
  	}
  }
  #endif /* LCD_TEST_PATTERN */
cefa47171   Anatolij Gustschin   lcd: allow overri...
124
125
126
127
128
129
130
  /*
   * With most lcd drivers the line length is set up
   * by calculating it from panel_info parameters. Some
   * drivers need to calculate the line length differently,
   * so make the function weak to allow overriding it.
   */
  __weak int lcd_get_size(int *line_length)
676d319ef   Simon Glass   lcd: Add CONFIG_L...
131
132
133
134
  {
  	*line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
  	return *line_length * panel_info.vl_row;
  }
6b035141f   Jeroen Hofstee   common/lcd: cosme...
135
  int drv_lcd_init(void)
8655b6f86   wdenk   * Clean up tools/...
136
  {
52cb4d4fb   Jean-Christophe PLAGNIOL-VILLARD   stdio/device: rew...
137
  	struct stdio_dev lcddev;
8655b6f86   wdenk   * Clean up tools/...
138
  	int rc;
7d95f2a32   Simon Glass   sandbox: Add LCD ...
139
  	lcd_base = map_sysmem(gd->fb_base, 0);
8655b6f86   wdenk   * Clean up tools/...
140

c8d2febcc   Nikita Kiryanov   lcd: various clea...
141
  	lcd_init(lcd_base);
8655b6f86   wdenk   * Clean up tools/...
142
143
  
  	/* Device initialization */
8f47d917c   Nikita Kiryanov   common lcd: minor...
144
  	memset(&lcddev, 0, sizeof(lcddev));
8655b6f86   wdenk   * Clean up tools/...
145

8f47d917c   Nikita Kiryanov   common lcd: minor...
146
  	strcpy(lcddev.name, "lcd");
8655b6f86   wdenk   * Clean up tools/...
147
148
  	lcddev.ext   = 0;			/* No extensions */
  	lcddev.flags = DEV_FLAGS_OUTPUT;	/* Output only */
709ea543b   Simon Glass   stdio: Pass devic...
149
150
  	lcddev.putc  = lcd_stub_putc;		/* 'putc' function */
  	lcddev.puts  = lcd_stub_puts;		/* 'puts' function */
8655b6f86   wdenk   * Clean up tools/...
151

6b035141f   Jeroen Hofstee   common/lcd: cosme...
152
  	rc = stdio_register(&lcddev);
8655b6f86   wdenk   * Clean up tools/...
153
154
155
  
  	return (rc == 0) ? 1 : rc;
  }
02110903a   Che-Liang Chiou   lcd: add clear an...
156
  void lcd_clear(void)
8655b6f86   wdenk   * Clean up tools/...
157
  {
5eb83c0ac   Igor Opaniuk   splash: display s...
158
  	__maybe_unused ulong addr;
7bf71d1f5   Nikita Kiryanov   lcd: split splash...
159
  	static int do_splash = 1;
0bd36ee73   Peng Fan   MLK-12425-2 video...
160
161
162
163
164
  #if LCD_BPP == LCD_MONOCHROME
  	/* Setting the palette */
  	lcd_initcolregs();
  
  #elif LCD_BPP == LCD_COLOR8
8655b6f86   wdenk   * Clean up tools/...
165
  	/* Setting the palette */
8f47d917c   Nikita Kiryanov   common lcd: minor...
166
167
168
169
170
171
172
173
174
  	lcd_setcolreg(CONSOLE_COLOR_BLACK, 0, 0, 0);
  	lcd_setcolreg(CONSOLE_COLOR_RED, 0xFF, 0, 0);
  	lcd_setcolreg(CONSOLE_COLOR_GREEN, 0, 0xFF, 0);
  	lcd_setcolreg(CONSOLE_COLOR_YELLOW, 0xFF, 0xFF, 0);
  	lcd_setcolreg(CONSOLE_COLOR_BLUE, 0, 0, 0xFF);
  	lcd_setcolreg(CONSOLE_COLOR_MAGENTA, 0xFF, 0, 0xFF);
  	lcd_setcolreg(CONSOLE_COLOR_CYAN, 0, 0xFF, 0xFF);
  	lcd_setcolreg(CONSOLE_COLOR_GREY, 0xAA, 0xAA, 0xAA);
  	lcd_setcolreg(CONSOLE_COLOR_WHITE, 0xFF, 0xFF, 0xFF);
8655b6f86   wdenk   * Clean up tools/...
175
  #endif
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
176
  #ifndef CONFIG_SYS_WHITE_ON_BLACK
8f47d917c   Nikita Kiryanov   common lcd: minor...
177
178
  	lcd_setfgcolor(CONSOLE_COLOR_BLACK);
  	lcd_setbgcolor(CONSOLE_COLOR_WHITE);
8655b6f86   wdenk   * Clean up tools/...
179
  #else
8f47d917c   Nikita Kiryanov   common lcd: minor...
180
181
  	lcd_setfgcolor(CONSOLE_COLOR_WHITE);
  	lcd_setbgcolor(CONSOLE_COLOR_BLACK);
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
182
  #endif	/* CONFIG_SYS_WHITE_ON_BLACK */
8655b6f86   wdenk   * Clean up tools/...
183
184
185
186
187
  
  #ifdef	LCD_TEST_PATTERN
  	test_pattern();
  #else
  	/* set framebuffer to background color */
57d76a89b   Hannes Petermaier   Add support for 3...
188
  #if (LCD_BPP != LCD_COLOR32)
0bd36ee73   Peng Fan   MLK-12425-2 video...
189
190
  	memset((char *)lcd_base, COLOR_MASK(lcd_getbgcolor()),
  	       lcd_line_length * panel_info.vl_row);
57d76a89b   Hannes Petermaier   Add support for 3...
191
192
193
194
195
196
  #else
  	u32 *ppix = lcd_base;
  	u32 i;
  	for (i = 0;
  	   i < (lcd_line_length * panel_info.vl_row)/NBYTES(panel_info.vl_bpix);
  	   i++) {
0bd36ee73   Peng Fan   MLK-12425-2 video...
197
  		*ppix++ = COLOR_MASK(lcd_getbgcolor());
57d76a89b   Hannes Petermaier   Add support for 3...
198
199
  	}
  #endif
8655b6f86   wdenk   * Clean up tools/...
200
  #endif
604c7d4a5   Hannes Petermaier   common/lcd_consol...
201
202
203
204
205
206
207
  	/* setup text-console */
  	debug("[LCD] setting up console...
  ");
  	lcd_init_console(lcd_base,
  			 panel_info.vl_col,
  			 panel_info.vl_row,
  			 panel_info.vl_rot);
8655b6f86   wdenk   * Clean up tools/...
208
  	/* Paint the logo and retrieve LCD base address */
8f47d917c   Nikita Kiryanov   common lcd: minor...
209
210
  	debug("[LCD] Drawing the logo...
  ");
7bf71d1f5   Nikita Kiryanov   lcd: split splash...
211
  	if (do_splash) {
5eb83c0ac   Igor Opaniuk   splash: display s...
212
  		if (splash_display() == 0) {
7bf71d1f5   Nikita Kiryanov   lcd: split splash...
213
  			do_splash = 0;
5eb83c0ac   Igor Opaniuk   splash: display s...
214
215
  			lcd_sync();
  			return;
7bf71d1f5   Nikita Kiryanov   lcd: split splash...
216
217
218
219
220
221
  		}
  	}
  
  	lcd_logo();
  #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
  	addr = (ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length;
3b96b9096   Marcel Ziswiler   common/lcd_consol...
222
223
  	lcd_init_console((void *)addr, panel_info.vl_col,
  			 panel_info.vl_row, panel_info.vl_rot);
7bf71d1f5   Nikita Kiryanov   lcd: split splash...
224
  #endif
9a8efc460   Simon Glass   lcd: Add support ...
225
226
  	lcd_sync();
  }
8f47d917c   Nikita Kiryanov   common lcd: minor...
227
  static int lcd_init(void *lcdbase)
8655b6f86   wdenk   * Clean up tools/...
228
  {
8f47d917c   Nikita Kiryanov   common lcd: minor...
229
230
  	debug("[LCD] Initializing LCD frambuffer at %p
  ", lcdbase);
8f47d917c   Nikita Kiryanov   common lcd: minor...
231
  	lcd_ctrl_init(lcdbase);
1d3dea12e   Anatolij Gustschin   video: bcm2835: f...
232
233
  
  	/*
9316e1440   Stephen Warren   ARM: rpi: rename ...
234
  	 * lcd_ctrl_init() of some drivers (i.e. bcm2835 on rpi) ignores
1d3dea12e   Anatolij Gustschin   video: bcm2835: f...
235
236
237
238
  	 * the 'lcdbase' argument and uses custom lcd base address
  	 * by setting up gd->fb_base. Check for this condition and fixup
  	 * 'lcd_base' address.
  	 */
7d95f2a32   Simon Glass   sandbox: Add LCD ...
239
240
  	if (map_to_sysmem(lcdbase) != gd->fb_base)
  		lcd_base = map_sysmem(gd->fb_base, 0);
1d3dea12e   Anatolij Gustschin   video: bcm2835: f...
241
242
243
  
  	debug("[LCD] Using LCD frambuffer at %p
  ", lcd_base);
6d3307195   Stephen Warren   lcd: calculate li...
244
  	lcd_get_size(&lcd_line_length);
6f93d2b8f   Haavard Skinnemoen   lcd: Set lcd_is_e...
245
  	lcd_is_enabled = 1;
02110903a   Che-Liang Chiou   lcd: add clear an...
246
  	lcd_clear();
6b035141f   Jeroen Hofstee   common/lcd: cosme...
247
  	lcd_enable();
8655b6f86   wdenk   * Clean up tools/...
248
249
  
  	/* Initialize the console */
140beb943   Nikita Kiryanov   lcd: expand conso...
250
  	lcd_set_col(0);
88804d19e   wdenk   * Patch by Detlev...
251
  #ifdef CONFIG_LCD_INFO_BELOW_LOGO
140beb943   Nikita Kiryanov   lcd: expand conso...
252
  	lcd_set_row(7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT);
8655b6f86   wdenk   * Clean up tools/...
253
  #else
140beb943   Nikita Kiryanov   lcd: expand conso...
254
  	lcd_set_row(1);	/* leave 1 blank line below logo */
8655b6f86   wdenk   * Clean up tools/...
255
  #endif
8655b6f86   wdenk   * Clean up tools/...
256
257
258
  
  	return 0;
  }
8655b6f86   wdenk   * Clean up tools/...
259
260
261
262
263
264
265
  /*
   * This is called early in the system initialization to grab memory
   * for the LCD controller.
   * Returns new address for monitor, after reserving LCD buffer memory
   *
   * Note that this is running from ROM, so no write access to global data.
   */
8f47d917c   Nikita Kiryanov   common lcd: minor...
266
  ulong lcd_setmem(ulong addr)
8655b6f86   wdenk   * Clean up tools/...
267
268
  {
  	ulong size;
676d319ef   Simon Glass   lcd: Add CONFIG_L...
269
  	int line_length;
8655b6f86   wdenk   * Clean up tools/...
270

0bd36ee73   Peng Fan   MLK-12425-2 video...
271
272
  	debug("LCD panel info: %lu x %lu, %d bit/pix
  ", panel_info.vl_col,
8f47d917c   Nikita Kiryanov   common lcd: minor...
273
  		panel_info.vl_row, NBITS(panel_info.vl_bpix));
8655b6f86   wdenk   * Clean up tools/...
274

676d319ef   Simon Glass   lcd: Add CONFIG_L...
275
  	size = lcd_get_size(&line_length);
8655b6f86   wdenk   * Clean up tools/...
276

676d319ef   Simon Glass   lcd: Add CONFIG_L...
277
278
279
  	/* Round up to nearest full page, or MMU section if defined */
  	size = ALIGN(size, CONFIG_LCD_ALIGNMENT);
  	addr = ALIGN(addr - CONFIG_LCD_ALIGNMENT + 1, CONFIG_LCD_ALIGNMENT);
8655b6f86   wdenk   * Clean up tools/...
280
281
282
  
  	/* Allocate pages for the frame buffer. */
  	addr -= size;
6b035141f   Jeroen Hofstee   common/lcd: cosme...
283
284
285
  	debug("Reserving %ldk for LCD Framebuffer at: %08lx
  ",
  	      size >> 10, addr);
8655b6f86   wdenk   * Clean up tools/...
286

8f47d917c   Nikita Kiryanov   common lcd: minor...
287
  	return addr;
8655b6f86   wdenk   * Clean up tools/...
288
  }
8f47d917c   Nikita Kiryanov   common lcd: minor...
289
  static void lcd_setfgcolor(int color)
8655b6f86   wdenk   * Clean up tools/...
290
  {
39cf48048   Stelian Pop   Add ATMEL LCD driver
291
  	lcd_color_fg = color;
8655b6f86   wdenk   * Clean up tools/...
292
  }
4d03634e5   Nikita Kiryanov   lcd: introduce ge...
293
294
295
296
  int lcd_getfgcolor(void)
  {
  	return lcd_color_fg;
  }
8f47d917c   Nikita Kiryanov   common lcd: minor...
297
  static void lcd_setbgcolor(int color)
8655b6f86   wdenk   * Clean up tools/...
298
  {
39cf48048   Stelian Pop   Add ATMEL LCD driver
299
  	lcd_color_bg = color;
8655b6f86   wdenk   * Clean up tools/...
300
  }
4d03634e5   Nikita Kiryanov   lcd: introduce ge...
301
302
303
304
  int lcd_getbgcolor(void)
  {
  	return lcd_color_bg;
  }
8655b6f86   wdenk   * Clean up tools/...
305
  #ifdef CONFIG_LCD_LOGO
a02e94813   Nikita Kiryanov   lcd: atmel: intro...
306
307
  __weak void lcd_logo_set_cmap(void)
  {
2306457c4   Nikita Kiryanov   lcd: logo: move g...
308
309
310
311
312
  	int i;
  	ushort *cmap = configuration_get_cmap();
  
  	for (i = 0; i < ARRAY_SIZE(bmp_logo_palette); ++i)
  		*cmap++ = bmp_logo_palette[i];
a02e94813   Nikita Kiryanov   lcd: atmel: intro...
313
  }
bf21a5deb   Nikita Kiryanov   lcd: rename bitma...
314
  void lcd_logo_plot(int x, int y)
8655b6f86   wdenk   * Clean up tools/...
315
  {
8655b6f86   wdenk   * Clean up tools/...
316
  	ushort i, j;
c8d2febcc   Nikita Kiryanov   lcd: various clea...
317
  	uchar *bmap = &bmp_logo_bitmap[0];
317461c1d   Andre Renaud   Fix bitmap offset...
318
  	unsigned bpix = NBITS(panel_info.vl_bpix);
c8d2febcc   Nikita Kiryanov   lcd: various clea...
319
320
  	uchar *fb = (uchar *)(lcd_base + y * lcd_line_length + x * bpix / 8);
  	ushort *fb16;
8655b6f86   wdenk   * Clean up tools/...
321

2306457c4   Nikita Kiryanov   lcd: logo: move g...
322
323
324
  	debug("Logo: width %d  height %d  colors %d
  ",
  	      BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS);
8655b6f86   wdenk   * Clean up tools/...
325

317461c1d   Andre Renaud   Fix bitmap offset...
326
  	if (bpix < 12) {
8655b6f86   wdenk   * Clean up tools/...
327
  		WATCHDOG_RESET();
a02e94813   Nikita Kiryanov   lcd: atmel: intro...
328
  		lcd_logo_set_cmap();
8655b6f86   wdenk   * Clean up tools/...
329
  		WATCHDOG_RESET();
8f47d917c   Nikita Kiryanov   common lcd: minor...
330
331
  		for (i = 0; i < BMP_LOGO_HEIGHT; ++i) {
  			memcpy(fb, bmap, BMP_LOGO_WIDTH);
8655b6f86   wdenk   * Clean up tools/...
332
  			bmap += BMP_LOGO_WIDTH;
6b035141f   Jeroen Hofstee   common/lcd: cosme...
333
  			fb += panel_info.vl_col;
8655b6f86   wdenk   * Clean up tools/...
334
335
336
  		}
  	}
  	else { /* true color mode */
acb138689   Alessandro Rubini   lcd: make 16bpp work
337
  		u16 col16;
317461c1d   Andre Renaud   Fix bitmap offset...
338
  		fb16 = (ushort *)fb;
8f47d917c   Nikita Kiryanov   common lcd: minor...
339
340
  		for (i = 0; i < BMP_LOGO_HEIGHT; ++i) {
  			for (j = 0; j < BMP_LOGO_WIDTH; j++) {
acb138689   Alessandro Rubini   lcd: make 16bpp work
341
342
343
344
345
  				col16 = bmp_logo_palette[(bmap[j]-16)];
  				fb16[j] =
  					((col16 & 0x000F) << 1) |
  					((col16 & 0x00F0) << 3) |
  					((col16 & 0x0F00) << 4);
8655b6f86   wdenk   * Clean up tools/...
346
347
348
349
350
351
352
  				}
  			bmap += BMP_LOGO_WIDTH;
  			fb16 += panel_info.vl_col;
  		}
  	}
  
  	WATCHDOG_RESET();
9a8efc460   Simon Glass   lcd: Add support ...
353
  	lcd_sync();
8655b6f86   wdenk   * Clean up tools/...
354
  }
2b5cb3d33   Anatolij Gustschin   common/lcd.c: red...
355
  #else
bf21a5deb   Nikita Kiryanov   lcd: rename bitma...
356
  static inline void lcd_logo_plot(int x, int y) {}
8655b6f86   wdenk   * Clean up tools/...
357
  #endif /* CONFIG_LCD_LOGO */
c3517f919   Jon Loeliger   common/* non-cmd*...
358
  #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
1ca298ced   Matthias Weisser   Added support for...
359
  #ifdef CONFIG_SPLASH_SCREEN_ALIGN
7c7e280aa   Nikita Kiryanov   common lcd: simpl...
360
361
362
363
364
365
366
367
368
369
370
371
372
  
  static void splash_align_axis(int *axis, unsigned long panel_size,
  					unsigned long picture_size)
  {
  	unsigned long panel_picture_delta = panel_size - picture_size;
  	unsigned long axis_alignment;
  
  	if (*axis == BMP_ALIGN_CENTER)
  		axis_alignment = panel_picture_delta / 2;
  	else if (*axis < 0)
  		axis_alignment = panel_picture_delta + *axis + 1;
  	else
  		return;
b41411954   Masahiro Yamada   linux/kernel.h: s...
373
  	*axis = max(0, (int)axis_alignment);
7c7e280aa   Nikita Kiryanov   common lcd: simpl...
374
  }
1ca298ced   Matthias Weisser   Added support for...
375
  #endif
45d7f5251   Tom Wai-Hong Tam   lcd: Implement RL...
376
  #ifdef CONFIG_LCD_BMP_RLE8
45d7f5251   Tom Wai-Hong Tam   lcd: Implement RL...
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
  #define BMP_RLE8_ESCAPE		0
  #define BMP_RLE8_EOL		0
  #define BMP_RLE8_EOBMP		1
  #define BMP_RLE8_DELTA		2
  
  static void draw_unencoded_bitmap(ushort **fbp, uchar *bmap, ushort *cmap,
  				  int cnt)
  {
  	while (cnt > 0) {
  		*(*fbp)++ = cmap[*bmap++];
  		cnt--;
  	}
  }
  
  static void draw_encoded_bitmap(ushort **fbp, ushort c, int cnt)
  {
  	ushort *fb = *fbp;
  	int cnt_8copy = cnt >> 3;
  
  	cnt -= cnt_8copy << 3;
  	while (cnt_8copy > 0) {
  		*fb++ = c;
  		*fb++ = c;
  		*fb++ = c;
  		*fb++ = c;
  		*fb++ = c;
  		*fb++ = c;
  		*fb++ = c;
  		*fb++ = c;
  		cnt_8copy--;
  	}
  	while (cnt > 0) {
  		*fb++ = c;
  		cnt--;
  	}
6b035141f   Jeroen Hofstee   common/lcd: cosme...
412
  	*fbp = fb;
45d7f5251   Tom Wai-Hong Tam   lcd: Implement RL...
413
414
415
  }
  
  /*
6b035141f   Jeroen Hofstee   common/lcd: cosme...
416
   * Do not call this function directly, must be called from lcd_display_bitmap.
45d7f5251   Tom Wai-Hong Tam   lcd: Implement RL...
417
   */
1c3dbe56f   Simon Glass   Remove typedefs f...
418
419
  static void lcd_display_rle8_bitmap(struct bmp_image *bmp, ushort *cmap,
  				    uchar *fb, int x_off, int y_off)
45d7f5251   Tom Wai-Hong Tam   lcd: Implement RL...
420
421
422
423
424
425
  {
  	uchar *bmap;
  	ulong width, height;
  	ulong cnt, runlen;
  	int x, y;
  	int decode = 1;
dca2a1c18   Przemyslaw Marczak   common: lcd.c: fi...
426
427
428
  	width = get_unaligned_le32(&bmp->header.width);
  	height = get_unaligned_le32(&bmp->header.height);
  	bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
45d7f5251   Tom Wai-Hong Tam   lcd: Implement RL...
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
  
  	x = 0;
  	y = height - 1;
  
  	while (decode) {
  		if (bmap[0] == BMP_RLE8_ESCAPE) {
  			switch (bmap[1]) {
  			case BMP_RLE8_EOL:
  				/* end of line */
  				bmap += 2;
  				x = 0;
  				y--;
  				/* 16bpix, 2-byte per pixel, width should *2 */
  				fb -= (width * 2 + lcd_line_length);
  				break;
  			case BMP_RLE8_EOBMP:
  				/* end of bitmap */
  				decode = 0;
  				break;
  			case BMP_RLE8_DELTA:
  				/* delta run */
  				x += bmap[2];
  				y -= bmap[3];
  				/* 16bpix, 2-byte per pixel, x should *2 */
  				fb = (uchar *) (lcd_base + (y + y_off - 1)
  					* lcd_line_length + (x + x_off) * 2);
  				bmap += 4;
  				break;
  			default:
  				/* unencoded run */
  				runlen = bmap[1];
  				bmap += 2;
  				if (y < height) {
  					if (x < width) {
  						if (x + runlen > width)
  							cnt = width - x;
  						else
  							cnt = runlen;
  						draw_unencoded_bitmap(
  							(ushort **)&fb,
  							bmap, cmap, cnt);
  					}
  					x += runlen;
  				}
  				bmap += runlen;
  				if (runlen & 1)
  					bmap++;
  			}
  		} else {
  			/* encoded run */
  			if (y < height) {
  				runlen = bmap[0];
  				if (x < width) {
  					/* aggregate the same code */
  					while (bmap[0] == 0xff &&
  					       bmap[2] != BMP_RLE8_ESCAPE &&
  					       bmap[1] == bmap[3]) {
  						runlen += bmap[2];
  						bmap += 2;
  					}
  					if (x + runlen > width)
  						cnt = width - x;
  					else
  						cnt = runlen;
  					draw_encoded_bitmap((ushort **)&fb,
  						cmap[bmap[1]], cnt);
  				}
  				x += runlen;
  			}
  			bmap += 2;
  		}
  	}
  }
  #endif
27fad01b7   Nikita Kiryanov   lcd: mpc8xx: move...
503
504
505
506
  __weak void fb_put_byte(uchar **fb, uchar **from)
  {
  	*(*fb)++ = *(*from)++;
  }
bfdcc65e1   Nikita Kiryanov   common lcd: simpl...
507
508
  
  #if defined(CONFIG_BMP_16BPP)
b3d12e9bc   Nikita Kiryanov   lcd: atmel: move ...
509
  __weak void fb_put_word(uchar **fb, uchar **from)
bfdcc65e1   Nikita Kiryanov   common lcd: simpl...
510
511
512
513
  {
  	*(*fb)++ = *(*from)++;
  	*(*fb)++ = *(*from)++;
  }
bfdcc65e1   Nikita Kiryanov   common lcd: simpl...
514
  #endif /* CONFIG_BMP_16BPP */
1c3dbe56f   Simon Glass   Remove typedefs f...
515
  __weak void lcd_set_cmap(struct bmp_image *bmp, unsigned colors)
0b29a8969   Nikita Kiryanov   lcd: introduce lc...
516
517
  {
  	int i;
1c3dbe56f   Simon Glass   Remove typedefs f...
518
  	struct bmp_color_table_entry cte;
0b29a8969   Nikita Kiryanov   lcd: introduce lc...
519
520
521
522
523
524
525
  	ushort *cmap = configuration_get_cmap();
  
  	for (i = 0; i < colors; ++i) {
  		cte = bmp->color_table[i];
  		*cmap = (((cte.red)   << 8) & 0xf800) |
  			(((cte.green) << 3) & 0x07e0) |
  			(((cte.blue)  >> 3) & 0x001f);
0b29a8969   Nikita Kiryanov   lcd: introduce lc...
526
  		cmap++;
0b29a8969   Nikita Kiryanov   lcd: introduce lc...
527
528
  	}
  }
8655b6f86   wdenk   * Clean up tools/...
529
530
  int lcd_display_bitmap(ulong bmp_image, int x, int y)
  {
00cc5595a   Anatolij Gustschin   lcd: Fix compilat...
531
  	ushort *cmap_base = NULL;
8655b6f86   wdenk   * Clean up tools/...
532
533
  	ushort i, j;
  	uchar *fb;
1c3dbe56f   Simon Glass   Remove typedefs f...
534
  	struct bmp_image *bmp = (struct bmp_image *)map_sysmem(bmp_image, 0);
8655b6f86   wdenk   * Clean up tools/...
535
  	uchar *bmap;
fecac46cf   Tom Wai-Hong Tam   lcd: Fix BMP deco...
536
  	ushort padded_width;
b245e65ee   Guennadi Liakhovetski   LCD: support 8bpp...
537
  	unsigned long width, height, byte_width;
e8143e72e   Wolfgang Denk   Add splashscreen ...
538
  	unsigned long pwidth = panel_info.vl_col;
b245e65ee   Guennadi Liakhovetski   LCD: support 8bpp...
539
  	unsigned colors, bpix, bmp_bpix;
8d379f179   Simon Glass   lcd: Support colo...
540
  	int hdr_size;
021414a33   xypron.glpk@gmx.de   lcd: avoid possib...
541
  	struct bmp_color_table_entry *palette;
8655b6f86   wdenk   * Clean up tools/...
542

6b035141f   Jeroen Hofstee   common/lcd: cosme...
543
544
  	if (!bmp || !(bmp->header.signature[0] == 'B' &&
  		bmp->header.signature[1] == 'M')) {
8f47d917c   Nikita Kiryanov   common lcd: minor...
545
546
  		printf("Error: no valid bmp image at %lx
  ", bmp_image);
8655b6f86   wdenk   * Clean up tools/...
547
  		return 1;
b245e65ee   Guennadi Liakhovetski   LCD: support 8bpp...
548
  	}
8655b6f86   wdenk   * Clean up tools/...
549

021414a33   xypron.glpk@gmx.de   lcd: avoid possib...
550
  	palette = bmp->color_table;
dca2a1c18   Przemyslaw Marczak   common: lcd.c: fi...
551
552
553
  	width = get_unaligned_le32(&bmp->header.width);
  	height = get_unaligned_le32(&bmp->header.height);
  	bmp_bpix = get_unaligned_le16(&bmp->header.bit_count);
8d379f179   Simon Glass   lcd: Support colo...
554
555
556
  	hdr_size = get_unaligned_le16(&bmp->header.size);
  	debug("hdr_size=%d, bmp_bpix=%d
  ", hdr_size, bmp_bpix);
dca2a1c18   Przemyslaw Marczak   common: lcd.c: fi...
557

b245e65ee   Guennadi Liakhovetski   LCD: support 8bpp...
558
  	colors = 1 << bmp_bpix;
8655b6f86   wdenk   * Clean up tools/...
559
560
  
  	bpix = NBITS(panel_info.vl_bpix);
6b035141f   Jeroen Hofstee   common/lcd: cosme...
561
  	if (bpix != 1 && bpix != 8 && bpix != 16 && bpix != 32) {
b245e65ee   Guennadi Liakhovetski   LCD: support 8bpp...
562
563
564
  		printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel
  ",
  			bpix, bmp_bpix);
8f47d917c   Nikita Kiryanov   common lcd: minor...
565

8655b6f86   wdenk   * Clean up tools/...
566
567
  		return 1;
  	}
a305fb155   Hannes Petermaier   lcd: support disp...
568
569
570
571
572
573
574
  	/*
  	 * We support displaying 8bpp BMPs on 16bpp LCDs
  	 * and displaying 24bpp BMPs on 32bpp LCDs
  	 * */
  	if (bpix != bmp_bpix &&
  	    !(bmp_bpix == 8 && bpix == 16) &&
  	    !(bmp_bpix == 24 && bpix == 32)) {
8655b6f86   wdenk   * Clean up tools/...
575
576
  		printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel
  ",
dca2a1c18   Przemyslaw Marczak   common: lcd.c: fi...
577
  			bpix, get_unaligned_le16(&bmp->header.bit_count));
8655b6f86   wdenk   * Clean up tools/...
578
579
  		return 1;
  	}
8d379f179   Simon Glass   lcd: Support colo...
580
581
582
  	debug("Display-bmp: %d x %d  with %d colors, display %d
  ",
  	      (int)width, (int)height, (int)colors, 1 << bpix);
8655b6f86   wdenk   * Clean up tools/...
583

0b29a8969   Nikita Kiryanov   lcd: introduce lc...
584
585
  	if (bmp_bpix == 8)
  		lcd_set_cmap(bmp, colors);
e8143e72e   Wolfgang Denk   Add splashscreen ...
586

6b035141f   Jeroen Hofstee   common/lcd: cosme...
587
  	padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width);
1ca298ced   Matthias Weisser   Added support for...
588
589
  
  #ifdef CONFIG_SPLASH_SCREEN_ALIGN
7c7e280aa   Nikita Kiryanov   common lcd: simpl...
590
591
  	splash_align_axis(&x, pwidth, width);
  	splash_align_axis(&y, panel_info.vl_row, height);
1ca298ced   Matthias Weisser   Added support for...
592
  #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
8f47d917c   Nikita Kiryanov   common lcd: minor...
593
  	if ((x + width) > pwidth)
e8143e72e   Wolfgang Denk   Add splashscreen ...
594
  		width = pwidth - x;
8f47d917c   Nikita Kiryanov   common lcd: minor...
595
  	if ((y + height) > panel_info.vl_row)
8655b6f86   wdenk   * Clean up tools/...
596
  		height = panel_info.vl_row - y;
dca2a1c18   Przemyslaw Marczak   common: lcd.c: fi...
597
598
  	bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
  	fb   = (uchar *)(lcd_base +
8d46d5b18   Liu Ying   lcd: align fb wri...
599
  		(y + height - 1) * lcd_line_length + x * bpix / 8);
a303dfb0e   Mark Jackson   Add 16bpp BMP sup...
600

b245e65ee   Guennadi Liakhovetski   LCD: support 8bpp...
601
  	switch (bmp_bpix) {
c8d2febcc   Nikita Kiryanov   lcd: various clea...
602
  	case 1:
0156444cf   Simon Glass   lcd: Fix build er...
603
  	case 8: {
0b29a8969   Nikita Kiryanov   lcd: introduce lc...
604
  		cmap_base = configuration_get_cmap();
45d7f5251   Tom Wai-Hong Tam   lcd: Implement RL...
605
  #ifdef CONFIG_LCD_BMP_RLE8
dca2a1c18   Przemyslaw Marczak   common: lcd.c: fi...
606
  		u32 compression = get_unaligned_le32(&bmp->header.compression);
8d379f179   Simon Glass   lcd: Support colo...
607
608
  		debug("compressed %d %d
  ", compression, BMP_BI_RLE8);
dca2a1c18   Przemyslaw Marczak   common: lcd.c: fi...
609
  		if (compression == BMP_BI_RLE8) {
45d7f5251   Tom Wai-Hong Tam   lcd: Implement RL...
610
611
612
613
614
615
616
617
618
  			if (bpix != 16) {
  				/* TODO implement render code for bpix != 16 */
  				printf("Error: only support 16 bpix");
  				return 1;
  			}
  			lcd_display_rle8_bitmap(bmp, cmap_base, fb, x, y);
  			break;
  		}
  #endif
b245e65ee   Guennadi Liakhovetski   LCD: support 8bpp...
619
620
621
622
  		if (bpix != 16)
  			byte_width = width;
  		else
  			byte_width = width * 2;
a303dfb0e   Mark Jackson   Add 16bpp BMP sup...
623
624
  		for (i = 0; i < height; ++i) {
  			WATCHDOG_RESET();
b245e65ee   Guennadi Liakhovetski   LCD: support 8bpp...
625
626
  			for (j = 0; j < width; j++) {
  				if (bpix != 16) {
27fad01b7   Nikita Kiryanov   lcd: mpc8xx: move...
627
  					fb_put_byte(&fb, &bmap);
b245e65ee   Guennadi Liakhovetski   LCD: support 8bpp...
628
  				} else {
8d379f179   Simon Glass   lcd: Support colo...
629
630
631
632
633
634
635
636
637
638
639
640
641
  					struct bmp_color_table_entry *entry;
  					uint val;
  
  					if (cmap_base) {
  						val = cmap_base[*bmap];
  					} else {
  						entry = &palette[*bmap];
  						val = entry->blue >> 3 |
  							entry->green >> 2 << 5 |
  							entry->red >> 3 << 11;
  					}
  					*(uint16_t *)fb = val;
  					bmap++;
b245e65ee   Guennadi Liakhovetski   LCD: support 8bpp...
642
643
644
  					fb += sizeof(uint16_t) / sizeof(*fb);
  				}
  			}
fecac46cf   Tom Wai-Hong Tam   lcd: Fix BMP deco...
645
  			bmap += (padded_width - width);
6b035141f   Jeroen Hofstee   common/lcd: cosme...
646
  			fb -= byte_width + lcd_line_length;
a303dfb0e   Mark Jackson   Add 16bpp BMP sup...
647
648
  		}
  		break;
0156444cf   Simon Glass   lcd: Fix build er...
649
  	}
a303dfb0e   Mark Jackson   Add 16bpp BMP sup...
650
651
652
653
  #if defined(CONFIG_BMP_16BPP)
  	case 16:
  		for (i = 0; i < height; ++i) {
  			WATCHDOG_RESET();
bfdcc65e1   Nikita Kiryanov   common lcd: simpl...
654
655
  			for (j = 0; j < width; j++)
  				fb_put_word(&fb, &bmap);
fecac46cf   Tom Wai-Hong Tam   lcd: Fix BMP deco...
656
  			bmap += (padded_width - width) * 2;
6b035141f   Jeroen Hofstee   common/lcd: cosme...
657
  			fb -= width * 2 + lcd_line_length;
a303dfb0e   Mark Jackson   Add 16bpp BMP sup...
658
659
660
  		}
  		break;
  #endif /* CONFIG_BMP_16BPP */
10ba6b333   Philipp Tomsich   video: bmp: renam...
661
  #if defined(CONFIG_BMP_24BPP)
a305fb155   Hannes Petermaier   lcd: support disp...
662
663
664
665
666
667
668
669
670
671
672
  	case 24:
  		for (i = 0; i < height; ++i) {
  			for (j = 0; j < width; j++) {
  				*(fb++) = *(bmap++);
  				*(fb++) = *(bmap++);
  				*(fb++) = *(bmap++);
  				*(fb++) = 0;
  			}
  			fb -= lcd_line_length + width * (bpix / 8);
  		}
  		break;
10ba6b333   Philipp Tomsich   video: bmp: renam...
673
  #endif /* CONFIG_BMP_24BPP */
fb6a9aab7   Donghwa Lee   LCD: display 32bp...
674
675
676
677
678
679
680
681
682
  #if defined(CONFIG_BMP_32BPP)
  	case 32:
  		for (i = 0; i < height; ++i) {
  			for (j = 0; j < width; j++) {
  				*(fb++) = *(bmap++);
  				*(fb++) = *(bmap++);
  				*(fb++) = *(bmap++);
  				*(fb++) = *(bmap++);
  			}
6b035141f   Jeroen Hofstee   common/lcd: cosme...
683
  			fb -= lcd_line_length + width * (bpix / 8);
fb6a9aab7   Donghwa Lee   LCD: display 32bp...
684
685
686
  		}
  		break;
  #endif /* CONFIG_BMP_32BPP */
a303dfb0e   Mark Jackson   Add 16bpp BMP sup...
687
688
689
  	default:
  		break;
  	};
8655b6f86   wdenk   * Clean up tools/...
690

9a8efc460   Simon Glass   lcd: Add support ...
691
  	lcd_sync();
8f47d917c   Nikita Kiryanov   common lcd: minor...
692
  	return 0;
8655b6f86   wdenk   * Clean up tools/...
693
  }
c3517f919   Jon Loeliger   common/* non-cmd*...
694
  #endif
8655b6f86   wdenk   * Clean up tools/...
695

7bf71d1f5   Nikita Kiryanov   lcd: split splash...
696
  static void lcd_logo(void)
8655b6f86   wdenk   * Clean up tools/...
697
  {
bf21a5deb   Nikita Kiryanov   lcd: rename bitma...
698
  	lcd_logo_plot(0, 0);
8655b6f86   wdenk   * Clean up tools/...
699

6b59e03e0   Haavard Skinnemoen   lcd: Let the boar...
700
  #ifdef CONFIG_LCD_INFO
140beb943   Nikita Kiryanov   lcd: expand conso...
701
702
  	lcd_set_col(LCD_INFO_X / VIDEO_FONT_WIDTH);
  	lcd_set_row(LCD_INFO_Y / VIDEO_FONT_HEIGHT);
6b59e03e0   Haavard Skinnemoen   lcd: Let the boar...
703
704
  	lcd_show_board_info();
  #endif /* CONFIG_LCD_INFO */
8655b6f86   wdenk   * Clean up tools/...
705
  }
c08804853   Nikita Kiryanov   lcd: implement a ...
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
  #ifdef CONFIG_SPLASHIMAGE_GUARD
  static int on_splashimage(const char *name, const char *value, enum env_op op,
  	int flags)
  {
  	ulong addr;
  	int aligned;
  
  	if (op == env_op_delete)
  		return 0;
  
  	addr = simple_strtoul(value, NULL, 16);
  	/* See README.displaying-bmps */
  	aligned = (addr % 4 == 2);
  	if (!aligned) {
  		printf("Invalid splashimage value. Value must be 16 bit aligned, but not 32 bit aligned
  ");
  		return -1;
  	}
  
  	return 0;
  }
  
  U_BOOT_ENV_CALLBACK(splashimage, on_splashimage);
  #endif
395166cff   Vadim Bendebury   lcd: Provide an A...
730
731
732
733
734
735
736
737
738
  int lcd_get_pixel_width(void)
  {
  	return panel_info.vl_col;
  }
  
  int lcd_get_pixel_height(void)
  {
  	return panel_info.vl_row;
  }