summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2010-12-13 19:58:04 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2010-12-13 19:58:04 +0000
commit298bbe8d3c1ab612d43a56b659a117d0ef12cd4c (patch)
tree2e328c12e90a1bb6624a3edb4c256f0b68459e53
parent693bf86a25ecf61e6bfa345529ab1bec2d8790f9 (diff)
downloadrockbox-298bbe8d3c1ab612d43a56b659a117d0ef12cd4c.tar.gz
rockbox-298bbe8d3c1ab612d43a56b659a117d0ef12cd4c.zip
FS#11807 - Major speedup of iPod nano 2G. Part 5: Introduce asm for RGB screen updates, set LCD_PHTIME to Apple's default for LDS176 type LCD's.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28824 a1c6a512-1295-4272-9138-f99709370657
-rwxr-xr-xfirmware/target/arm/s5l8700/ipodnano2g/lcd-asm-nano2g.S36
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c44
2 files changed, 56 insertions, 24 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/lcd-asm-nano2g.S b/firmware/target/arm/s5l8700/ipodnano2g/lcd-asm-nano2g.S
index 25cf662c3f..3902d34133 100755
--- a/firmware/target/arm/s5l8700/ipodnano2g/lcd-asm-nano2g.S
+++ b/firmware/target/arm/s5l8700/ipodnano2g/lcd-asm-nano2g.S
@@ -22,10 +22,44 @@
22#include "config.h" 22#include "config.h"
23 23
24 .section .icode, "ax", %progbits 24 .section .icode, "ax", %progbits
25
26/****************************************************************************
27 * void lcd_write_line(const fb_data *addr,
28 * int pixelcount,
29 * const unsigned int lcd_base_addr);
30 *
31 * Writes pixelcount pixels from src-pointer (lcd_framebuffer) to LCD dataport.
32 */
33 .align 2
34 .global lcd_write_line
35 .type lcd_write_line, %function
36 /* r0 = addr, must be aligned */
37 /* r1 = pixel count, must be even */
38lcd_write_line: /* r2 = LCD_BASE */
39 stmfd sp!, {r4-r6, lr} /* save non-scratch registers */
40 add r12, r2, #0x40 /* LCD_WDATA = LCD data port */
41
42.loop:
43 ldmia r0!, {r3, r5} /* read 2 pixel (=8 byte) */
44
45 /* wait for FIFO half full */
46.fifo_wait:
47 ldr lr, [r2, #0x1C] /* while (LCD_STATUS & 0x08); */
48 tst lr, #0x8
49 bgt .fifo_wait
50
51 mov r4, r3, asr #16 /* r3 = 1st pixel, r4 = 2nd pixel */
52 mov r6, r5, asr #16 /* r5 = 3rd pixel, r6 = 4th pixel */
53 stmia r12, {r3-r6} /* write pixels (lowest 16 bit used) */
54
55 subs r1, r1, #4
56 bgt .loop
57
58 ldmpc regs=r4-r6
25 59
26/**************************************************************************** 60/****************************************************************************
27 * extern void lcd_write_yuv420_lines(unsigned char const * const src[3], 61 * extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
28 * unsigned LCD_BASE, 62 * const unsigned LCD_BASE,
29 * int width, 63 * int width,
30 * int stride); 64 * int stride);
31 * 65 *
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c
index d1c41d652f..7b177f4fc4 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c
@@ -312,10 +312,12 @@ void lcd_init_device(void)
312 PCON13 &= ~0xf; /* Set pin 0 to input */ 312 PCON13 &= ~0xf; /* Set pin 0 to input */
313 PCON14 &= ~0xf0; /* Set pin 1 to input */ 313 PCON14 &= ~0xf0; /* Set pin 1 to input */
314 314
315 if (((PDAT13 & 1) == 0) && ((PDAT14 & 2) == 2)) 315 if (((PDAT13 & 1) == 0) && ((PDAT14 & 2) == 2)) {
316 lcd_type = 0; /* Similar to ILI9320 - aka "type 2" */ 316 lcd_type = 0; /* Similar to ILI9320 - aka "type 2" */
317 else 317 } else {
318 lcd_type = 1; /* Similar to LDS176 - aka "type 7" */ 318 lcd_type = 1; /* Similar to LDS176 - aka "type 7" */
319 LCD_PHTIME = 0x22; /* Set Phase Time reg (relevant for LCD IF speed) */
320 }
319 321
320 LCD_CON |= 0x100; /* use 16 bit bus width, little endian */ 322 LCD_CON |= 0x100; /* use 16 bit bus width, little endian */
321 323
@@ -337,6 +339,11 @@ void lcd_update(void)
337 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); 339 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
338} 340}
339 341
342/* Line write helper function. */
343extern void lcd_write_line(const fb_data *addr,
344 int pixelcount,
345 const unsigned int lcd_base_addr);
346
340/* Update a fraction of the display. */ 347/* Update a fraction of the display. */
341void lcd_update_rect(int, int, int, int) ICODE_ATTR; 348void lcd_update_rect(int, int, int, int) ICODE_ATTR;
342void lcd_update_rect(int x, int y, int width, int height) 349void lcd_update_rect(int x, int y, int width, int height)
@@ -344,7 +351,9 @@ void lcd_update_rect(int x, int y, int width, int height)
344 int y0, x0, y1, x1; 351 int y0, x0, y1, x1;
345 fb_data* p; 352 fb_data* p;
346 353
347 width = (width + 1) & ~1; /* ensure width is even */ 354 /* Both x and width need to be preprocessed due to asm optimizations */
355 x = x & ~1; /* ensure x is even */
356 width = (width + 3) & ~3; /* ensure width is a multiple of 4 */
348 357
349 x0 = x; /* start horiz */ 358 x0 = x; /* start horiz */
350 y0 = y; /* start vert */ 359 y0 = y; /* start vert */
@@ -376,33 +385,22 @@ void lcd_update_rect(int x, int y, int width, int height)
376 385
377 /* Copy display bitmap to hardware */ 386 /* Copy display bitmap to hardware */
378 p = &lcd_framebuffer[y0][x0]; 387 p = &lcd_framebuffer[y0][x0];
379 if (LCD_WIDTH == width) 388 if (LCD_WIDTH == width) {
380 { 389 /* Write all lines at once */
381 x1 = height*LCD_WIDTH/4; 390 lcd_write_line(p, height*LCD_WIDTH, LCD_BASE);
382 do {
383 while (LCD_STATUS & 0x08); /* wait while FIFO is half full */
384 lcd_write_pixel(*(p++));
385 lcd_write_pixel(*(p++));
386 lcd_write_pixel(*(p++));
387 lcd_write_pixel(*(p++));
388 } while (--x1 > 0);
389 } else { 391 } else {
390 y1 = height; 392 y1 = height;
391 do { 393 do {
392 x1 = width/2; /* width is forced to even to allow speed up */ 394 /* Write a single line */
393 do { 395 lcd_write_line(p, width, LCD_BASE);
394 while (LCD_STATUS & 0x08); /* wait while FIFO is half full */ 396 p += LCD_WIDTH;
395 lcd_write_pixel(*(p++));
396 lcd_write_pixel(*(p++));
397 } while (--x1 > 0 );
398 p += LCD_WIDTH - width;
399 } while (--y1 > 0 ); 397 } while (--y1 > 0 );
400 } 398 }
401} 399}
402 400
403/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */ 401/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
404extern void lcd_write_yuv420_lines(unsigned char const * const src[3], 402extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
405 unsigned lcd_baseadress, 403 const unsigned int lcd_baseadress,
406 int width, 404 int width,
407 int stride); 405 int stride);
408 406