summaryrefslogtreecommitdiff
path: root/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c
diff options
context:
space:
mode:
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.c69
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];
16unsigned long bg_pattern_blit[4]; 16unsigned long bg_pattern_blit[4];
17 17
18volatile bool use_dma_blit = false; 18volatile bool use_dma_blit = false;
19volatile bool lcd_on = true; 19static volatile bool lcd_on = true;
20volatile bool lcd_poweroff = true; 20volatile bool lcd_poweroff = false;
21/* 21/*
22** These are imported from lcd-16bit.c 22** These are imported from lcd-16bit.c
23*/ 23*/
24extern unsigned fg_pattern; 24extern unsigned fg_pattern;
25extern unsigned bg_pattern; 25extern unsigned bg_pattern;
26 26
27extern volatile bool lcd_on; 27static struct mutex lcd_update_mtx;
28static struct mutex lcd_clear_mtx;
29static struct mutex lcd_enable_mtx;
30
31
32bool lcd_enabled()
33{
34 return lcd_on;
35}
28 36
29/* LCD init */ 37/* LCD init */
30void lcd_init_device(void) 38void 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
96void lcd_enable(bool state) 114void 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
113void lcd_set_foreground(unsigned color) 135void 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
121void lcd_set_background(unsigned color) 143void 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
128void lcd_device_prepare_backdrop(fb_data* backdrop) 150void 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
133void lcd_clear_display_dma(void) 155void 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
182void lcd_clear_display(void) 204void 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