diff options
Diffstat (limited to 'firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c')
-rw-r--r-- | firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c | 69 |
1 files changed, 46 insertions, 23 deletions
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 965f4523c8..cbeddc6ee7 100644 --- a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c +++ b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c | |||
@@ -16,29 +16,45 @@ unsigned long fg_pattern_blit[4]; | |||
16 | unsigned long bg_pattern_blit[4]; | 16 | unsigned long bg_pattern_blit[4]; |
17 | 17 | ||
18 | volatile bool use_dma_blit = false; | 18 | volatile bool use_dma_blit = false; |
19 | volatile bool lcd_on = true; | 19 | static volatile bool lcd_on = true; |
20 | volatile bool lcd_poweroff = true; | 20 | volatile bool lcd_poweroff = false; |
21 | /* | 21 | /* |
22 | ** These are imported from lcd-16bit.c | 22 | ** These are imported from lcd-16bit.c |
23 | */ | 23 | */ |
24 | extern unsigned fg_pattern; | 24 | extern unsigned fg_pattern; |
25 | extern unsigned bg_pattern; | 25 | extern unsigned bg_pattern; |
26 | 26 | ||
27 | extern volatile bool lcd_on; | 27 | static struct mutex lcd_update_mtx; |
28 | static struct mutex lcd_clear_mtx; | ||
29 | static struct mutex lcd_enable_mtx; | ||
30 | |||
31 | |||
32 | bool lcd_enabled() | ||
33 | { | ||
34 | return lcd_on; | ||
35 | } | ||
28 | 36 | ||
29 | /* LCD init */ | 37 | /* LCD init */ |
30 | void lcd_init_device(void) | 38 | void lcd_init_device(void) |
31 | { | 39 | { |
40 | mutex_init(&lcd_update_mtx); | ||
41 | mutex_init(&lcd_clear_mtx); | ||
42 | mutex_init(&lcd_enable_mtx); | ||
43 | |||
32 | memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); | 44 | memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); |
33 | memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); | 45 | memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); |
34 | clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); | 46 | clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); |
35 | clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); | 47 | clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); |
36 | 48 | ||
37 | /* Switch from 555I mode to 565 mode */ | 49 | LCDSADDR1 = 0x18F00000; /* These values are pulled from an F40 */ |
38 | LCDCON5 |= 1 << 11; | 50 | LCDSADDR2 = 0x00112C00; /* They should move FRAME to the correct location */ |
51 | LCDSADDR3 = 0x000000F0; /* TODO: Move FRAME to where we want it */ | ||
52 | |||
53 | LCDCON5 |= 1 << 11; /* Switch from 555I mode to 565 mode */ | ||
39 | 54 | ||
40 | #if !defined(BOOTLOADER) | 55 | #if !defined(BOOTLOADER) |
41 | use_dma_blit = true; | 56 | use_dma_blit = true; |
57 | lcd_poweroff = true; | ||
42 | #endif | 58 | #endif |
43 | } | 59 | } |
44 | 60 | ||
@@ -52,15 +68,16 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
52 | 68 | ||
53 | if(!lcd_on) | 69 | if(!lcd_on) |
54 | { | 70 | { |
55 | for(x=0; x < 2; x++) | 71 | sleep(200); |
56 | yield(); | ||
57 | return; | 72 | return; |
58 | } | 73 | } |
59 | if (use_dma_blit) | 74 | if (use_dma_blit) |
60 | { | 75 | { |
76 | // mutex_lock(&lcd_update_mtx); | ||
77 | |||
61 | /* Wait for this controller to stop pending transfer */ | 78 | /* Wait for this controller to stop pending transfer */ |
62 | while((DSTAT1 & 0x000fffff)) | 79 | while((DSTAT1 & 0x000fffff)) |
63 | yield(); | 80 | CLKCON |= (1 << 2); /* set IDLE bit */ |
64 | 81 | ||
65 | /* Flush DCache */ | 82 | /* Flush DCache */ |
66 | invalidate_dcache_range((void *)(((int) &lcd_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH)), (height * sizeof(fb_data) * LCD_WIDTH)); | 83 | invalidate_dcache_range((void *)(((int) &lcd_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH)), (height * sizeof(fb_data) * LCD_WIDTH)); |
@@ -86,7 +103,8 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
86 | 103 | ||
87 | /* Wait for transfer to complete */ | 104 | /* Wait for transfer to complete */ |
88 | while((DSTAT1 & 0x000fffff)) | 105 | while((DSTAT1 & 0x000fffff)) |
89 | yield(); | 106 | CLKCON |= (1 << 2); /* set IDLE bit */ |
107 | // mutex_unlock(&lcd_update_mtx); | ||
90 | } | 108 | } |
91 | else | 109 | else |
92 | memcpy(((char*)FRAME) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH))); | 110 | memcpy(((char*)FRAME) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH))); |
@@ -95,19 +113,23 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
95 | 113 | ||
96 | void lcd_enable(bool state) | 114 | void lcd_enable(bool state) |
97 | { | 115 | { |
116 | if(!lcd_poweroff) | ||
117 | return; | ||
118 | mutex_lock(&lcd_enable_mtx); | ||
98 | if(state) { | 119 | if(state) { |
99 | if(lcd_poweroff && !lcd_on) { | 120 | if(!lcd_on) { |
100 | memcpy(FRAME, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2); | ||
101 | lcd_on = true; | 121 | lcd_on = true; |
122 | memcpy(FRAME, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2); | ||
102 | LCDCON1 |= 1; | 123 | LCDCON1 |= 1; |
103 | } | 124 | } |
104 | } | 125 | } |
105 | else { | 126 | else { |
106 | if(lcd_poweroff && lcd_on) { | 127 | if(lcd_on) { |
107 | lcd_on = false; | 128 | lcd_on = false; |
108 | LCDCON1 &= ~1; | 129 | LCDCON1 &= ~1; |
109 | } | 130 | } |
110 | } | 131 | } |
132 | mutex_unlock(&lcd_enable_mtx); | ||
111 | } | 133 | } |
112 | 134 | ||
113 | void lcd_set_foreground(unsigned color) | 135 | void lcd_set_foreground(unsigned color) |
@@ -115,19 +137,19 @@ void lcd_set_foreground(unsigned color) | |||
115 | fg_pattern = color; | 137 | fg_pattern = color; |
116 | 138 | ||
117 | memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); | 139 | memset16(fg_pattern_blit, fg_pattern, sizeof(fg_pattern_blit)/2); |
118 | clean_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); | 140 | invalidate_dcache_range((void *)fg_pattern_blit, sizeof(fg_pattern_blit)); |
119 | } | 141 | } |
120 | 142 | ||
121 | void lcd_set_background(unsigned color) | 143 | void lcd_set_background(unsigned color) |
122 | { | 144 | { |
123 | bg_pattern = color; | 145 | bg_pattern = color; |
124 | memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); | 146 | memset16(bg_pattern_blit, bg_pattern, sizeof(bg_pattern_blit)/2); |
125 | clean_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); | 147 | invalidate_dcache_range((void *)bg_pattern_blit, sizeof(bg_pattern_blit)); |
126 | } | 148 | } |
127 | 149 | ||
128 | void lcd_device_prepare_backdrop(fb_data* backdrop) | 150 | void lcd_device_prepare_backdrop(fb_data* backdrop) |
129 | { | 151 | { |
130 | clean_dcache_range((void *)backdrop, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); | 152 | invalidate_dcache_range((void *)backdrop, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); |
131 | } | 153 | } |
132 | 154 | ||
133 | void lcd_clear_display_dma(void) | 155 | void lcd_clear_display_dma(void) |
@@ -136,10 +158,8 @@ void lcd_clear_display_dma(void) | |||
136 | bool inc = false; | 158 | bool inc = false; |
137 | 159 | ||
138 | if(!lcd_on) { | 160 | if(!lcd_on) { |
139 | yield(); | 161 | sleep(200); |
140 | yield(); | ||
141 | } | 162 | } |
142 | |||
143 | if (lcd_get_drawmode() & DRMODE_INVERSEVID) | 163 | if (lcd_get_drawmode() & DRMODE_INVERSEVID) |
144 | src = fg_pattern_blit; | 164 | src = fg_pattern_blit; |
145 | else | 165 | else |
@@ -154,9 +174,10 @@ void lcd_clear_display_dma(void) | |||
154 | inc = true; | 174 | inc = true; |
155 | } | 175 | } |
156 | } | 176 | } |
177 | // mutex_lock(&lcd_clear_mtx); | ||
157 | /* Wait for any pending transfer to complete */ | 178 | /* Wait for any pending transfer to complete */ |
158 | while((DSTAT3 & 0x000fffff)) | 179 | while((DSTAT3 & 0x000fffff)) |
159 | yield(); | 180 | CLKCON |= (1 << 2); /* set IDLE bit */ |
160 | DMASKTRIG3 |= 0x4; /* Stop controller */ | 181 | DMASKTRIG3 |= 0x4; /* Stop controller */ |
161 | DIDST3 = ((int) lcd_framebuffer) + 0x30000000; /* set DMA dest, physical address */ | 182 | DIDST3 = ((int) lcd_framebuffer) + 0x30000000; /* set DMA dest, physical address */ |
162 | DIDSTC3 = 0; /* Dest on AHB, increment */ | 183 | DIDSTC3 = 0; /* Dest on AHB, increment */ |
@@ -165,10 +186,10 @@ void lcd_clear_display_dma(void) | |||
165 | DISRCC3 = inc ? 0x00 : 0x01; /* memory is on AHB bus, increment addresses based on backdrop */ | 186 | DISRCC3 = inc ? 0x00 : 0x01; /* memory is on AHB bus, increment addresses based on backdrop */ |
166 | 187 | ||
167 | /* Handshake on AHB, Burst mode, whole service mode, no reload, move 32-bits */ | 188 | /* Handshake on AHB, Burst mode, whole service mode, no reload, move 32-bits */ |
168 | DCON3 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | ((LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH) >> 4); | 189 | DCON3 = ((1<<30) | (1<<28) | (1<<27) | (1<<22) | (2<<20)) | (sizeof(lcd_framebuffer) >> 4); |
169 | 190 | ||
170 | /* Dump DCache for dest, we are about to overwrite it with DMA */ | 191 | /* Dump DCache for dest, we are about to overwrite it with DMA */ |
171 | dump_dcache_range((void *)lcd_framebuffer, (LCD_HEIGHT * sizeof(fb_data) * LCD_WIDTH)); | 192 | invalidate_dcache_range((void *)lcd_framebuffer, sizeof(lcd_framebuffer)); |
172 | /* Activate the channel */ | 193 | /* Activate the channel */ |
173 | DMASKTRIG3 = 2; | 194 | DMASKTRIG3 = 2; |
174 | /* Start DMA */ | 195 | /* Start DMA */ |
@@ -176,11 +197,14 @@ void lcd_clear_display_dma(void) | |||
176 | 197 | ||
177 | /* Wait for transfer to complete */ | 198 | /* Wait for transfer to complete */ |
178 | while((DSTAT3 & 0x000fffff)) | 199 | while((DSTAT3 & 0x000fffff)) |
179 | yield(); | 200 | CLKCON |= (1 << 2); /* set IDLE bit */ |
201 | // mutex_unlock(&lcd_update_mtx); | ||
180 | } | 202 | } |
181 | 203 | ||
182 | void lcd_clear_display(void) | 204 | void lcd_clear_display(void) |
183 | { | 205 | { |
206 | lcd_stop_scroll(); | ||
207 | |||
184 | if(use_dma_blit) | 208 | if(use_dma_blit) |
185 | { | 209 | { |
186 | lcd_clear_display_dma(); | 210 | lcd_clear_display_dma(); |
@@ -201,7 +225,6 @@ void lcd_clear_display(void) | |||
201 | else | 225 | else |
202 | memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); | 226 | memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); |
203 | } | 227 | } |
204 | lcd_stop_scroll(); | ||
205 | } | 228 | } |
206 | 229 | ||
207 | 230 | ||