diff options
author | Greg White <gwhite@rockbox.org> | 2007-01-04 11:43:33 +0000 |
---|---|---|
committer | Greg White <gwhite@rockbox.org> | 2007-01-04 11:43:33 +0000 |
commit | 9d0faed29ce2293ce35ed8ba0dcba779b50f50a8 (patch) | |
tree | bcbb4cd78b863ded1d84bae94b7cccc81ddfe5be | |
parent | dd7b75bd2c716f888b49ff50afc1f621157f394b (diff) | |
download | rockbox-9d0faed29ce2293ce35ed8ba0dcba779b50f50a8.tar.gz rockbox-9d0faed29ce2293ce35ed8ba0dcba779b50f50a8.zip |
Use DMA for Blit to screen/clear
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11906 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/drivers/lcd-16bit.c | 68 | ||||
-rw-r--r-- | firmware/export/lcd.h | 6 | ||||
-rw-r--r-- | firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c | 294 |
3 files changed, 217 insertions, 151 deletions
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index 6e5c31c0a5..949f80ffbc 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c | |||
@@ -33,6 +33,11 @@ | |||
33 | #include "font.h" | 33 | #include "font.h" |
34 | #include "rbunicode.h" | 34 | #include "rbunicode.h" |
35 | #include "bidi.h" | 35 | #include "bidi.h" |
36 | #if defined(TOSHIBA_GIGABEAT_F) | ||
37 | #define NON_GB_STATIC | ||
38 | #else | ||
39 | #define NON_GB_STATIC static | ||
40 | #endif | ||
36 | 41 | ||
37 | #define SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32) | 42 | #define SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32) |
38 | 43 | ||
@@ -45,11 +50,12 @@ enum fill_opt { | |||
45 | /*** globals ***/ | 50 | /*** globals ***/ |
46 | fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH] IRAM_LCDFRAMEBUFFER __attribute__ ((aligned (16))); | 51 | fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH] IRAM_LCDFRAMEBUFFER __attribute__ ((aligned (16))); |
47 | 52 | ||
53 | |||
48 | static fb_data* lcd_backdrop = NULL; | 54 | static fb_data* lcd_backdrop = NULL; |
49 | static long lcd_backdrop_offset IDATA_ATTR = 0; | 55 | static long lcd_backdrop_offset IDATA_ATTR = 0; |
50 | 56 | ||
51 | static unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG; | 57 | NON_GB_STATIC unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG; |
52 | static unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG; | 58 | NON_GB_STATIC unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG; |
53 | static int drawmode = DRMODE_SOLID; | 59 | static int drawmode = DRMODE_SOLID; |
54 | static int xmargin = 0; | 60 | static int xmargin = 0; |
55 | static int ymargin = 0; | 61 | static int ymargin = 0; |
@@ -75,9 +81,12 @@ static const char scroll_tick_table[16] = { | |||
75 | /* LCD init */ | 81 | /* LCD init */ |
76 | void lcd_init(void) | 82 | void lcd_init(void) |
77 | { | 83 | { |
78 | lcd_clear_display(); | 84 | lcd_clear_display(); |
79 | /* Call device specific init */ | 85 | |
80 | lcd_init_device(); | 86 | /* Call device specific init */ |
87 | lcd_init_device(); | ||
88 | |||
89 | |||
81 | create_thread(scroll_thread, scroll_stack, | 90 | create_thread(scroll_thread, scroll_stack, |
82 | sizeof(scroll_stack), scroll_name | 91 | sizeof(scroll_stack), scroll_name |
83 | IF_PRIO(, PRIORITY_USER_INTERFACE)); | 92 | IF_PRIO(, PRIORITY_USER_INTERFACE)); |
@@ -95,20 +104,24 @@ int lcd_get_drawmode(void) | |||
95 | return drawmode; | 104 | return drawmode; |
96 | } | 105 | } |
97 | 106 | ||
107 | #if !defined(TOSHIBA_GIGABEAT_F) | ||
98 | void lcd_set_foreground(unsigned color) | 108 | void lcd_set_foreground(unsigned color) |
99 | { | 109 | { |
100 | fg_pattern = color; | 110 | fg_pattern = color; |
101 | } | 111 | } |
112 | #endif | ||
102 | 113 | ||
103 | unsigned lcd_get_foreground(void) | 114 | unsigned lcd_get_foreground(void) |
104 | { | 115 | { |
105 | return fg_pattern; | 116 | return fg_pattern; |
106 | } | 117 | } |
107 | 118 | ||
119 | #if !defined(TOSHIBA_GIGABEAT_F) | ||
108 | void lcd_set_background(unsigned color) | 120 | void lcd_set_background(unsigned color) |
109 | { | 121 | { |
110 | bg_pattern = color; | 122 | bg_pattern = color; |
111 | } | 123 | } |
124 | #endif | ||
112 | 125 | ||
113 | unsigned lcd_get_background(void) | 126 | unsigned lcd_get_background(void) |
114 | { | 127 | { |
@@ -201,12 +214,13 @@ void lcd_set_backdrop(fb_data* backdrop) | |||
201 | { | 214 | { |
202 | lcd_backdrop_offset = (long)backdrop - (long)&lcd_framebuffer[0][0]; | 215 | lcd_backdrop_offset = (long)backdrop - (long)&lcd_framebuffer[0][0]; |
203 | lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop; | 216 | lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop; |
204 | } | 217 | } |
205 | else | 218 | else |
206 | { | 219 | { |
207 | lcd_backdrop_offset = 0; | 220 | lcd_backdrop_offset = 0; |
208 | lcd_fastpixelfuncs = lcd_fastpixelfuncs_bgcolor; | 221 | lcd_fastpixelfuncs = lcd_fastpixelfuncs_bgcolor; |
209 | } | 222 | } |
223 | lcd_device_prepare_backdrop(backdrop); | ||
210 | } | 224 | } |
211 | 225 | ||
212 | fb_data* lcd_get_backdrop(void) | 226 | fb_data* lcd_get_backdrop(void) |
@@ -217,10 +231,11 @@ fb_data* lcd_get_backdrop(void) | |||
217 | /*** drawing functions ***/ | 231 | /*** drawing functions ***/ |
218 | 232 | ||
219 | /* Clear the whole display */ | 233 | /* Clear the whole display */ |
234 | #if !defined(TOSHIBA_GIGABEAT_F) | ||
220 | void lcd_clear_display(void) | 235 | void lcd_clear_display(void) |
221 | { | 236 | { |
222 | fb_data *dst = LCDADDR(0, 0); | 237 | fb_data *dst = LCDADDR(0, 0); |
223 | 238 | ||
224 | if (drawmode & DRMODE_INVERSEVID) | 239 | if (drawmode & DRMODE_INVERSEVID) |
225 | { | 240 | { |
226 | memset16(dst, fg_pattern, LCD_WIDTH*LCD_HEIGHT); | 241 | memset16(dst, fg_pattern, LCD_WIDTH*LCD_HEIGHT); |
@@ -234,6 +249,7 @@ void lcd_clear_display(void) | |||
234 | } | 249 | } |
235 | scrolling_lines = 0; | 250 | scrolling_lines = 0; |
236 | } | 251 | } |
252 | #endif | ||
237 | 253 | ||
238 | /* Set a single pixel */ | 254 | /* Set a single pixel */ |
239 | void lcd_drawpixel(int x, int y) | 255 | void lcd_drawpixel(int x, int y) |
@@ -329,17 +345,17 @@ void lcd_hline(int x1, int x2, int y) | |||
329 | x1 = x2; | 345 | x1 = x2; |
330 | x2 = x; | 346 | x2 = x; |
331 | } | 347 | } |
332 | 348 | ||
333 | /* nothing to draw? */ | 349 | /* nothing to draw? */ |
334 | if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) | 350 | if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) |
335 | return; | 351 | return; |
336 | 352 | ||
337 | /* clipping */ | 353 | /* clipping */ |
338 | if (x1 < 0) | 354 | if (x1 < 0) |
339 | x1 = 0; | 355 | x1 = 0; |
340 | if (x2 >= LCD_WIDTH) | 356 | if (x2 >= LCD_WIDTH) |
341 | x2 = LCD_WIDTH-1; | 357 | x2 = LCD_WIDTH-1; |
342 | 358 | ||
343 | if (drawmode & DRMODE_INVERSEVID) | 359 | if (drawmode & DRMODE_INVERSEVID) |
344 | { | 360 | { |
345 | if (drawmode & DRMODE_BG) | 361 | if (drawmode & DRMODE_BG) |
@@ -363,7 +379,7 @@ void lcd_hline(int x1, int x2, int y) | |||
363 | } | 379 | } |
364 | dst = LCDADDR(x1, y); | 380 | dst = LCDADDR(x1, y); |
365 | width = x2 - x1 + 1; | 381 | width = x2 - x1 + 1; |
366 | 382 | ||
367 | switch (fillopt) | 383 | switch (fillopt) |
368 | { | 384 | { |
369 | case OPT_SET: | 385 | case OPT_SET: |
@@ -401,14 +417,14 @@ void lcd_vline(int x, int y1, int y2) | |||
401 | 417 | ||
402 | /* nothing to draw? */ | 418 | /* nothing to draw? */ |
403 | if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) | 419 | if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) |
404 | return; | 420 | return; |
405 | 421 | ||
406 | /* clipping */ | 422 | /* clipping */ |
407 | if (y1 < 0) | 423 | if (y1 < 0) |
408 | y1 = 0; | 424 | y1 = 0; |
409 | if (y2 >= LCD_HEIGHT) | 425 | if (y2 >= LCD_HEIGHT) |
410 | y2 = LCD_HEIGHT-1; | 426 | y2 = LCD_HEIGHT-1; |
411 | 427 | ||
412 | dst = LCDADDR(x, y1); | 428 | dst = LCDADDR(x, y1); |
413 | dst_end = dst + (y2 - y1) * LCD_WIDTH; | 429 | dst_end = dst + (y2 - y1) * LCD_WIDTH; |
414 | 430 | ||
@@ -463,7 +479,7 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
463 | width = LCD_WIDTH - x; | 479 | width = LCD_WIDTH - x; |
464 | if (y + height > LCD_HEIGHT) | 480 | if (y + height > LCD_HEIGHT) |
465 | height = LCD_HEIGHT - y; | 481 | height = LCD_HEIGHT - y; |
466 | 482 | ||
467 | if (drawmode & DRMODE_INVERSEVID) | 483 | if (drawmode & DRMODE_INVERSEVID) |
468 | { | 484 | { |
469 | if (drawmode & DRMODE_BG) | 485 | if (drawmode & DRMODE_BG) |
@@ -544,7 +560,7 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
544 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | 560 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) |
545 | || (x + width <= 0) || (y + height <= 0)) | 561 | || (x + width <= 0) || (y + height <= 0)) |
546 | return; | 562 | return; |
547 | 563 | ||
548 | /* clipping */ | 564 | /* clipping */ |
549 | if (x < 0) | 565 | if (x < 0) |
550 | { | 566 | { |
@@ -577,7 +593,7 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
577 | unsigned data = *src_col >> src_y; | 593 | unsigned data = *src_col >> src_y; |
578 | fb_data *dst_col = dst++; | 594 | fb_data *dst_col = dst++; |
579 | int numbits = 8 - src_y; | 595 | int numbits = 8 - src_y; |
580 | 596 | ||
581 | dst_end = dst_col + height * LCD_WIDTH; | 597 | dst_end = dst_col + height * LCD_WIDTH; |
582 | do | 598 | do |
583 | { | 599 | { |
@@ -620,7 +636,7 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
620 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | 636 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) |
621 | || (x + width <= 0) || (y + height <= 0)) | 637 | || (x + width <= 0) || (y + height <= 0)) |
622 | return; | 638 | return; |
623 | 639 | ||
624 | /* clipping */ | 640 | /* clipping */ |
625 | if (x < 0) | 641 | if (x < 0) |
626 | { | 642 | { |
@@ -672,7 +688,7 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, | |||
672 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | 688 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) |
673 | || (x + width <= 0) || (y + height <= 0)) | 689 | || (x + width <= 0) || (y + height <= 0)) |
674 | return; | 690 | return; |
675 | 691 | ||
676 | /* clipping */ | 692 | /* clipping */ |
677 | if (x < 0) | 693 | if (x < 0) |
678 | { | 694 | { |
@@ -742,7 +758,7 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | |||
742 | bits = font_get_bits(pf, ch); | 758 | bits = font_get_bits(pf, ch); |
743 | 759 | ||
744 | lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); | 760 | lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); |
745 | 761 | ||
746 | x += width - ofs; | 762 | x += width - ofs; |
747 | ofs = 0; | 763 | ofs = 0; |
748 | } | 764 | } |
@@ -850,8 +866,8 @@ void lcd_puts_scroll_style(int x, int y, const unsigned char *string, int style) | |||
850 | void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, int offset) | 866 | void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, int offset) |
851 | { | 867 | { |
852 | lcd_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset); | 868 | lcd_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset); |
853 | } | 869 | } |
854 | 870 | ||
855 | void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | 871 | void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, |
856 | int style, int offset) | 872 | int style, int offset) |
857 | { | 873 | { |
@@ -963,7 +979,7 @@ static void scroll_thread(void) | |||
963 | } | 979 | } |
964 | 980 | ||
965 | lastmode = drawmode; | 981 | lastmode = drawmode; |
966 | drawmode = s->invert ? | 982 | drawmode = s->invert ? |
967 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 983 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; |
968 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | 984 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); |
969 | drawmode = lastmode; | 985 | drawmode = lastmode; |
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 3e1ea4430b..fc0562419c 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h | |||
@@ -345,6 +345,12 @@ extern unsigned lcd_get_background(void); | |||
345 | extern void lcd_set_drawinfo(int mode, unsigned foreground, | 345 | extern void lcd_set_drawinfo(int mode, unsigned foreground, |
346 | unsigned background); | 346 | unsigned background); |
347 | void lcd_set_backdrop(fb_data* backdrop); | 347 | void lcd_set_backdrop(fb_data* backdrop); |
348 | #if !defined(TOSHIBA_GIGABEAT_F) | ||
349 | #define lcd_device_prepare_backdrop(x) ; | ||
350 | #else | ||
351 | void lcd_device_prepare_backdrop(fb_data* backdrop); | ||
352 | #endif | ||
353 | |||
348 | fb_data* lcd_get_backdrop(void); | 354 | fb_data* lcd_get_backdrop(void); |
349 | 355 | ||
350 | extern void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | 356 | extern void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, |
diff --git a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c index df5be43551..754ee6dec4 100644 --- a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c +++ b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c | |||
@@ -4,19 +4,42 @@ | |||
4 | #include "lcd.h" | 4 | #include "lcd.h" |
5 | #include "kernel.h" | 5 | #include "kernel.h" |
6 | #include "system.h" | 6 | #include "system.h" |
7 | 7 | #include "mmu-meg-fx.h" | |
8 | void lcd_init_device(void); | 8 | #include <stdlib.h> |
9 | void lcd_update_rec(int, int, int, int); | 9 | #include "memory.h" |
10 | void lcd_update(void); | 10 | #include "lcd-target.h" |
11 | 11 | ||
12 | bool usedmablit = false; | 12 | /* |
13 | ** We prepare foreground and background fills ahead of time - DMA fills in 16 byte groups | ||
14 | */ | ||
15 | unsigned long fg_pattern_blit[4]; | ||
16 | unsigned long bg_pattern_blit[4]; | ||
17 | |||
18 | volatile bool use_dma_blit = false; | ||
19 | volatile bool lcd_on = true; | ||
20 | volatile bool lcd_poweroff = true; | ||
21 | /* | ||
22 | ** These are imported from lcd-16bit.c | ||
23 | */ | ||
24 | extern unsigned fg_pattern; | ||
25 | extern unsigned bg_pattern; | ||
26 | |||
27 | extern volatile bool lcd_on; | ||
13 | 28 | ||
14 | /* LCD init */ | 29 | /* LCD init */ |
15 | void lcd_init_device(void) | 30 | void lcd_init_device(void) |
16 | { | 31 | { |
32 | memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); | ||
33 | memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); | ||
34 | clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); | ||
35 | clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); | ||
36 | |||
17 | /* Switch from 555I mode to 565 mode */ | 37 | /* Switch from 555I mode to 565 mode */ |
18 | LCDCON5 |= 1 << 11; | 38 | LCDCON5 |= 1 << 11; |
19 | 39 | ||
40 | #if !defined(BOOTLOADER) | ||
41 | use_dma_blit = true; | ||
42 | #endif | ||
20 | } | 43 | } |
21 | 44 | ||
22 | /* Update a fraction of the display. */ | 45 | /* Update a fraction of the display. */ |
@@ -24,35 +47,159 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
24 | { | 47 | { |
25 | (void)x; | 48 | (void)x; |
26 | (void)width; | 49 | (void)width; |
27 | 50 | (void)y; | |
28 | if (usedmablit) | 51 | (void)height; |
52 | |||
53 | if(!lcd_on) | ||
54 | { | ||
55 | yield(); | ||
56 | return; | ||
57 | } | ||
58 | if (use_dma_blit) | ||
29 | { | 59 | { |
30 | /* Spin waiting for DMA to become available */ | 60 | /* Wait for this controller to stop pending transfer */ |
31 | //while (DSTAT0 & (1<<20)) ; | 61 | while((DSTAT1 & 0x000fffff)) |
32 | if (DSTAT0 & (1<<20)) return; | 62 | yield(); |
33 | 63 | ||
64 | /* Flush DCache */ | ||
65 | invalidate_dcache_range((void *)(((int) &lcd_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH)), (height * sizeof(fb_data) * LCD_WIDTH)); | ||
66 | |||
34 | /* set DMA dest */ | 67 | /* set DMA dest */ |
35 | DIDST0 = (int) FRAME + y * sizeof(fb_data) * LCD_WIDTH; | 68 | DIDST1 = ((int) FRAME) + (y * sizeof(fb_data) * LCD_WIDTH); |
36 | 69 | ||
37 | /* FRAME on AHB buf, increment */ | 70 | /* FRAME on AHB buf, increment */ |
38 | DIDSTC0 = 0; | 71 | DIDSTC1 = 0; |
39 | DCON0 = (((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((height * sizeof(fb_data) * LCD_WIDTH) >> 4)); | 72 | /* Handshake on AHB, Burst transfer, Whole service, Don't reload, transfer 32-bits */ |
73 | DCON1 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((height * sizeof(fb_data) * LCD_WIDTH) >> 4); | ||
40 | 74 | ||
41 | /* set DMA source and options */ | 75 | /* set DMA source */ |
42 | DISRC0 = (int) &lcd_framebuffer + (y * sizeof(fb_data) * LCD_WIDTH) + 0x30000000; | 76 | DISRC1 = ((int) &lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH) + 0x30000000; |
43 | DISRCC0 = 0x00; /* memory is on AHB bus, increment addresses */ | 77 | /* memory is on AHB bus, increment addresses */ |
78 | DISRCC1 = 0x00; | ||
44 | 79 | ||
45 | /* Activate the channel */ | 80 | /* Activate the channel */ |
46 | DMASKTRIG0 = 0x2; | 81 | DMASKTRIG1 = 0x2; |
82 | |||
47 | /* Start DMA */ | 83 | /* Start DMA */ |
48 | DMASKTRIG0 |= 0x1; | 84 | DMASKTRIG1 |= 0x1; |
85 | |||
86 | /* Wait for transfer to complete */ | ||
87 | while((DSTAT1 & 0x000fffff)) | ||
88 | yield(); | ||
89 | } | ||
90 | else | ||
91 | memcpy(((char*)FRAME) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH))); | ||
92 | } | ||
93 | |||
94 | |||
95 | void lcd_enable(bool state) | ||
96 | { | ||
97 | if(state) { | ||
98 | if(lcd_poweroff) { | ||
99 | if(!lcd_on) | ||
100 | memcpy(FRAME, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2); | ||
101 | lcd_on = true; | ||
102 | LCDCON1 |= 1; | ||
103 | } | ||
104 | } | ||
105 | else { | ||
106 | if(lcd_poweroff) { | ||
107 | lcd_on = false; | ||
108 | LCDCON1 &= ~1; | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | |||
113 | void lcd_set_foreground(unsigned color) | ||
114 | { | ||
115 | fg_pattern = color; | ||
116 | |||
117 | memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); | ||
118 | clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); | ||
119 | } | ||
120 | |||
121 | void lcd_set_background(unsigned color) | ||
122 | { | ||
123 | bg_pattern = color; | ||
124 | memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); | ||
125 | clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); | ||
126 | } | ||
127 | |||
128 | void lcd_device_prepare_backdrop(fb_data* backdrop) | ||
129 | { | ||
130 | clean_dcache_range((void *)backdrop, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); | ||
131 | } | ||
132 | |||
133 | void lcd_clear_display_dma(void) | ||
134 | { | ||
135 | void *src; | ||
136 | bool inc = false; | ||
137 | |||
138 | if (lcd_get_drawmode() & DRMODE_INVERSEVID) | ||
139 | src = fg_pattern_blit; | ||
140 | else | ||
141 | { | ||
142 | fb_data* lcd_backdrop = lcd_get_backdrop(); | ||
143 | |||
144 | if (!lcd_backdrop) | ||
145 | src = bg_pattern_blit; | ||
146 | else | ||
147 | { | ||
148 | src = lcd_backdrop; | ||
149 | inc = true; | ||
150 | } | ||
151 | } | ||
152 | /* Wait for any pending transfer to complete */ | ||
153 | while((DSTAT3 & 0x000fffff)) | ||
154 | yield(); | ||
155 | DMASKTRIG3 |= 0x4; /* Stop controller */ | ||
156 | DIDST3 = ((int) lcd_framebuffer) + 0x30000000; /* set DMA dest, physical address */ | ||
157 | DIDSTC3 = 0; /* Dest on AHB, increment */ | ||
158 | |||
159 | DISRC3 = ((int) src) + 0x30000000; /* Set source, in physical space */ | ||
160 | DISRCC3 = inc ? 0x00 : 0x01; /* memory is on AHB bus, increment addresses based on backdrop */ | ||
161 | |||
162 | /* Handshake on AHB, Burst mode, whole service mode, no reload, move 32-bits */ | ||
163 | DCON3 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH) >> 4); | ||
164 | |||
165 | /* Dump DCache for dest, we are about to overwrite it with DMA */ | ||
166 | dump_dcache_range((void *)lcd_framebuffer, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); | ||
167 | /* Activate the channel */ | ||
168 | DMASKTRIG3 = 2; | ||
169 | /* Start DMA */ | ||
170 | DMASKTRIG3 |= 1; | ||
171 | |||
172 | /* Wait for transfer to complete */ | ||
173 | while((DSTAT3 & 0x000fffff)) | ||
174 | yield(); | ||
175 | } | ||
176 | |||
177 | void lcd_clear_display(void) | ||
178 | { | ||
179 | if(use_dma_blit) | ||
180 | { | ||
181 | lcd_clear_display_dma(); | ||
182 | return; | ||
183 | } | ||
184 | |||
185 | fb_data *dst = &lcd_framebuffer[0][0]; | ||
186 | |||
187 | if (lcd_get_drawmode() & DRMODE_INVERSEVID) | ||
188 | { | ||
189 | memset16(dst, fg_pattern, LCD_WIDTH*LCD_HEIGHT); | ||
49 | } | 190 | } |
50 | else | 191 | else |
51 | { | 192 | { |
52 | memcpy((void*)FRAME, &lcd_framebuffer, sizeof(lcd_framebuffer)); | 193 | fb_data* lcd_backdrop = lcd_get_backdrop(); |
194 | if (!lcd_backdrop) | ||
195 | memset16(dst, bg_pattern, LCD_WIDTH*LCD_HEIGHT); | ||
196 | else | ||
197 | memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); | ||
53 | } | 198 | } |
199 | lcd_stop_scroll(); | ||
54 | } | 200 | } |
55 | 201 | ||
202 | |||
56 | /* Update the display. | 203 | /* Update the display. |
57 | This must be called after all other LCD functions that change the display. */ | 204 | This must be called after all other LCD functions that change the display. */ |
58 | void lcd_update(void) | 205 | void lcd_update(void) |
@@ -164,7 +311,6 @@ void lcd_yuv_blit(unsigned char * const src[3], | |||
164 | } | 311 | } |
165 | 312 | ||
166 | 313 | ||
167 | |||
168 | void lcd_set_contrast(int val) { | 314 | void lcd_set_contrast(int val) { |
169 | (void) val; | 315 | (void) val; |
170 | // TODO: | 316 | // TODO: |
@@ -192,105 +338,3 @@ void lcd_set_flip(bool yesno) { | |||
192 | // TODO: | 338 | // TODO: |
193 | } | 339 | } |
194 | 340 | ||
195 | |||
196 | |||
197 | |||
198 | |||
199 | |||
200 | |||
201 | |||
202 | |||
203 | |||
204 | |||
205 | |||
206 | |||
207 | #if 0 | ||
208 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
209 | void lcd_yuv_blit(unsigned char * const src[3], | ||
210 | int src_x, int src_y, int stride, | ||
211 | int x, int y, int width, int height) | ||
212 | { | ||
213 | fb_data *dst, *dst_end; | ||
214 | |||
215 | width = (width + 1) & ~1; | ||
216 | |||
217 | dst = (fb_data*)FRAME + LCD_WIDTH * y + x; | ||
218 | dst_end = dst + LCD_WIDTH * height; | ||
219 | |||
220 | do | ||
221 | { | ||
222 | fb_data *dst_row = dst; | ||
223 | fb_data *row_end = dst_row + width; | ||
224 | const unsigned char *ysrc = src[0] + stride * src_y + src_x; | ||
225 | int y, u, v; | ||
226 | int red, green, blue; | ||
227 | unsigned rbits, gbits, bbits; | ||
228 | |||
229 | /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ | ||
230 | const unsigned char *usrc = src[1] + (stride/CSUB_X) * (src_y/CSUB_Y) | ||
231 | + (src_x/CSUB_X); | ||
232 | const unsigned char *vsrc = src[2] + (stride/CSUB_X) * (src_y/CSUB_Y) | ||
233 | + (src_x/CSUB_X); | ||
234 | int xphase = src_x % CSUB_X; | ||
235 | int rc, gc, bc; | ||
236 | |||
237 | u = *usrc++ - 128; | ||
238 | v = *vsrc++ - 128; | ||
239 | rc = RVFAC * v + ROUNDOFFS; | ||
240 | gc = GVFAC * v + GUFAC * u + ROUNDOFFS; | ||
241 | bc = BUFAC * u + ROUNDOFFS; | ||
242 | |||
243 | do | ||
244 | { | ||
245 | y = *ysrc++; | ||
246 | red = RYFAC * y + rc; | ||
247 | green = GYFAC * y + gc; | ||
248 | blue = BYFAC * y + bc; | ||
249 | |||
250 | if ((unsigned)red > (RYFAC*255+ROUNDOFFS)) | ||
251 | { | ||
252 | if (red < 0) | ||
253 | red = 0; | ||
254 | else | ||
255 | red = (RYFAC*255+ROUNDOFFS); | ||
256 | } | ||
257 | if ((unsigned)green > (GYFAC*255+ROUNDOFFS)) | ||
258 | { | ||
259 | if (green < 0) | ||
260 | green = 0; | ||
261 | else | ||
262 | green = (GYFAC*255+ROUNDOFFS); | ||
263 | } | ||
264 | if ((unsigned)blue > (BYFAC*255+ROUNDOFFS)) | ||
265 | { | ||
266 | if (blue < 0) | ||
267 | blue = 0; | ||
268 | else | ||
269 | blue = (BYFAC*255+ROUNDOFFS); | ||
270 | } | ||
271 | rbits = ((unsigned)red) >> 16 ; | ||
272 | gbits = ((unsigned)green) >> 16 ; | ||
273 | bbits = ((unsigned)blue) >> 16 ; | ||
274 | *dst_row++ = (rbits << 11) | (gbits << 5) | bbits; | ||
275 | |||
276 | if (++xphase >= CSUB_X) | ||
277 | { | ||
278 | u = *usrc++ - 128; | ||
279 | v = *vsrc++ - 128; | ||
280 | rc = RVFAC * v + ROUNDOFFS; | ||
281 | gc = GVFAC * v + GUFAC * u + ROUNDOFFS; | ||
282 | bc = BUFAC * u + ROUNDOFFS; | ||
283 | xphase = 0; | ||
284 | } | ||
285 | } | ||
286 | while (dst_row < row_end); | ||
287 | |||
288 | src_y++; | ||
289 | dst += LCD_WIDTH; | ||
290 | } | ||
291 | while (dst < dst_end); | ||
292 | } | ||
293 | #endif | ||
294 | |||
295 | |||
296 | |||