diff options
Diffstat (limited to 'firmware/target/arm/s5l8702/ipod6g/lcd-asm-ipod6g.S')
-rw-r--r-- | firmware/target/arm/s5l8702/ipod6g/lcd-asm-ipod6g.S | 81 |
1 files changed, 13 insertions, 68 deletions
diff --git a/firmware/target/arm/s5l8702/ipod6g/lcd-asm-ipod6g.S b/firmware/target/arm/s5l8702/ipod6g/lcd-asm-ipod6g.S index 7d9e8274d5..ec8a24c4e5 100644 --- a/firmware/target/arm/s5l8702/ipod6g/lcd-asm-ipod6g.S +++ b/firmware/target/arm/s5l8702/ipod6g/lcd-asm-ipod6g.S | |||
@@ -19,57 +19,15 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #define FORCE_FIFO_WAIT | ||
23 | /**************************************************************************** | ||
24 | * #define FORCE_FIFO_WAIT | ||
25 | * | ||
26 | * This is not needed in YUV blitting when the LCD IF is fast enough. In this | ||
27 | * case YUV-to-RGB conversion per pixel needs longer than the transfer of a | ||
28 | * pixel via the LCD IF. For iPod nano 2G this is true if the LCD IF is | ||
29 | * configured to use LCD_PHTIME = 0x00 (see lcd-nano2g.c). | ||
30 | ****************************************************************************/ | ||
31 | 22 | ||
32 | #include "config.h" | 23 | #include "config.h" |
33 | 24 | ||
34 | .section .icode, "ax", %progbits | 25 | .section .icode, "ax", %progbits |
35 | 26 | ||
36 | /**************************************************************************** | ||
37 | * void lcd_write_line(const fb_data *addr, | ||
38 | * int pixelcount, | ||
39 | * const unsigned int lcd_base_addr); | ||
40 | * | ||
41 | * Writes pixelcount pixels from src-pointer (lcd_framebuffer) to LCD dataport. | ||
42 | */ | ||
43 | .align 2 | ||
44 | .global lcd_write_line | ||
45 | .type lcd_write_line, %function | ||
46 | /* r0 = addr, must be aligned */ | ||
47 | /* r1 = pixel count, must be even */ | ||
48 | lcd_write_line: /* r2 = LCD_BASE */ | ||
49 | stmfd sp!, {r4-r6, lr} /* save non-scratch registers */ | ||
50 | add r12, r2, #0x40 /* LCD_WDATA = LCD data port */ | ||
51 | |||
52 | .loop: | ||
53 | ldmia r0!, {r3, r5} /* read 2 pixel (=8 byte) */ | ||
54 | |||
55 | /* wait for FIFO half full */ | ||
56 | .fifo_wait: | ||
57 | ldr lr, [r2, #0x1C] /* while (LCD_STATUS & 0x08); */ | ||
58 | tst lr, #0x8 | ||
59 | bgt .fifo_wait | ||
60 | |||
61 | mov r4, r3, asr #16 /* r3 = 1st pixel, r4 = 2nd pixel */ | ||
62 | mov r6, r5, asr #16 /* r5 = 3rd pixel, r6 = 4th pixel */ | ||
63 | stmia r12, {r3-r6} /* write pixels (lowest 16 bit used) */ | ||
64 | |||
65 | subs r1, r1, #4 | ||
66 | bgt .loop | ||
67 | |||
68 | ldmpc regs=r4-r6 | ||
69 | 27 | ||
70 | /**************************************************************************** | 28 | /**************************************************************************** |
71 | * extern void lcd_write_yuv420_lines(unsigned char const * const src[3], | 29 | * extern void lcd_write_yuv420_lines(unsigned char const * const src[3], |
72 | * const unsigned LCD_BASE, | 30 | * uint16_t* out, |
73 | * int width, | 31 | * int width, |
74 | * int stride); | 32 | * int stride); |
75 | * | 33 | * |
@@ -93,7 +51,7 @@ lcd_write_line: /* r2 = LCD_BASE */ | |||
93 | .type lcd_write_yuv420_lines, %function | 51 | .type lcd_write_yuv420_lines, %function |
94 | lcd_write_yuv420_lines: | 52 | lcd_write_yuv420_lines: |
95 | /* r0 = src = yuv_src */ | 53 | /* r0 = src = yuv_src */ |
96 | /* r1 = dst = LCD_BASE */ | 54 | /* r1 = dst = out */ |
97 | /* r2 = width */ | 55 | /* r2 = width */ |
98 | /* r3 = stride */ | 56 | /* r3 = stride */ |
99 | stmfd sp!, { r4-r10, lr } /* save non-scratch */ | 57 | stmfd sp!, { r4-r10, lr } /* save non-scratch */ |
@@ -103,14 +61,14 @@ lcd_write_yuv420_lines: | |||
103 | add r3, r9, r3 /* r3 = &ysrc[stride] */ | 61 | add r3, r9, r3 /* r3 = &ysrc[stride] */ |
104 | add r4, r2, r2, asr #1 /* chroma buffer lenght = width/2 *3 */ | 62 | add r4, r2, r2, asr #1 /* chroma buffer lenght = width/2 *3 */ |
105 | mov r4, r4, asl #2 /* use words for str/ldm possibility */ | 63 | mov r4, r4, asl #2 /* use words for str/ldm possibility */ |
106 | add r4, r4, #19 /* plus room for 4 additional words, */ | 64 | add r4, r4, #15 /* plus room for 3 additional words, */ |
107 | bic r4, r4, #3 /* rounded up to multiples of 4 byte */ | 65 | bic r4, r4, #3 /* rounded up to multiples of 4 byte */ |
108 | sub sp, sp, r4 /* and allocate on stack */ | 66 | sub sp, sp, r4 /* and allocate on stack */ |
109 | stmia sp, {r1-r4} /* LCD_BASE, width, &ysrc[stride], stack_alloc */ | 67 | stmia sp, {r2-r4} /* width, &ysrc[stride], stack_alloc */ |
110 | 68 | ||
111 | mov r7, r2 /* r7 = loop count */ | 69 | mov r7, r2 /* r7 = loop count */ |
112 | add r8, sp, #16 /* chroma buffer */ | 70 | add r8, sp, #12 /* chroma buffer */ |
113 | add lr, r1, #0x40 /* LCD data port = LCD_BASE + 0x40 */ | 71 | mov lr, r1 /* RGB565 data destination buffer */ |
114 | 72 | ||
115 | /* 1st loop start */ | 73 | /* 1st loop start */ |
116 | 10: /* loop start */ | 74 | 10: /* loop start */ |
@@ -195,23 +153,16 @@ lcd_write_yuv420_lines: | |||
195 | /* calculate pixel_2 and pack with pixel_1 before writing */ | 153 | /* calculate pixel_2 and pack with pixel_1 before writing */ |
196 | orr r5, r5, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */ | 154 | orr r5, r5, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */ |
197 | orr r5, r5, r6, lsl #11 /* r5 = pixel_2 */ | 155 | orr r5, r5, r6, lsl #11 /* r5 = pixel_2 */ |
198 | #ifdef FORCE_FIFO_WAIT | 156 | orr r4, r4, r5, lsl #16 |
199 | /* wait for FIFO half full */ | 157 | str r4, [lr], #4 /* write pixel_1 and pixel_2 */ |
200 | .fifo_wait1: | ||
201 | ldr r3, [lr, #-0x24] /* while (LCD_STATUS & 0x08); */ | ||
202 | tst r3, #0x8 | ||
203 | bgt .fifo_wait1 | ||
204 | #endif | ||
205 | stmia lr, {r4,r5} /* write pixel_1 and pixel_2 */ | ||
206 | 158 | ||
207 | subs r7, r7, #2 /* check for loop end */ | 159 | subs r7, r7, #2 /* check for loop end */ |
208 | bgt 10b /* back to beginning */ | 160 | bgt 10b /* back to beginning */ |
209 | /* 1st loop end */ | 161 | /* 1st loop end */ |
210 | 162 | ||
211 | /* Reload several registers for pointer rewinding for next loop */ | 163 | /* Reload several registers for pointer rewinding for next loop */ |
212 | add r8, sp, #16 /* chroma buffer */ | 164 | add r8, sp, #12 /* chroma buffer */ |
213 | ldmia sp, { r1, r7, r9} /* r1 = LCD_BASE */ | 165 | ldmia sp, {r7, r9} /* r7 = loop count */ |
214 | /* r7 = loop count */ | ||
215 | /* r9 = &ysrc[stride] */ | 166 | /* r9 = &ysrc[stride] */ |
216 | 167 | ||
217 | /* 2nd loop start */ | 168 | /* 2nd loop start */ |
@@ -275,20 +226,14 @@ lcd_write_yuv420_lines: | |||
275 | /* calculate pixel_2 and pack with pixel_1 before writing */ | 226 | /* calculate pixel_2 and pack with pixel_1 before writing */ |
276 | orr r5, r5, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */ | 227 | orr r5, r5, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */ |
277 | orr r5, r5, r6, lsl #11 /* r5 = pixel_2 */ | 228 | orr r5, r5, r6, lsl #11 /* r5 = pixel_2 */ |
278 | #ifdef FORCE_FIFO_WAIT | 229 | orr r4, r4, r5, lsl #16 |
279 | /* wait for FIFO half full */ | 230 | str r4, [lr], #4 /* write pixel_1 and pixel_2 */ |
280 | .fifo_wait2: | ||
281 | ldr r3, [lr, #-0x24] /* while (LCD_STATUS & 0x08); */ | ||
282 | tst r3, #0x8 | ||
283 | bgt .fifo_wait2 | ||
284 | #endif | ||
285 | stmia lr, {r4,r5} /* write pixel_1 and pixel_2 */ | ||
286 | 231 | ||
287 | subs r7, r7, #2 /* check for loop end */ | 232 | subs r7, r7, #2 /* check for loop end */ |
288 | bgt 20b /* back to beginning */ | 233 | bgt 20b /* back to beginning */ |
289 | /* 2nd loop end */ | 234 | /* 2nd loop end */ |
290 | 235 | ||
291 | ldr r3, [sp, #12] | 236 | ldr r3, [sp, #8] |
292 | add sp, sp, r3 /* deallocate buffer */ | 237 | add sp, sp, r3 /* deallocate buffer */ |
293 | ldmpc regs=r4-r10 /* restore registers */ | 238 | ldmpc regs=r4-r10 /* restore registers */ |
294 | 239 | ||