forked from len0rd/rockbox
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
This commit is contained in:
parent
693bf86a25
commit
298bbe8d3c
2 changed files with 56 additions and 24 deletions
|
@ -22,10 +22,44 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
.section .icode, "ax", %progbits
|
.section .icode, "ax", %progbits
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* void lcd_write_line(const fb_data *addr,
|
||||||
|
* int pixelcount,
|
||||||
|
* const unsigned int lcd_base_addr);
|
||||||
|
*
|
||||||
|
* Writes pixelcount pixels from src-pointer (lcd_framebuffer) to LCD dataport.
|
||||||
|
*/
|
||||||
|
.align 2
|
||||||
|
.global lcd_write_line
|
||||||
|
.type lcd_write_line, %function
|
||||||
|
/* r0 = addr, must be aligned */
|
||||||
|
/* r1 = pixel count, must be even */
|
||||||
|
lcd_write_line: /* r2 = LCD_BASE */
|
||||||
|
stmfd sp!, {r4-r6, lr} /* save non-scratch registers */
|
||||||
|
add r12, r2, #0x40 /* LCD_WDATA = LCD data port */
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
ldmia r0!, {r3, r5} /* read 2 pixel (=8 byte) */
|
||||||
|
|
||||||
|
/* wait for FIFO half full */
|
||||||
|
.fifo_wait:
|
||||||
|
ldr lr, [r2, #0x1C] /* while (LCD_STATUS & 0x08); */
|
||||||
|
tst lr, #0x8
|
||||||
|
bgt .fifo_wait
|
||||||
|
|
||||||
|
mov r4, r3, asr #16 /* r3 = 1st pixel, r4 = 2nd pixel */
|
||||||
|
mov r6, r5, asr #16 /* r5 = 3rd pixel, r6 = 4th pixel */
|
||||||
|
stmia r12, {r3-r6} /* write pixels (lowest 16 bit used) */
|
||||||
|
|
||||||
|
subs r1, r1, #4
|
||||||
|
bgt .loop
|
||||||
|
|
||||||
|
ldmpc regs=r4-r6
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
* extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||||
* unsigned LCD_BASE,
|
* const unsigned LCD_BASE,
|
||||||
* int width,
|
* int width,
|
||||||
* int stride);
|
* int stride);
|
||||||
*
|
*
|
||||||
|
|
|
@ -312,10 +312,12 @@ void lcd_init_device(void)
|
||||||
PCON13 &= ~0xf; /* Set pin 0 to input */
|
PCON13 &= ~0xf; /* Set pin 0 to input */
|
||||||
PCON14 &= ~0xf0; /* Set pin 1 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" */
|
lcd_type = 0; /* Similar to ILI9320 - aka "type 2" */
|
||||||
else
|
} else {
|
||||||
lcd_type = 1; /* Similar to LDS176 - aka "type 7" */
|
lcd_type = 1; /* Similar to LDS176 - aka "type 7" */
|
||||||
|
LCD_PHTIME = 0x22; /* Set Phase Time reg (relevant for LCD IF speed) */
|
||||||
|
}
|
||||||
|
|
||||||
LCD_CON |= 0x100; /* use 16 bit bus width, little endian */
|
LCD_CON |= 0x100; /* use 16 bit bus width, little endian */
|
||||||
|
|
||||||
|
@ -337,6 +339,11 @@ void lcd_update(void)
|
||||||
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
|
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Line write helper function. */
|
||||||
|
extern void lcd_write_line(const fb_data *addr,
|
||||||
|
int pixelcount,
|
||||||
|
const unsigned int lcd_base_addr);
|
||||||
|
|
||||||
/* Update a fraction of the display. */
|
/* Update a fraction of the display. */
|
||||||
void lcd_update_rect(int, int, int, int) ICODE_ATTR;
|
void lcd_update_rect(int, int, int, int) ICODE_ATTR;
|
||||||
void lcd_update_rect(int x, int y, int width, int height)
|
void 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)
|
||||||
int y0, x0, y1, x1;
|
int y0, x0, y1, x1;
|
||||||
fb_data* p;
|
fb_data* p;
|
||||||
|
|
||||||
width = (width + 1) & ~1; /* ensure width is even */
|
/* Both x and width need to be preprocessed due to asm optimizations */
|
||||||
|
x = x & ~1; /* ensure x is even */
|
||||||
|
width = (width + 3) & ~3; /* ensure width is a multiple of 4 */
|
||||||
|
|
||||||
x0 = x; /* start horiz */
|
x0 = x; /* start horiz */
|
||||||
y0 = y; /* start vert */
|
y0 = y; /* start vert */
|
||||||
|
@ -376,33 +385,22 @@ void lcd_update_rect(int x, int y, int width, int height)
|
||||||
|
|
||||||
/* Copy display bitmap to hardware */
|
/* Copy display bitmap to hardware */
|
||||||
p = &lcd_framebuffer[y0][x0];
|
p = &lcd_framebuffer[y0][x0];
|
||||||
if (LCD_WIDTH == width)
|
if (LCD_WIDTH == width) {
|
||||||
{
|
/* Write all lines at once */
|
||||||
x1 = height*LCD_WIDTH/4;
|
lcd_write_line(p, height*LCD_WIDTH, LCD_BASE);
|
||||||
do {
|
|
||||||
while (LCD_STATUS & 0x08); /* wait while FIFO is half full */
|
|
||||||
lcd_write_pixel(*(p++));
|
|
||||||
lcd_write_pixel(*(p++));
|
|
||||||
lcd_write_pixel(*(p++));
|
|
||||||
lcd_write_pixel(*(p++));
|
|
||||||
} while (--x1 > 0);
|
|
||||||
} else {
|
} else {
|
||||||
y1 = height;
|
y1 = height;
|
||||||
do {
|
do {
|
||||||
x1 = width/2; /* width is forced to even to allow speed up */
|
/* Write a single line */
|
||||||
do {
|
lcd_write_line(p, width, LCD_BASE);
|
||||||
while (LCD_STATUS & 0x08); /* wait while FIFO is half full */
|
p += LCD_WIDTH;
|
||||||
lcd_write_pixel(*(p++));
|
|
||||||
lcd_write_pixel(*(p++));
|
|
||||||
} while (--x1 > 0 );
|
|
||||||
p += LCD_WIDTH - width;
|
|
||||||
} while (--y1 > 0 );
|
} while (--y1 > 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
|
/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
|
||||||
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
|
||||||
unsigned lcd_baseadress,
|
const unsigned int lcd_baseadress,
|
||||||
int width,
|
int width,
|
||||||
int stride);
|
int stride);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue