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"
|
||||
|
||||
.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],
|
||||
* unsigned LCD_BASE,
|
||||
* const unsigned LCD_BASE,
|
||||
* int width,
|
||||
* int stride);
|
||||
*
|
||||
|
|
|
@ -312,10 +312,12 @@ void lcd_init_device(void)
|
|||
PCON13 &= ~0xf; /* Set pin 0 to input */
|
||||
PCON14 &= ~0xf0; /* Set pin 1 to input */
|
||||
|
||||
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" */
|
||||
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" */
|
||||
LCD_PHTIME = 0x22; /* Set Phase Time reg (relevant for LCD IF speed) */
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
void lcd_update_rect(int, int, int, int) ICODE_ATTR;
|
||||
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;
|
||||
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 */
|
||||
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 */
|
||||
p = &lcd_framebuffer[y0][x0];
|
||||
if (LCD_WIDTH == width)
|
||||
{
|
||||
x1 = height*LCD_WIDTH/4;
|
||||
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);
|
||||
if (LCD_WIDTH == width) {
|
||||
/* Write all lines at once */
|
||||
lcd_write_line(p, height*LCD_WIDTH, LCD_BASE);
|
||||
} else {
|
||||
y1 = height;
|
||||
do {
|
||||
x1 = width/2; /* width is forced to even to allow speed up */
|
||||
do {
|
||||
while (LCD_STATUS & 0x08); /* wait while FIFO is half full */
|
||||
lcd_write_pixel(*(p++));
|
||||
lcd_write_pixel(*(p++));
|
||||
} while (--x1 > 0 );
|
||||
p += LCD_WIDTH - width;
|
||||
/* Write a single line */
|
||||
lcd_write_line(p, width, LCD_BASE);
|
||||
p += LCD_WIDTH;
|
||||
} while (--y1 > 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/* 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],
|
||||
unsigned lcd_baseadress,
|
||||
const unsigned int lcd_baseadress,
|
||||
int width,
|
||||
int stride);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue