summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2010-08-08 18:41:19 +0000
committerMarcin Bukat <marcin.bukat@gmail.com>2010-08-08 18:41:19 +0000
commita86b08e4fa1e4de5e7f33d5d92ba698c335b3dc7 (patch)
treed094e7471c749f35a46c699db6d29549121c87e9 /firmware/target
parent33a5f1a2bba507d1f6a0e32fbcc7f24e2015a44b (diff)
downloadrockbox-a86b08e4fa1e4de5e7f33d5d92ba698c335b3dc7.tar.gz
rockbox-a86b08e4fa1e4de5e7f33d5d92ba698c335b3dc7.zip
HD200 - Use DMA transfers in lcd_update() and lcd_update_rect(). Gives 12-26% speedup.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27757 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/coldfire/mpio/hd200/lcd-hd200.c102
1 files changed, 86 insertions, 16 deletions
diff --git a/firmware/target/coldfire/mpio/hd200/lcd-hd200.c b/firmware/target/coldfire/mpio/hd200/lcd-hd200.c
index 8cb4449b57..5983c7af36 100644
--- a/firmware/target/coldfire/mpio/hd200/lcd-hd200.c
+++ b/firmware/target/coldfire/mpio/hd200/lcd-hd200.c
@@ -55,6 +55,13 @@ static bool cached_invert = false;
55static bool cached_flip = false; 55static bool cached_flip = false;
56static int cached_contrast = DEFAULT_CONTRAST_SETTING; 56static int cached_contrast = DEFAULT_CONTRAST_SETTING;
57 57
58static struct mutex lcd_mtx; /* The update functions use DMA and yield */
59
60volatile unsigned char page IBSS_ATTR;
61unsigned char column IBSS_ATTR;
62unsigned int dma_len IBSS_ATTR;
63volatile unsigned long dma_count IBSS_ATTR;
64
58/*** hardware configuration ***/ 65/*** hardware configuration ***/
59int lcd_default_contrast(void) 66int lcd_default_contrast(void)
60{ 67{
@@ -155,24 +162,72 @@ void lcd_init_device(void)
155 lcd_set_contrast(cached_contrast); 162 lcd_set_contrast(cached_contrast);
156 lcd_set_invert_display(cached_invert); 163 lcd_set_invert_display(cached_invert);
157 164
165 /* Configure DMA3 */
166 DAR3 = 0xf0000002;
167 DSR3 = 1;
168 DIVR3 = 57; /* DMA3 is mapped into vector 57 in system.c */
169 ICR9 = (6 << 2); /* Enable DMA3 interrupt at level 6, priority 0 */
170 and_l(~(1<<17), &IMR);
171
172 mutex_init(&lcd_mtx);
173
158 lcd_update(); 174 lcd_update();
159} 175}
160 176
177/* LCD DMA ISR */
178void DMA3(void) __attribute__ ((interrupt_handler, section(".icode")));
179void DMA3(void)
180{
181 DSR3 = 1;
182
183 if (--dma_count > 0)
184 {
185 /* Setup write address in lcd controller ram*/
186 lcd_write_command(LCD_SET_PAGE | ++page);
187 lcd_write_command_e(LCD_SET_COLUMN | ((column >> 4) & 0xf),
188 column & 0x0f);
189
190 SAR3 = (unsigned long)&lcd_framebuffer[page][column];
191 BCR3 = dma_len;
192 DCR3 = DMA_INT | DMA_AA | DMA_BWC(1)
193 | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE)
194 | DMA_DSIZE(DMA_SIZE_BYTE) | DMA_START;
195
196 }
197}
198
161/* Update the display. 199/* Update the display.
162 This must be called after all other LCD functions that change the display. */ 200 This must be called after all other LCD functions that change the display. */
163void lcd_update(void) ICODE_ATTR; 201void lcd_update(void) ICODE_ATTR;
164void lcd_update(void) 202void lcd_update(void)
165{ 203{
166 int y; 204 mutex_lock(&lcd_mtx);
167 205
168 for(y = 0;y < LCD_FBHEIGHT;y++) 206 /* Setup initial address in lcd controller */
169 { 207 lcd_write_command(LCD_SET_PAGE | 0);
170 lcd_write_command(LCD_SET_PAGE | y); 208 lcd_write_command_e(LCD_SET_COLUMN, 0);
171 lcd_write_command_e(LCD_SET_COLUMN, 0); 209
172 lcd_write_data(lcd_framebuffer[y], LCD_WIDTH); 210 /* Initial lcd ram address */
173 } 211 page = 0;
212 column = 0;
213
214 /* Number of pages to address */
215 dma_count = LCD_FBHEIGHT;
174 216
217 /* Transfer size in bytes to the given page */
218 dma_len = LCD_WIDTH*2;
219
220 /* Initialize DMA transfer */
221 SAR3 = (unsigned long)lcd_framebuffer;
222 BCR3 = LCD_WIDTH*2;
223 DCR3 = DMA_INT | DMA_AA | DMA_BWC(1)
224 | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE)
225 | DMA_DSIZE(DMA_SIZE_BYTE) | DMA_START;
226
227 while (dma_count > 0)
228 yield();
175 229
230 mutex_unlock(&lcd_mtx);
176} 231}
177 232
178/* Update a fraction of the display. */ 233/* Update a fraction of the display. */
@@ -191,17 +246,32 @@ void lcd_update_rect(int x, int y, int width, int height)
191 if (width <= 0) 246 if (width <= 0)
192 return; /* nothing left to do, 0 is harmful to lcd_write_data() */ 247 return; /* nothing left to do, 0 is harmful to lcd_write_data() */
193 248
249 mutex_lock(&lcd_mtx);
250
194 if (ymax >= LCD_FBHEIGHT) 251 if (ymax >= LCD_FBHEIGHT)
195 ymax = LCD_FBHEIGHT-1; 252 ymax = LCD_FBHEIGHT-1;
196 253
197 /* Copy specified rectange bitmap to hardware */ 254 /* Initial lcd ram address*/
198 for (; y <= ymax; y++) 255 lcd_write_command(LCD_SET_PAGE | y );
199 { 256 lcd_write_command_e(LCD_SET_COLUMN | ((x >> 4) & 0xf), x & 0x0f);
200 lcd_write_command(LCD_SET_PAGE | y ); 257
201 lcd_write_command_e(LCD_SET_COLUMN | ((x >> 4) & 0xf), x & 0x0f); 258 page = y;
202 lcd_write_data (&lcd_framebuffer[y][x], width); 259 column = x;
203 } 260 dma_len = width*2;
204 261 dma_count = ymax - y + 1;
262
263 /* Initialize DMA transfer */
264 SAR3 = (unsigned long)&lcd_framebuffer[page][column];
265 BCR3 = dma_len;
266 DCR3 = DMA_INT | DMA_AA | DMA_BWC(1)
267 | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE)
268 | DMA_DSIZE(DMA_SIZE_BYTE) | DMA_START;
269
270 while (dma_count > 0)
271 yield();
272
273 mutex_unlock(&lcd_mtx);
274
205} 275}
206 276
207/* Helper function. */ 277/* Helper function. */