Index: firmware/target/arm/s5l8700/ipodnano2g/lcd-asm-nano2g.S =================================================================== --- firmware/target/arm/s5l8700/ipodnano2g/lcd-asm-nano2g.S (revision 28817) +++ firmware/target/arm/s5l8700/ipodnano2g/lcd-asm-nano2g.S (working copy) @@ -22,7 +22,39 @@ #include "config.h" .section .icode, "ax", %progbits + +/**************************************************************************** + * void lcd_write_data(const fb_data *addr, int pixelcount); + * + * Writes pixelcount pixels from src-pointer (lcd_framebuffer) to LCD dataport. + */ + .align 2 + .global lcd_write_data + .type lcd_write_data, %function + /* r0 = addr, must be aligned */ +lcd_write_data: /* r1 = pixel count, must be even */ + stmfd sp!, {r4-r7, lr} /* save non-scratch registers */ + ldr lr, =0x38600000 /* LCD IF base address */ + add r12, lr, #0x40 /* LCD_WDATA */ +.loop: + ldmia r0!, {r4, r6} + + /* wait for FIFO half full */ +.fifo_wait: + ldr r2, [lr, #0x1C] /* while (LCD_STATUS & 0x08); */ + tst r2, #0x8 + bgt .fifo_wait + + mov r5, r4, asr #16 + mov r7, r6, asr #16 + stmia r12, {r4-r7} + + subs r1, r1, #4 + bgt .loop + + ldmpc regs=r4-r7 + /**************************************************************************** * extern void lcd_write_yuv420_lines(unsigned char const * const src[3], * unsigned LCD_BASE, Index: firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c =================================================================== --- firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c (revision 28817) +++ firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c (working copy) @@ -312,10 +312,12 @@ PCON13 &= ~0xf; /* Set pin 0 to input */ PCON14 &= ~0xf0; /* Set pin 1 to input */ - if (((PDAT13 & 1) == 0) && ((PDAT14 & 2) == 2)) + if (((PDAT13 & 1) == 0) && ((PDAT14 & 2) == 2)) { lcd_type = 0; /* Similar to ILI9320 - aka "type 2" */ - else - lcd_type = 1; /* Similar to LDS176 - aka "type 7" */ + } else { + lcd_type = 1; /* Similar to LDS176 - aka "type 7" */ + LCD_PHTIME = 0x00; + } LCD_CON |= 0x100; /* use 16 bit bus width, little endian */ @@ -337,6 +339,8 @@ lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); } +extern void lcd_write_data(const fb_data *addr, int pixelcount); + /* Update a fraction of the display. */ void lcd_update_rect(int, int, int, int) ICODE_ATTR; void lcd_update_rect(int x, int y, int width, int height) @@ -344,7 +348,8 @@ int y0, x0, y1, x1; fb_data* p; - width = (width + 1) & ~1; /* ensure width is even */ + x = x & ~1; /* ensure x is even */ + width = (width + 3) & ~3; /* ensure width is a multiple of 4 */ x0 = x; /* start horiz */ y0 = y; /* start vert */ @@ -378,6 +383,9 @@ p = &lcd_framebuffer[y0][x0]; if (LCD_WIDTH == width) { +#if 1 + lcd_write_data(p, height*LCD_WIDTH); +#else x1 = height*LCD_WIDTH/4; do { while (LCD_STATUS & 0x08); /* wait while FIFO is half full */ @@ -386,9 +394,14 @@ lcd_write_pixel(*(p++)); lcd_write_pixel(*(p++)); } while (--x1 > 0); +#endif } else { y1 = height; do { +#if 1 + lcd_write_data(p, width); + p += LCD_WIDTH; +#else x1 = width/2; /* width is forced to even to allow speed up */ do { while (LCD_STATUS & 0x08); /* wait while FIFO is half full */ @@ -396,6 +409,7 @@ lcd_write_pixel(*(p++)); } while (--x1 > 0 ); p += LCD_WIDTH - width; +#endif } while (--y1 > 0 ); } }