]> git.ipfire.org Git - people/ms/u-boot.git/blob - board/esd/common/lcd.c
drivers, block: remove sil680 driver
[people/ms/u-boot.git] / board / esd / common / lcd.c
1 /*
2 * (C) Copyright 2003-2004
3 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
4 *
5 * (C) Copyright 2005
6 * Stefan Roese, DENX Software Engineering, sr@denx.de.
7 *
8 * SPDX-License-Identifier: GPL-2.0+
9 */
10
11 #include <asm/io.h>
12 #include "lcd.h"
13
14
15 extern int video_display_bitmap (ulong, int, int);
16
17
18 int palette_index;
19 int palette_value;
20 int lcd_depth;
21 unsigned char *glob_lcd_reg;
22 unsigned char *glob_lcd_mem;
23
24 #if defined(CONFIG_SYS_LCD_ENDIAN)
25 void lcd_setup(int lcd, int config)
26 {
27 if (lcd == 0) {
28 /*
29 * Set endianess and reset lcd controller 0 (small)
30 */
31
32 /* set reset to low */
33 out_be32((void*)GPIO0_OR,
34 in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD0_RST);
35 udelay(10); /* wait 10us */
36 if (config == 1) {
37 /* big-endian */
38 out_be32((void*)GPIO0_OR,
39 in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD_ENDIAN);
40 } else {
41 /* little-endian */
42 out_be32((void*)GPIO0_OR,
43 in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD_ENDIAN);
44 }
45 udelay(10); /* wait 10us */
46 /* set reset to high */
47 out_be32((void*)GPIO0_OR,
48 in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD0_RST);
49 } else {
50 /*
51 * Set endianess and reset lcd controller 1 (big)
52 */
53
54 /* set reset to low */
55 out_be32((void*)GPIO0_OR,
56 in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD1_RST);
57 udelay(10); /* wait 10us */
58 if (config == 1) {
59 /* big-endian */
60 out_be32((void*)GPIO0_OR,
61 in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD_ENDIAN);
62 } else {
63 /* little-endian */
64 out_be32((void*)GPIO0_OR,
65 in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD_ENDIAN);
66 }
67 udelay(10); /* wait 10us */
68 /* set reset to high */
69 out_be32((void*)GPIO0_OR,
70 in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD1_RST);
71 }
72
73 /*
74 * CONFIG_SYS_LCD_ENDIAN may also be FPGA_RESET, so set inactive
75 */
76 out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD_ENDIAN);
77 }
78 #endif /* CONFIG_SYS_LCD_ENDIAN */
79
80
81 int lcd_bmp(uchar *logo_bmp)
82 {
83 int i;
84 uchar *ptr;
85 ushort *ptr2;
86 ushort val;
87 unsigned char *dst = NULL;
88 int x, y;
89 int width, height, bpp, colors, line_size;
90 int header_size;
91 unsigned char *bmp;
92 unsigned char r, g, b;
93 BITMAPINFOHEADER *bm_info;
94 ulong len;
95
96 /*
97 * Check for bmp mark 'BM'
98 */
99 if (*(ushort *)logo_bmp != 0x424d) {
100 /*
101 * Decompress bmp image
102 */
103 len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
104 dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
105 if (dst == NULL) {
106 printf("Error: malloc for gunzip failed!\n");
107 return 1;
108 }
109 if (gunzip(dst, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE,
110 (uchar *)logo_bmp, &len) != 0) {
111 free(dst);
112 return 1;
113 }
114 if (len == CONFIG_SYS_VIDEO_LOGO_MAX_SIZE) {
115 printf("Image could be truncated"
116 " (increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n");
117 }
118
119 /*
120 * Check for bmp mark 'BM'
121 */
122 if (*(ushort *)dst != 0x424d) {
123 printf("LCD: Unknown image format!\n");
124 free(dst);
125 return 1;
126 }
127 } else {
128 /*
129 * Uncompressed BMP image, just use this pointer
130 */
131 dst = (uchar *)logo_bmp;
132 }
133
134 /*
135 * Get image info from bmp-header
136 */
137 bm_info = (BITMAPINFOHEADER *)(dst + 14);
138 bpp = LOAD_SHORT(bm_info->biBitCount);
139 width = LOAD_LONG(bm_info->biWidth);
140 height = LOAD_LONG(bm_info->biHeight);
141 switch (bpp) {
142 case 1:
143 colors = 1;
144 line_size = width >> 3;
145 break;
146 case 4:
147 colors = 16;
148 line_size = width >> 1;
149 break;
150 case 8:
151 colors = 256;
152 line_size = width;
153 break;
154 case 24:
155 colors = 0;
156 line_size = width * 3;
157 break;
158 default:
159 printf("LCD: Unknown bpp (%d) im image!\n", bpp);
160 if ((dst != NULL) && (dst != (uchar *)logo_bmp))
161 free(dst);
162 return 1;
163 }
164 printf(" (%d*%d, %dbpp)\n", width, height, bpp);
165
166 /*
167 * Write color palette
168 */
169 if ((colors <= 256) && (lcd_depth <= 8)) {
170 ptr = (unsigned char *)(dst + 14 + 40);
171 for (i = 0; i < colors; i++) {
172 b = *ptr++;
173 g = *ptr++;
174 r = *ptr++;
175 ptr++;
176 S1D_WRITE_PALETTE(glob_lcd_reg, i, r, g, b);
177 }
178 }
179
180 /*
181 * Write bitmap data into framebuffer
182 */
183 ptr = glob_lcd_mem;
184 ptr2 = (ushort *)glob_lcd_mem;
185 header_size = 14 + 40 + 4*colors; /* skip bmp header */
186 for (y = 0; y < height; y++) {
187 bmp = &dst[(height-1-y)*line_size + header_size];
188 if (lcd_depth == 16) {
189 if (bpp == 24) {
190 for (x = 0; x < width; x++) {
191 /*
192 * Generate epson 16bpp fb-format
193 * from 24bpp image
194 */
195 b = *bmp++ >> 3;
196 g = *bmp++ >> 2;
197 r = *bmp++ >> 3;
198 val = ((r & 0x1f) << 11) |
199 ((g & 0x3f) << 5) |
200 (b & 0x1f);
201 *ptr2++ = val;
202 }
203 } else if (bpp == 8) {
204 for (x = 0; x < line_size; x++) {
205 /* query rgb value from palette */
206 ptr = (unsigned char *)(dst + 14 + 40);
207 ptr += (*bmp++) << 2;
208 b = *ptr++ >> 3;
209 g = *ptr++ >> 2;
210 r = *ptr++ >> 3;
211 val = ((r & 0x1f) << 11) |
212 ((g & 0x3f) << 5) |
213 (b & 0x1f);
214 *ptr2++ = val;
215 }
216 }
217 } else {
218 for (x = 0; x < line_size; x++)
219 *ptr++ = *bmp++;
220 }
221 }
222
223 if ((dst != NULL) && (dst != (uchar *)logo_bmp))
224 free(dst);
225 return 0;
226 }
227
228
229 int lcd_init(uchar *lcd_reg, uchar *lcd_mem, S1D_REGS *regs, int reg_count,
230 uchar *logo_bmp, ulong len)
231 {
232 int i;
233 ushort s1dReg;
234 uchar s1dValue;
235 int reg_byte_swap;
236
237 /*
238 * Detect epson
239 */
240 out_8(&lcd_reg[0], 0x00);
241 out_8(&lcd_reg[1], 0x00);
242
243 if (in_8(&lcd_reg[0]) == 0x1c) {
244 /*
245 * Big epson detected
246 */
247 reg_byte_swap = false;
248 palette_index = 0x1e2;
249 palette_value = 0x1e4;
250 lcd_depth = 16;
251 puts("LCD: S1D13806");
252 } else if (in_8(&lcd_reg[1]) == 0x1c) {
253 /*
254 * Big epson detected (with register swap bug)
255 */
256 reg_byte_swap = true;
257 palette_index = 0x1e3;
258 palette_value = 0x1e5;
259 lcd_depth = 16;
260 puts("LCD: S1D13806S");
261 } else if (in_8(&lcd_reg[0]) == 0x18) {
262 /*
263 * Small epson detected (704)
264 */
265 reg_byte_swap = false;
266 palette_index = 0x15;
267 palette_value = 0x17;
268 lcd_depth = 8;
269 puts("LCD: S1D13704");
270 } else if (in_8(&lcd_reg[0x10000]) == 0x24) {
271 /*
272 * Small epson detected (705)
273 */
274 reg_byte_swap = false;
275 palette_index = 0x15;
276 palette_value = 0x17;
277 lcd_depth = 8;
278 lcd_reg += 0x10000; /* add offset for 705 regs */
279 puts("LCD: S1D13705");
280 } else {
281 out_8(&lcd_reg[0x1a], 0x00);
282 udelay(1000);
283 if (in_8(&lcd_reg[1]) == 0x0c) {
284 /*
285 * S1D13505 detected
286 */
287 reg_byte_swap = true;
288 palette_index = 0x25;
289 palette_value = 0x27;
290 lcd_depth = 16;
291
292 puts("LCD: S1D13505");
293 } else {
294 puts("LCD: No controller detected!\n");
295 return 1;
296 }
297 }
298
299 /*
300 * Setup lcd controller regs
301 */
302 for (i = 0; i < reg_count; i++) {
303 s1dReg = regs[i].Index;
304 if (reg_byte_swap) {
305 if ((s1dReg & 0x0001) == 0)
306 s1dReg |= 0x0001;
307 else
308 s1dReg &= ~0x0001;
309 }
310 s1dValue = regs[i].Value;
311 out_8(&lcd_reg[s1dReg], s1dValue);
312 }
313
314 /*
315 * Save reg & mem pointer for later usage (e.g. bmp command)
316 */
317 glob_lcd_reg = lcd_reg;
318 glob_lcd_mem = lcd_mem;
319
320 /*
321 * Display bmp image
322 */
323 return lcd_bmp(logo_bmp);
324 }
325
326 int do_esdbmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
327 {
328 ulong addr;
329 #ifdef CONFIG_VIDEO_SM501
330 char *str;
331 #endif
332 if (argc != 2)
333 return cmd_usage(cmdtp);
334
335 addr = simple_strtoul(argv[1], NULL, 16);
336
337 #ifdef CONFIG_VIDEO_SM501
338 str = getenv("bd_type");
339 if ((strcmp(str, "ppc221") == 0) || (strcmp(str, "ppc231") == 0)) {
340 /*
341 * SM501 available, use standard bmp command
342 */
343 return video_display_bitmap(addr, 0, 0);
344 } else {
345 /*
346 * No SM501 available, use esd epson bmp command
347 */
348 return lcd_bmp((uchar *)addr);
349 }
350 #else
351 return lcd_bmp((uchar *)addr);
352 #endif
353 }
354
355 U_BOOT_CMD(
356 esdbmp, 2, 1, do_esdbmp,
357 "display BMP image",
358 "<imageAddr> - display image"
359 );