]>
Commit | Line | Data |
---|---|---|
50217dee JS |
1 | /* |
2 | * (C) Copyright 2005-2009 | |
3 | * Jens Scharsig @ BuS Elektronik GmbH & Co. KG, <esw@bus-elektronik.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 | #include <common.h> | |
25 | #include <bmp_layout.h> | |
26 | #include <asm/io.h> | |
27 | ||
28 | vu_char *vcxk_bws = ((vu_char *) (CONFIG_SYS_VCXK_BASE)); | |
29 | vu_short *vcxk_bws_word = ((vu_short *)(CONFIG_SYS_VCXK_BASE)); | |
30 | vu_long *vcxk_bws_long = ((vu_long *) (CONFIG_SYS_VCXK_BASE)); | |
31 | ||
32 | #ifdef CONFIG_AT91RM9200 | |
33 | #include <asm/arch/hardware.h> | |
0cf0b931 JS |
34 | #include <asm/arch/at91_pio.h> |
35 | ||
50217dee JS |
36 | #ifndef VCBITMASK |
37 | #define VCBITMASK(bitno) (0x0001 << (bitno % 16)) | |
38 | #endif | |
0cf0b931 JS |
39 | #ifndef CONFIG_AT91_LEGACY |
40 | at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; | |
41 | #define VCXK_INIT_PIN(PORT, PIN, DDR, I0O1) \ | |
42 | do { \ | |
43 | writel(PIN, &pio->PORT.per); \ | |
44 | writel(PIN, &pio->PORT.DDR); \ | |
45 | writel(PIN, &pio->PORT.mddr); \ | |
46 | if (!I0O1) \ | |
47 | writel(PIN, &pio->PORT.puer); \ | |
48 | } while (0); | |
49 | ||
50 | #define VCXK_SET_PIN(PORT, PIN) writel(PIN, &pio->PORT.sodr); | |
51 | #define VCXK_CLR_PIN(PORT, PIN) writel(PIN, &pio->PORT.codr); | |
52 | ||
53 | #define VCXK_ACKNOWLEDGE \ | |
54 | (!(readl(&pio->CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT.pdsr) & \ | |
55 | CONFIG_SYS_VCXK_ACKNOWLEDGE_PIN)) | |
56 | #else | |
50217dee JS |
57 | #define VCXK_INIT_PIN(PORT, PIN, DDR, I0O1) \ |
58 | ((AT91PS_PIO) PORT)->PIO_PER = PIN; \ | |
59 | ((AT91PS_PIO) PORT)->DDR = PIN; \ | |
60 | ((AT91PS_PIO) PORT)->PIO_MDDR = PIN; \ | |
61 | if (!I0O1) ((AT91PS_PIO) PORT)->PIO_PPUER = PIN; | |
62 | ||
63 | #define VCXK_SET_PIN(PORT, PIN) ((AT91PS_PIO) PORT)->PIO_SODR = PIN; | |
64 | #define VCXK_CLR_PIN(PORT, PIN) ((AT91PS_PIO) PORT)->PIO_CODR = PIN; | |
65 | ||
66 | #define VCXK_ACKNOWLEDGE \ | |
67 | (!(((AT91PS_PIO) CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT)->\ | |
68 | PIO_PDSR & CONFIG_SYS_VCXK_ACKNOWLEDGE_PIN)) | |
0cf0b931 | 69 | #endif |
50217dee JS |
70 | #elif defined(CONFIG_MCF52x2) |
71 | #include <asm/m5282.h> | |
72 | #ifndef VCBITMASK | |
73 | #define VCBITMASK(bitno) (0x8000 >> (bitno % 16)) | |
74 | #endif | |
75 | ||
76 | #define VCXK_INIT_PIN(PORT, PIN, DDR, I0O1) \ | |
77 | if (I0O1) DDR |= PIN; else DDR &= ~PIN; | |
78 | ||
79 | #define VCXK_SET_PIN(PORT, PIN) PORT |= PIN; | |
80 | #define VCXK_CLR_PIN(PORT, PIN) PORT &= ~PIN; | |
81 | ||
82 | #define VCXK_ACKNOWLEDGE \ | |
83 | (!(CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT & \ | |
84 | CONFIG_SYS_VCXK_ACKNOWLEDGE_PIN)) | |
85 | ||
86 | #else | |
87 | #error no vcxk support for selected ARCH | |
88 | #endif | |
89 | ||
90 | #define VCXK_DISABLE\ | |
91 | VCXK_SET_PIN(CONFIG_SYS_VCXK_ENABLE_PORT, CONFIG_SYS_VCXK_ENABLE_PIN) | |
92 | #define VCXK_ENABLE\ | |
93 | VCXK_CLR_PIN(CONFIG_SYS_VCXK_ENABLE_PORT, CONFIG_SYS_VCXK_ENABLE_PIN) | |
94 | ||
95 | #ifndef CONFIG_SYS_VCXK_DOUBLEBUFFERED | |
96 | #define VCXK_BWS(x, data) vcxk_bws[x] = data; | |
97 | #define VCXK_BWS_WORD_SET(x, mask) vcxk_bws_word[x] |= mask; | |
98 | #define VCXK_BWS_WORD_CLEAR(x, mask) vcxk_bws_word[x] &= ~mask; | |
99 | #define VCXK_BWS_LONG(x, data) vcxk_bws_long[x] = data; | |
100 | #else | |
101 | u_char double_bws[16384]; | |
102 | u_short *double_bws_word; | |
103 | u_long *double_bws_long; | |
104 | #define VCXK_BWS(x,data) \ | |
105 | double_bws[x] = data; vcxk_bws[x] = data; | |
106 | #define VCXK_BWS_WORD_SET(x,mask) \ | |
107 | double_bws_word[x] |= mask; \ | |
108 | vcxk_bws_word[x] = double_bws_word[x]; | |
109 | #define VCXK_BWS_WORD_CLEAR(x,mask) \ | |
110 | double_bws_word[x] &= ~mask; \ | |
111 | vcxk_bws_word[x] = double_bws_word[x]; | |
112 | #define VCXK_BWS_LONG(x,data) \ | |
113 | double_bws_long[x] = data; vcxk_bws_long[x] = data; | |
114 | #endif | |
115 | ||
116 | #define VC4K16_Bright1 vcxk_bws_word[0x20004 / 2] | |
117 | #define VC4K16_Bright2 vcxk_bws_word[0x20006 / 2] | |
118 | #define VC2K_Bright vcxk_bws[0x8000] | |
119 | #define VC8K_BrightH vcxk_bws[0xC000] | |
120 | #define VC8K_BrightL vcxk_bws[0xC001] | |
121 | ||
122 | vu_char VC4K16; | |
123 | ||
124 | u_long display_width; | |
125 | u_long display_height; | |
126 | u_long display_bwidth; | |
127 | ||
128 | ulong search_vcxk_driver(void); | |
129 | void vcxk_cls(void); | |
130 | void vcxk_setbrightness(unsigned int side, short brightness); | |
131 | int vcxk_request(void); | |
132 | int vcxk_acknowledge_wait(void); | |
133 | void vcxk_clear(void); | |
134 | ||
135 | /* | |
136 | ****f* bus_vcxk/vcxk_init | |
137 | * FUNCTION | |
138 | * initialalize Video Controller | |
139 | * PARAMETERS | |
140 | * width visible display width in pixel | |
141 | * height visible display height in pixel | |
142 | *** | |
143 | */ | |
144 | ||
145 | int vcxk_init(unsigned long width, unsigned long height) | |
146 | { | |
147 | #ifdef CONFIG_SYS_VCXK_RESET_PORT | |
148 | VCXK_INIT_PIN(CONFIG_SYS_VCXK_RESET_PORT, | |
149 | CONFIG_SYS_VCXK_RESET_PIN, CONFIG_SYS_VCXK_RESET_DDR, 1) | |
150 | VCXK_SET_PIN(CONFIG_SYS_VCXK_RESET_PORT, CONFIG_SYS_VCXK_RESET_PIN); | |
151 | #endif | |
152 | ||
153 | #ifdef CONFIG_SYS_VCXK_DOUBLEBUFFERED | |
04538cdb | 154 | double_bws_word = (u_short *)double_bws; |
50217dee JS |
155 | double_bws_long = (u_long *)double_bws; |
156 | debug("%lx %lx %lx \n", double_bws, double_bws_word, double_bws_long); | |
157 | #endif | |
158 | display_width = width; | |
159 | display_height = height; | |
160 | #if (CONFIG_SYS_VCXK_DEFAULT_LINEALIGN == 4) | |
161 | display_bwidth = ((width + 31) / 8) & ~0x3; | |
162 | #elif (CONFIG_SYS_VCXK_DEFAULT_LINEALIGN == 2) | |
163 | display_bwidth = ((width + 15) / 8) & ~0x1; | |
164 | #else | |
165 | #error CONFIG_SYS_VCXK_DEFAULT_LINEALIGN is invalid | |
166 | #endif | |
167 | debug("linesize ((%d + 15) / 8 & ~0x1) = %d\n", | |
168 | display_width, display_bwidth); | |
169 | ||
170 | #ifdef CONFIG_SYS_VCXK_AUTODETECT | |
171 | VC4K16 = 0; | |
172 | vcxk_bws_long[1] = 0x0; | |
173 | vcxk_bws_long[1] = 0x55AAAA55; | |
174 | vcxk_bws_long[5] = 0x0; | |
04538cdb AG |
175 | if (vcxk_bws_long[1] == 0x55AAAA55) |
176 | VC4K16 = 1; | |
50217dee JS |
177 | #else |
178 | VC4K16 = 1; | |
179 | debug("No autodetect: use vc4k\n"); | |
180 | #endif | |
181 | ||
182 | VCXK_INIT_PIN(CONFIG_SYS_VCXK_INVERT_PORT, | |
183 | CONFIG_SYS_VCXK_INVERT_PIN, CONFIG_SYS_VCXK_INVERT_DDR, 1) | |
184 | VCXK_SET_PIN(CONFIG_SYS_VCXK_INVERT_PORT, CONFIG_SYS_VCXK_INVERT_PIN) | |
185 | ||
186 | VCXK_SET_PIN(CONFIG_SYS_VCXK_REQUEST_PORT, CONFIG_SYS_VCXK_REQUEST_PIN); | |
187 | VCXK_INIT_PIN(CONFIG_SYS_VCXK_REQUEST_PORT, | |
188 | CONFIG_SYS_VCXK_REQUEST_PIN, CONFIG_SYS_VCXK_REQUEST_DDR, 1) | |
189 | ||
190 | VCXK_INIT_PIN(CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT, | |
191 | CONFIG_SYS_VCXK_ACKNOWLEDGE_PIN, | |
192 | CONFIG_SYS_VCXK_ACKNOWLEDGE_DDR, 0) | |
193 | ||
194 | VCXK_DISABLE; | |
195 | VCXK_INIT_PIN(CONFIG_SYS_VCXK_ENABLE_PORT, | |
196 | CONFIG_SYS_VCXK_ENABLE_PIN, CONFIG_SYS_VCXK_ENABLE_DDR, 1) | |
197 | ||
198 | vcxk_cls(); | |
199 | vcxk_cls(); /* clear second/hidden page */ | |
200 | ||
201 | vcxk_setbrightness(3, 1000); | |
202 | VCXK_ENABLE; | |
203 | return 1; | |
204 | } | |
205 | ||
206 | /* | |
207 | ****f* bus_vcxk/vcxk_setpixel | |
208 | * FUNCTION | |
209 | * set the pixel[x,y] with the given color | |
210 | * PARAMETER | |
211 | * x pixel colum | |
212 | * y pixel row | |
213 | * color <0x40 off/black | |
214 | * >0x40 on | |
215 | *** | |
216 | */ | |
217 | ||
218 | void vcxk_setpixel(int x, int y, unsigned long color) | |
219 | { | |
220 | vu_short dataptr; | |
221 | ||
222 | if ((x < display_width) && (y < display_height)) { | |
223 | dataptr = ((x / 16)) + (y * (display_bwidth >> 1)); | |
224 | ||
225 | color = ((color >> 16) & 0xFF) | | |
226 | ((color >> 8) & 0xFF) | (color & 0xFF); | |
227 | ||
228 | if (color > 0x40) { | |
229 | VCXK_BWS_WORD_SET(dataptr, VCBITMASK(x)); | |
230 | } else { | |
231 | VCXK_BWS_WORD_CLEAR(dataptr, VCBITMASK(x)); | |
232 | } | |
233 | } | |
234 | } | |
235 | ||
236 | /* | |
237 | ****f* bus_vcxk/vcxk_loadimage | |
238 | * FUNCTION | |
239 | * copies a binary image to display memory | |
240 | *** | |
241 | */ | |
242 | ||
243 | void vcxk_loadimage(ulong source) | |
244 | { | |
245 | int cnt; | |
246 | vcxk_acknowledge_wait(); | |
247 | if (VC4K16) { | |
248 | for (cnt = 0; cnt < (16384 / 4); cnt++) { | |
249 | VCXK_BWS_LONG(cnt, (*(ulong *) source)); | |
250 | source = source + 4; | |
251 | } | |
252 | } else { | |
253 | for (cnt = 0; cnt < 16384; cnt++) { | |
254 | VCXK_BWS_LONG(cnt*2, (*(vu_char *) source)); | |
255 | source++; | |
256 | } | |
257 | } | |
258 | vcxk_request(); | |
259 | } | |
260 | ||
261 | /* | |
262 | ****f* bus_vcxk/vcxk_cls | |
263 | * FUNCTION | |
264 | * clear the display | |
265 | *** | |
266 | */ | |
267 | ||
268 | void vcxk_cls(void) | |
269 | { | |
270 | vcxk_acknowledge_wait(); | |
271 | vcxk_clear(); | |
272 | vcxk_request(); | |
273 | } | |
274 | ||
275 | /* | |
276 | ****f* bus_vcxk/vcxk_clear(void) | |
277 | * FUNCTION | |
278 | * clear the display memory | |
279 | *** | |
280 | */ | |
281 | ||
282 | void vcxk_clear(void) | |
283 | { | |
284 | int cnt; | |
04538cdb | 285 | |
50217dee JS |
286 | for (cnt = 0; cnt < (16384 / 4); cnt++) { |
287 | VCXK_BWS_LONG(cnt, 0) | |
288 | } | |
289 | } | |
290 | ||
291 | /* | |
292 | ****f* bus_vcxk/vcxk_setbrightness | |
293 | * FUNCTION | |
294 | * set the display brightness | |
295 | * PARAMETER | |
296 | * side 1 set front side brightness | |
297 | * 2 set back side brightness | |
298 | * 3 set brightness for both sides | |
299 | * brightness 0..1000 | |
300 | *** | |
301 | */ | |
302 | ||
303 | void vcxk_setbrightness(unsigned int side, short brightness) | |
304 | { | |
305 | if (VC4K16) { | |
306 | if ((side == 0) || (side & 0x1)) | |
307 | VC4K16_Bright1 = brightness + 23; | |
308 | if ((side == 0) || (side & 0x2)) | |
309 | VC4K16_Bright2 = brightness + 23; | |
310 | } else { | |
311 | VC2K_Bright = (brightness >> 4) + 2; | |
312 | VC8K_BrightH = (brightness + 23) >> 8; | |
313 | VC8K_BrightL = (brightness + 23) & 0xFF; | |
314 | } | |
315 | } | |
316 | ||
317 | /* | |
318 | ****f* bus_vcxk/vcxk_request | |
319 | * FUNCTION | |
320 | * requests viewing of display memory | |
321 | *** | |
322 | */ | |
323 | ||
324 | int vcxk_request(void) | |
325 | { | |
326 | VCXK_CLR_PIN(CONFIG_SYS_VCXK_REQUEST_PORT, | |
327 | CONFIG_SYS_VCXK_REQUEST_PIN) | |
328 | VCXK_SET_PIN(CONFIG_SYS_VCXK_REQUEST_PORT, | |
329 | CONFIG_SYS_VCXK_REQUEST_PIN); | |
330 | return 1; | |
331 | } | |
332 | ||
333 | /* | |
334 | ****f* bus_vcxk/vcxk_acknowledge_wait | |
335 | * FUNCTION | |
336 | * wait for acknowledge viewing requests | |
337 | *** | |
338 | */ | |
339 | ||
340 | int vcxk_acknowledge_wait(void) | |
341 | { | |
04538cdb AG |
342 | while (VCXK_ACKNOWLEDGE) |
343 | ; | |
50217dee JS |
344 | return 1; |
345 | } | |
346 | ||
347 | /* | |
348 | ****f* bus_vcxk/vcxk_draw_mono | |
349 | * FUNCTION | |
350 | * copies a monochrom bitmap (BMP-Format) from given memory | |
351 | * PARAMETER | |
352 | * dataptr pointer to bitmap | |
353 | * x output bitmap @ columne | |
354 | * y output bitmap @ row | |
355 | *** | |
356 | */ | |
357 | ||
04538cdb | 358 | void vcxk_draw_mono(unsigned char *dataptr, unsigned long linewidth, |
50217dee JS |
359 | unsigned long cp_width, unsigned long cp_height) |
360 | { | |
361 | unsigned char *lineptr; | |
362 | unsigned long xcnt, ycnt; | |
363 | ||
364 | for (ycnt = cp_height; ycnt > 0; ycnt--) { | |
365 | lineptr = dataptr; | |
366 | for (xcnt = 0; xcnt < cp_width; xcnt++) { | |
367 | if ((*lineptr << (xcnt % 8)) & 0x80) | |
368 | vcxk_setpixel(xcnt, ycnt - 1, 0xFFFFFF); | |
369 | else | |
370 | vcxk_setpixel(xcnt, ycnt-1, 0); | |
371 | ||
04538cdb AG |
372 | if ((xcnt % 8) == 7) |
373 | lineptr++; | |
50217dee JS |
374 | } /* endfor xcnt */ |
375 | dataptr = dataptr + linewidth; | |
376 | } /* endfor ycnt */ | |
377 | } | |
378 | ||
379 | /* | |
380 | ****f* bus_vcxk/vcxk_display_bitmap | |
381 | * FUNCTION | |
382 | * copies a bitmap (BMP-Format) to the given position | |
383 | * PARAMETER | |
384 | * addr pointer to bitmap | |
385 | * x output bitmap @ columne | |
386 | * y output bitmap @ row | |
387 | *** | |
388 | */ | |
389 | ||
390 | int vcxk_display_bitmap(ulong addr, int x, int y) | |
391 | { | |
392 | bmp_image_t *bmp; | |
393 | unsigned long width; | |
394 | unsigned long height; | |
395 | unsigned long bpp; | |
396 | unsigned long compression; | |
397 | ||
398 | unsigned long lw; | |
399 | ||
400 | unsigned long c_width; | |
401 | unsigned long c_height; | |
402 | unsigned char *dataptr; | |
50217dee JS |
403 | |
404 | bmp = (bmp_image_t *) addr; | |
405 | if ((bmp->header.signature[0] == 'B') && | |
406 | (bmp->header.signature[1] == 'M')) { | |
407 | compression = le32_to_cpu(bmp->header.compression); | |
408 | width = le32_to_cpu(bmp->header.width); | |
409 | height = le32_to_cpu(bmp->header.height); | |
410 | bpp = le16_to_cpu(bmp->header.bit_count); | |
411 | ||
412 | dataptr = (unsigned char *) bmp + | |
413 | le32_to_cpu(bmp->header.data_offset); | |
414 | ||
415 | if (display_width < (width + x)) | |
416 | c_width = display_width - x; | |
417 | else | |
418 | c_width = width; | |
419 | if (display_height < (height + y)) | |
420 | c_height = display_height - y; | |
421 | else | |
422 | c_height = height; | |
423 | ||
424 | lw = (((width + 7) / 8) + 3) & ~0x3; | |
425 | ||
426 | if (c_height < height) | |
427 | dataptr = dataptr + lw * (height - c_height); | |
428 | switch (bpp) { | |
04538cdb AG |
429 | case 1: |
430 | vcxk_draw_mono(dataptr, lw, c_width, c_height); | |
431 | break; | |
432 | default: | |
433 | printf("Error: %ld bit per pixel " | |
434 | "not supported by VCxK\n", bpp); | |
50217dee JS |
435 | return 0; |
436 | } | |
437 | } else { | |
438 | printf("Error: no valid bmp at %lx\n", (ulong) bmp); | |
439 | return 0; | |
440 | } | |
441 | return 1; | |
442 | } | |
443 | ||
444 | /* | |
445 | ****f* bus_vcxk/video_display_bitmap | |
446 | *** | |
447 | */ | |
448 | ||
449 | int video_display_bitmap(ulong addr, int x, int y) | |
450 | { | |
451 | vcxk_acknowledge_wait(); | |
452 | if (vcxk_display_bitmap(addr, x, y)) { | |
453 | vcxk_request(); | |
454 | return 0; | |
455 | } | |
456 | return 1; | |
457 | } | |
458 | ||
459 | /* EOF */ |