summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-04-05 12:01:44 +0000
committerThomas Martitz <kugel@rockbox.org>2010-04-05 12:01:44 +0000
commit446a67698fc1d205637f8a489cee472c611d4b5f (patch)
treeaf5c7a12a29a1ca4729bd2f2b4e220047192aa0c
parent95b03d297459960fd8c4d063b122d16a50aa51d2 (diff)
downloadrockbox-446a67698fc1d205637f8a489cee472c611d4b5f.tar.gz
rockbox-446a67698fc1d205637f8a489cee472c611d4b5f.zip
Fuzev2: Reduce code duplication by reusing Fuzev1 code.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25481 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES7
-rw-r--r--firmware/target/arm/as3525/dbop-as3525.c21
-rw-r--r--firmware/target/arm/as3525/lcd-as-e200v2-fuze.S500
-rw-r--r--firmware/target/arm/as3525/sansa-fuzev2/lcd-as-fuzev2.S530
-rw-r--r--firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c65
5 files changed, 25 insertions, 1098 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 2ee04f2815..a61331f8f0 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1252,7 +1252,7 @@ target/arm/as3525/sansa-clip/powermgmt-clip.c
1252#ifdef SANSA_E200V2 1252#ifdef SANSA_E200V2
1253#ifndef SIMULATOR 1253#ifndef SIMULATOR
1254target/arm/as3525/sansa-e200v2/lcd-e200v2.c 1254target/arm/as3525/sansa-e200v2/lcd-e200v2.c
1255target/arm/as3525/lcd-as-e200v2-fuze.S 1255target/arm/as3525/lcd-as-e200v2-fuze-fuzev2.S
1256target/arm/as3525/button-e200v2-fuze.c 1256target/arm/as3525/button-e200v2-fuze.c
1257target/arm/as3525/backlight-e200v2-fuze.c 1257target/arm/as3525/backlight-e200v2-fuze.c
1258target/arm/as3525/dbop-as3525.c 1258target/arm/as3525/dbop-as3525.c
@@ -1290,7 +1290,7 @@ target/arm/as3525/sansa-m200v4/powermgmt-m200v4.c
1290#ifndef SIMULATOR 1290#ifndef SIMULATOR
1291target/arm/as3525/button-e200v2-fuze.c 1291target/arm/as3525/button-e200v2-fuze.c
1292target/arm/as3525/sansa-fuze/lcd-fuze.c 1292target/arm/as3525/sansa-fuze/lcd-fuze.c
1293target/arm/as3525/lcd-as-e200v2-fuze.S 1293target/arm/as3525/lcd-as-e200v2-fuze-fuzev2.S
1294target/arm/as3525/backlight-e200v2-fuze.c 1294target/arm/as3525/backlight-e200v2-fuze.c
1295target/arm/as3525/dbop-as3525.c 1295target/arm/as3525/dbop-as3525.c
1296#ifndef BOOTLOADER 1296#ifndef BOOTLOADER
@@ -1303,9 +1303,10 @@ target/arm/as3525/sansa-fuze/powermgmt-fuze.c
1303#ifdef SANSA_FUZEV2 1303#ifdef SANSA_FUZEV2
1304#ifndef SIMULATOR 1304#ifndef SIMULATOR
1305target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c 1305target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c
1306target/arm/as3525/sansa-fuzev2/lcd-as-fuzev2.S 1306target/arm/as3525/lcd-as-e200v2-fuze-fuzev2.S
1307target/arm/as3525/sansa-fuzev2/backlight-fuzev2.c 1307target/arm/as3525/sansa-fuzev2/backlight-fuzev2.c
1308target/arm/as3525/sansa-fuzev2/button-fuzev2.c 1308target/arm/as3525/sansa-fuzev2/button-fuzev2.c
1309target/arm/as3525/dbop-as3525.c
1309#ifndef BOOTLOADER 1310#ifndef BOOTLOADER
1310target/arm/powermgmt-ascodec.c 1311target/arm/powermgmt-ascodec.c
1311target/arm/as3525/sansa-fuzev2/powermgmt-fuzev2.c 1312target/arm/as3525/sansa-fuzev2/powermgmt-fuzev2.c
diff --git a/firmware/target/arm/as3525/dbop-as3525.c b/firmware/target/arm/as3525/dbop-as3525.c
index 1730290d46..5ca551ca70 100644
--- a/firmware/target/arm/as3525/dbop-as3525.c
+++ b/firmware/target/arm/as3525/dbop-as3525.c
@@ -30,6 +30,8 @@
30#define DBOP_PRECHARGE 0xF0FF 30#define DBOP_PRECHARGE 0xF0FF
31#endif 31#endif
32 32
33#if CONFIG_CPU == AS3525
34/* doesn't work with the new ams sansas so far and is not needed */
33static short int dbop_input_value = 0; 35static short int dbop_input_value = 0;
34 36
35/* read the DBOP data pins */ 37/* read the DBOP data pins */
@@ -77,13 +79,24 @@ unsigned short dbop_debug(void)
77 return dbop_input_value; 79 return dbop_input_value;
78} 80}
79 81
82#endif
83
80static inline void dbop_set_mode(int mode) 84static inline void dbop_set_mode(int mode)
81{ 85{
82 int delay = 10; 86 int delay = 10;
83 if (mode == 32 && (!(DBOP_CTRL & (1<<13|1<<14)))) 87 unsigned long ctrl = DBOP_CTRL;
84 DBOP_CTRL |= (1<<13|1<<14); 88 int curr_mode = (DBOP_CTRL >> 13) & 0x3; // bits 14:13
85 else if (mode == 16 && (DBOP_CTRL & (1<<13|1<<14))) 89#ifdef SANSA_FUZEV2
86 DBOP_CTRL &= ~(1<<14|1<<13); 90 if (mode == 32 && curr_mode != 1<<1)
91 DBOP_CTRL = (ctrl & ~(1<<13)) | (1<<14); // 2 serial half words
92 else if (mode == 16 && curr_mode != 1<<0)
93 DBOP_CTRL = (ctrl & ~(1<<14)) | (1<<13); // 2 serial bytes
94#else
95 if (mode == 32 && curr_mode == 0)
96 DBOP_CTRL = ctrl | (1<<13|1<<14); /* 2 serial half words */
97 else if (mode == 16 && curr_mode == (1<<1|1<<0))
98 DBOP_CTRL = ctrl & ~(1<<14|1<<13); /* 1 serial half word */
99#endif
87 else 100 else
88 return; 101 return;
89 while(delay--) asm volatile("nop"); 102 while(delay--) asm volatile("nop");
diff --git a/firmware/target/arm/as3525/lcd-as-e200v2-fuze.S b/firmware/target/arm/as3525/lcd-as-e200v2-fuze.S
deleted file mode 100644
index 2725c926a8..0000000000
--- a/firmware/target/arm/as3525/lcd-as-e200v2-fuze.S
+++ /dev/null
@@ -1,500 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Jens Arnold
11 * Heavily based on lcd-as-memframe.c by Michael Sevakis
12 * Adapted for Sansa Fuze/e200v2 by Rafaël Carré
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#include "config.h"
25#include "cpu.h"
26
27#define DBOP_BUSY (1<<10)
28
29/****************************************************************************
30 * void lcd_write_yuv_420_lines(unsigned char const * const src[3],
31 * int width,
32 * int stride);
33 *
34 * |R| |1.000000 -0.000001 1.402000| |Y'|
35 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
36 * |B| |1.000000 1.772000 0.000000| |Pr|
37 * Scaled, normalized, rounded and tweaked to yield RGB 565:
38 * |R| |74 0 101| |Y' - 16| >> 9
39 * |G| = |74 -24 -51| |Cb - 128| >> 8
40 * |B| |74 128 0| |Cr - 128| >> 9
41 *
42 * Write four RGB565 pixels in the following order on each loop:
43 * 1 3 + > down
44 * 2 4 \/ left
45 */
46 .section .icode, "ax", %progbits
47 .align 2
48 .global lcd_write_yuv420_lines
49 .type lcd_write_yuv420_lines, %function
50lcd_write_yuv420_lines:
51 @ r0 = yuv_src
52 @ r1 = width
53 @ r2 = stride
54 stmfd sp!, { r4-r11, lr } @ save non-scratch
55
56 mov r3, #0xC8000000 @
57 orr r3, r3, #0x120000 @ r3 = DBOP_BASE
58
59 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
60 @ r5 = yuv_src[1] = Cb_p
61 @ r6 = yuv_src[2] = Cr_p
62 @ r0 = scratch
63 ldr r12, [r3, #8] @
64 sub r2, r2, #1 @ stride -= 1
65 orr r12, r12, #3<<13 @
66 str r12, [r3, #8] @ DBOP_CTRL |= (1<<13|1<<14) (32bit mode)
6710: @ loop line @
68 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
69 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
70 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
71 @
72 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
73 add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
74 add r7, r12, r7, asl #5 @ by one less when adding - same for all
75 @
76 sub r8, r8, #128 @ Cb -= 128
77 sub r9, r9, #128 @ Cr -= 128
78 @
79 add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
80 add r10, r10, r10, asl #4 @
81 add r10, r10, r8, asl #3 @
82 add r10, r10, r8, asl #4 @
83 @
84 add lr, r9, r9, asl #2 @ r9 = Cr*101
85 add lr, lr, r9, asl #5 @
86 add r9, lr, r9, asl #6 @
87 @
88 add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
89 mov r8, r8, asr #2 @
90 add r9, r9, #256 @ r9 = rv = (r9 + 256) >> 9
91 mov r9, r9, asr #9 @
92 rsb r10, r10, #128 @ r10 = guv = (-r10 + 128) >> 8
93 mov r10, r10, asr #8 @
94 @ compute R, G, and B
95 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
96 add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
97 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
98 @
99 orr r12, r0, lr @ check if clamping is needed...
100 orr r12, r12, r7, asr #1 @ ...at all
101 cmp r12, #31 @
102 bls 15f @ no clamp @
103 cmp r0, #31 @ clamp b
104 mvnhi r0, r0, asr #31 @
105 andhi r0, r0, #31 @
106 cmp lr, #31 @ clamp r
107 mvnhi lr, lr, asr #31 @
108 andhi lr, lr, #31 @
109 cmp r7, #63 @ clamp g
110 mvnhi r7, r7, asr #31 @
111 andhi r7, r7, #63 @
11215: @ no clamp @
113 @
114 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
115 @
116 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
117 orr r11, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
118 @
119 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
120 add r12, r7, r7, asl #2 @
121 add r7, r12, r7, asl #5 @
122 @ compute R, G, and B
123 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
124 add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
125 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
126 @
127 orr r12, r0, lr @ check if clamping is needed...
128 orr r12, r12, r7, asr #1 @ ...at all
129 cmp r12, #31 @
130 bls 15f @ no clamp @
131 cmp r0, #31 @ clamp b
132 mvnhi r0, r0, asr #31 @
133 andhi r0, r0, #31 @
134 cmp lr, #31 @ clamp r
135 mvnhi lr, lr, asr #31 @
136 andhi lr, lr, #31 @
137 cmp r7, #63 @ clamp g
138 mvnhi r7, r7, asr #31 @
139 andhi r7, r7, #63 @
14015: @ no clamp @
141 @
142 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
143 @
144 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
145 orr r0, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
146 orr r0, r11, r0, lsl#16 @ pack with 2nd pixel
147 str r0, [r3, #0x10] @ write pixel
148 @
149 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
150 add r12, r7, r7, asl #2 @
151 add r7, r12, r7, asl #5 @
152 @ compute R, G, and B
153 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
154 add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
155 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
156 @
157 orr r12, r0, lr @ check if clamping is needed...
158 orr r12, r12, r7, asr #1 @ ...at all
159 cmp r12, #31 @
160 bls 15f @ no clamp @
161 cmp r0, #31 @ clamp b
162 mvnhi r0, r0, asr #31 @
163 andhi r0, r0, #31 @
164 cmp lr, #31 @ clamp r
165 mvnhi lr, lr, asr #31 @
166 andhi lr, lr, #31 @
167 cmp r7, #63 @ clamp g
168 mvnhi r7, r7, asr #31 @
169 andhi r7, r7, #63 @
17015: @ no clamp @
171 @
172 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
173 @
174 @
175 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
176 orr r11, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
177 @
178 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
179 add r12, r7, r7, asl #2 @
180 add r7, r12, r7, asl #5 @
181 @ compute R, G, and B
182 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
183 add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
184 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
185 @
186 orr r12, r0, lr @ check if clamping is needed...
187 orr r12, r12, r7, asr #1 @ ...at all
188 cmp r12, #31 @
189 bls 15f @ no clamp @
190 cmp r0, #31 @ clamp b
191 mvnhi r0, r0, asr #31 @
192 andhi r0, r0, #31 @
193 cmp lr, #31 @ clamp r
194 mvnhi lr, lr, asr #31 @
195 andhi lr, lr, #31 @
196 cmp r7, #63 @ clamp g
197 mvnhi r7, r7, asr #31 @
198 andhi r7, r7, #63 @
19915: @ no clamp @
200 @
201 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
202 orr r0, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
203 orr r0, r11, r0, lsl#16 @ pack with 2nd pixel
204 str r0, [r3, #0x10] @ write pixel
205 @
206 subs r1, r1, #2 @ subtract block from width
207 bgt 10b @ loop line @
208 @
2091: @ busy
210 @ writing at max 110*32 its (LCD_WIDTH/2), the fifo is bigger
211 @ so polling fifo empty after the loops is save
212 ldr r7, [r3,#0xc] @ r7 = DBOP_STATUS
213 tst r7, #DBOP_BUSY @ fifo not empty?
214 beq 1b @
215
216 ldmfd sp!, { r4-r11, pc } @ restore registers and return
217 bx lr @
218 .ltorg @ dump constant pool
219 .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
220
221/****************************************************************************
222 * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
223 * int width,
224 * int stride,
225 * int x_screen,
226 * int y_screen);
227 *
228 * |R| |1.000000 -0.000001 1.402000| |Y'|
229 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
230 * |B| |1.000000 1.772000 0.000000| |Pr|
231 * Red scaled at twice g & b but at same precision to place it in correct
232 * bit position after multiply and leave instruction count lower.
233 * |R| |258 0 408| |Y' - 16|
234 * |G| = |149 -49 -104| |Cb - 128|
235 * |B| |149 258 0| |Cr - 128|
236 *
237 * Write four RGB565 pixels in the following order on each loop:
238 * 1 3 + > down
239 * 2 4 \/ left
240 *
241 * Kernel pattern (raw|rotated|use order):
242 * 5 3 4 2 2 6 3 7 row0 row2 > down
243 * 1 7 0 6 | 4 0 5 1 | 2 4 6 0 3 5 7 1 col0 left
244 * 4 2 5 3 | 3 7 2 6 | 3 5 7 1 2 4 6 0 col2 \/
245 * 0 6 1 7 5 1 4 0
246 */
247 .section .icode, "ax", %progbits
248 .align 2
249 .global lcd_write_yuv420_lines_odither
250 .type lcd_write_yuv420_lines_odither, %function
251lcd_write_yuv420_lines_odither:
252 @ r0 = yuv_src
253 @ r1 = width
254 @ r2 = stride
255 @ r3 = x_screen
256 @ [sp] = y_screen
257 stmfd sp!, { r4-r11, lr } @ save non-scratch
258 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
259 @ r5 = yuv_src[1] = Cb_p
260 @ r6 = yuv_src[2] = Cr_p
261 @
262 ldr r14, [sp, #40] @ Line up pattern and kernel quadrant
263 sub r2, r2, #1 @ stride =- 1
264 eor r14, r14, r3 @
265 and r14, r14, #0x2 @
266 mov r14, r14, lsl #6 @ 0x00 or 0x80
267
268 mov r3, #0xC8000000 @
269 orr r3, r3, #0x120000 @ r3 = DBOP_BASE, need to be redone
270 @ due to lack of registers
271 ldr r12, [r3, #8] @
272 orr r12, r12, #3<<13 @ DBOP_CTRL |= (1<<13|1<<14)
273 str r12, [r3, #8] @ (32bit mode)
27410: @ loop line @
275 @
276 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
277 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
278 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
279 @
280 eor r14, r14, #0x80 @ flip pattern quadrant
281 @
282 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
283 add r12, r7, r7, asl #2 @
284 add r12, r12, r12, asl #4 @
285 add r7, r12, r7, asl #6 @
286 @
287 sub r8, r8, #128 @ Cb -= 128
288 sub r9, r9, #128 @ Cr -= 128
289 @
290 add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
291 add r10, r10, r8, asl #5 @
292 add r10, r10, r9, asl #3 @
293 add r10, r10, r9, asl #5 @
294 add r10, r10, r9, asl #6 @
295 @
296 mov r8, r8, asl #1 @ r8 = bu = Cb*258
297 add r8, r8, r8, asl #7 @
298 @
299 add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
300 add r9, r9, r9, asl #4 @
301 mov r9, r9, asl #3 @
302 @
303 @ compute R, G, and B
304 add r0, r8, r7 @ r0 = b' = Y + bu
305 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
306 rsb r7, r10, r7 @ r7 = g' = Y + guv
307 @
308 @ r8 = bu, r9 = rv, r10 = guv
309 @
310 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
311 add r0, r12, r0, lsr #8 @
312 @
313 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
314 add r11, r12, r11, lsr #8 @
315 @
316 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
317 add r7, r12, r7, lsr #8 @
318 @
319 add r12, r14, #0x100 @
320 @
321 add r0, r0, r12 @ b = r0 + delta
322 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
323 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
324 @
325 orr r12, r0, r11, asr #1 @ check if clamping is needed...
326 orr r12, r12, r7 @ ...at all
327 movs r12, r12, asr #15 @
328 beq 15f @ no clamp @
329 movs r12, r0, asr #15 @ clamp b
330 mvnne r0, r12, lsr #15 @
331 andne r0, r0, #0x7c00 @ mask b only if clamped
332 movs r12, r11, asr #16 @ clamp r
333 mvnne r11, r12, lsr #16 @
334 movs r12, r7, asr #15 @ clamp g
335 mvnne r7, r12, lsr #15 @
33615: @ no clamp @
337 @
338 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
339 @
340 and r11, r11, #0xf800 @ pack pixel
341 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
342 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
343 orr r3, r11, r0, lsr #10 @ (b >> 10)
344 @ save pixel
345 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
346 add r12, r7, r7, asl #2 @
347 add r12, r12, r12, asl #4 @
348 add r7, r12, r7, asl #6 @
349 @ compute R, G, and B
350 add r0, r8, r7 @ r0 = b' = Y + bu
351 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
352 rsb r7, r10, r7 @ r7 = g' = Y + guv
353 @
354 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
355 add r0, r12, r0, lsr #8 @
356 @
357 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
358 add r11, r12, r11, lsr #8 @
359 @
360 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
361 add r7, r12, r7, lsr #8 @
362 @
363 add r12, r14, #0x200 @
364 @
365 add r0, r0, r12 @ b = r0 + delta
366 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
367 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
368 @
369 orr r12, r0, r11, asr #1 @ check if clamping is needed...
370 orr r12, r12, r7 @ ...at all
371 movs r12, r12, asr #15 @
372 beq 15f @ no clamp @
373 movs r12, r0, asr #15 @ clamp b
374 mvnne r0, r12, lsr #15 @
375 andne r0, r0, #0x7c00 @ mask b only if clamped
376 movs r12, r11, asr #16 @ clamp r
377 mvnne r11, r12, lsr #16 @
378 movs r12, r7, asr #15 @ clamp g
379 mvnne r7, r12, lsr #15 @
38015: @ no clamp @
381 @
382 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
383
384 and r11, r11, #0xf800 @ pack pixel
385 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
386 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
387 orr r0, r11, r0, lsr #10 @ (b >> 10)
388 orr r3, r3, r0, lsl#16 @ pack with 2nd pixel
389 mov r0, #0xC8000000 @
390 orr r0, r0, #0x120000 @ r3 = DBOP_BASE
391
392 str r3, [r0, #0x10] @ write pixel
393 @
394 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
395 add r12, r7, r7, asl #2 @
396 add r12, r12, r12, asl #4 @
397 add r7, r12, r7, asl #6 @
398 @ compute R, G, and B
399 add r0, r8, r7 @ r0 = b' = Y + bu
400 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
401 rsb r7, r10, r7 @ r7 = g' = Y + guv
402 @
403 @ r8 = bu, r9 = rv, r10 = guv
404 @
405 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
406 add r0, r12, r0, lsr #8 @
407 @
408 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
409 add r11, r12, r11, lsr #8 @
410 @
411 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
412 add r7, r12, r7, lsr #8 @
413 @
414 add r12, r14, #0x300 @
415 @
416 add r0, r0, r12 @ b = r0 + delta
417 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
418 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
419 @
420 orr r12, r0, r11, asr #1 @ check if clamping is needed...
421 orr r12, r12, r7 @ ...at all
422 movs r12, r12, asr #15 @
423 beq 15f @ no clamp @
424 movs r12, r0, asr #15 @ clamp b
425 mvnne r0, r12, lsr #15 @
426 andne r0, r0, #0x7c00 @ mask b only if clamped
427 movs r12, r11, asr #16 @ clamp r
428 mvnne r11, r12, lsr #16 @
429 movs r12, r7, asr #15 @ clamp g
430 mvnne r7, r12, lsr #15 @
43115: @ no clamp @
432 @
433 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
434 @
435 and r11, r11, #0xf800 @ pack pixel
436 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
437 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
438 orr r3, r11, r0, lsr #10 @ (b >> 10)
439 @ save pixel
440 @
441 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
442 add r12, r7, r7, asl #2 @
443 add r12, r12, r12, asl #4 @
444 add r7, r12, r7, asl #6 @
445 @ compute R, G, and B
446 add r0, r8, r7 @ r0 = b' = Y + bu
447 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
448 rsb r7, r10, r7 @ r7 = g' = Y + guv
449 @
450 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
451 add r0, r12, r0, lsr #8 @
452 @
453 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
454 add r11, r12, r11, lsr #8 @
455 @
456 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
457 add r7, r12, r7, lsr #8 @
458 @
459 @ This element is zero - use r14 @
460 @
461 add r0, r0, r14 @ b = r0 + delta
462 add r11, r11, r14, lsl #1 @ r = r11 + delta*2
463 add r7, r7, r14, lsr #1 @ g = r7 + delta/2
464 @
465 orr r12, r0, r11, asr #1 @ check if clamping is needed...
466 orr r12, r12, r7 @ ...at all
467 movs r12, r12, asr #15 @
468 beq 15f @ no clamp @
469 movs r12, r0, asr #15 @ clamp b
470 mvnne r0, r12, lsr #15 @
471 andne r0, r0, #0x7c00 @ mask b only if clamped
472 movs r12, r11, asr #16 @ clamp r
473 mvnne r11, r12, lsr #16 @
474 movs r12, r7, asr #15 @ clamp g
475 mvnne r7, r12, lsr #15 @
47615: @ no clamp @
477 @
478 and r11, r11, #0xf800 @ pack pixel
479 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
480 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
481 orr r0, r11, r0, lsr #10 @ (b >> 10)
482 orr r3, r3, r0, lsl#16 @ pack with 2nd pixel
483 mov r0, #0xC8000000 @
484 orr r0, r0, #0x120000 @ r3 = DBOP_BASE
485
486 str r3, [r0, #0x10] @ write pixel
487 @
488 subs r1, r1, #2 @ subtract block from width
489 bgt 10b @ loop line @
490 @
4911: @ busy @
492 @ writing at max 110*32 its (LCD_WIDTH/2), the fifo is bigger
493 @ so polling fifo empty after the loops is save
494 ldr r7, [r0,#0xc] @ r7 = DBOP_STATUS
495 tst r7, #DBOP_BUSY @ fifo not empty?
496 beq 1b @
497
498 ldmfd sp!, { r4-r11, pc } @ restore registers and return
499 .ltorg @ dump constant pool
500 .size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
diff --git a/firmware/target/arm/as3525/sansa-fuzev2/lcd-as-fuzev2.S b/firmware/target/arm/as3525/sansa-fuzev2/lcd-as-fuzev2.S
deleted file mode 100644
index c760eea30a..0000000000
--- a/firmware/target/arm/as3525/sansa-fuzev2/lcd-as-fuzev2.S
+++ /dev/null
@@ -1,530 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Jens Arnold
11 * Heavily based on lcd-as-memframe.c by Michael Sevakis
12 * Adapted for Sansa Fuzev2 by Rafaël Carré
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#include "config.h"
25#include "cpu.h"
26
27#define DBOP_BUSY (1<<10)
28
29/****************************************************************************
30 * void lcd_write_yuv_420_lines(unsigned char const * const src[3],
31 * int width,
32 * int stride);
33 *
34 * |R| |1.000000 -0.000001 1.402000| |Y'|
35 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
36 * |B| |1.000000 1.772000 0.000000| |Pr|
37 * Scaled, normalized, rounded and tweaked to yield RGB 565:
38 * |R| |74 0 101| |Y' - 16| >> 9
39 * |G| = |74 -24 -51| |Cb - 128| >> 8
40 * |B| |74 128 0| |Cr - 128| >> 9
41 *
42 * Write four RGB565 pixels in the following order on each loop:
43 * 1 3 + > down
44 * 2 4 \/ left
45 */
46 .section .icode, "ax", %progbits
47 .align 2
48 .global lcd_write_yuv420_lines
49 .type lcd_write_yuv420_lines, %function
50lcd_write_yuv420_lines:
51 @ r0 = yuv_src
52 @ r1 = width
53 @ r2 = stride
54 stmfd sp!, { r4-r11, lr } @ save non-scratch
55
56 mov r3, #0xC8000000 @
57 orr r3, r3, #0x120000 @ r3 = DBOP_BASE
58
59 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
60 @ r5 = yuv_src[1] = Cb_p
61 @ r6 = yuv_src[2] = Cr_p
62 @ r0 = scratch
63
64 sub r2, r2, #1 @ stride -= 1
65
6610: @ loop line @
67 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
68 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
69 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
70 @
71 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
72 add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
73 add r7, r12, r7, asl #5 @ by one less when adding - same for all
74 @
75 sub r8, r8, #128 @ Cb -= 128
76 sub r9, r9, #128 @ Cr -= 128
77 @
78 add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
79 add r10, r10, r10, asl #4 @
80 add r10, r10, r8, asl #3 @
81 add r10, r10, r8, asl #4 @
82 @
83 add lr, r9, r9, asl #2 @ r9 = Cr*101
84 add lr, lr, r9, asl #5 @
85 add r9, lr, r9, asl #6 @
86 @
87 add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
88 mov r8, r8, asr #2 @
89 add r9, r9, #256 @ r9 = rv = (r9 + 256) >> 9
90 mov r9, r9, asr #9 @
91 rsb r10, r10, #128 @ r10 = guv = (-r10 + 128) >> 8
92 mov r10, r10, asr #8 @
93 @ compute R, G, and B
94 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
95 add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
96 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
97 @
98 orr r12, r0, lr @ check if clamping is needed...
99 orr r12, r12, r7, asr #1 @ ...at all
100 cmp r12, #31 @
101 bls 15f @ no clamp @
102 cmp r0, #31 @ clamp b
103 mvnhi r0, r0, asr #31 @
104 andhi r0, r0, #31 @
105 cmp lr, #31 @ clamp r
106 mvnhi lr, lr, asr #31 @
107 andhi lr, lr, #31 @
108 cmp r7, #63 @ clamp g
109 mvnhi r7, r7, asr #31 @
110 andhi r7, r7, #63 @
11115: @ no clamp @
112 @
113 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
114 @
115 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
116 orr r11, r0, r7, lsl #5 @ r11 = (r << 11) | (g << 5) | b
117 @
118 mov r0, r11, lsr #8 @
119 bic r11, r11, #0xff00 @
120 orr r11, r0, r11, lsl #8 @ swap bytes
121 @
122 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
123 add r12, r7, r7, asl #2 @
124 add r7, r12, r7, asl #5 @
125 @ compute R, G, and B
126 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
127 add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
128 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
129 @
130 orr r12, r0, lr @ check if clamping is needed...
131 orr r12, r12, r7, asr #1 @ ...at all
132 cmp r12, #31 @
133 bls 15f @ no clamp @
134 cmp r0, #31 @ clamp b
135 mvnhi r0, r0, asr #31 @
136 andhi r0, r0, #31 @
137 cmp lr, #31 @ clamp r
138 mvnhi lr, lr, asr #31 @
139 andhi lr, lr, #31 @
140 cmp r7, #63 @ clamp g
141 mvnhi r7, r7, asr #31 @
142 andhi r7, r7, #63 @
14315: @ no clamp @
144 @
145 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
146 @
147 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
148 orr r0, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
149 @
150 mov r7, r0, lsr #8 @
151 bic r7, r7, #0xff00 @
152 orr r0, r7, r0, lsl #8 @ swap bytes
153 @
154 orr r0, r11, r0, lsl#16 @ pack with 2nd pixel
155 str r0, [r3, #0x10] @ write pixel
156 @
157 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
158 add r12, r7, r7, asl #2 @
159 add r7, r12, r7, asl #5 @
160 @ compute R, G, and B
161 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
162 add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
163 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
164 @
165 orr r12, r0, lr @ check if clamping is needed...
166 orr r12, r12, r7, asr #1 @ ...at all
167 cmp r12, #31 @
168 bls 15f @ no clamp @
169 cmp r0, #31 @ clamp b
170 mvnhi r0, r0, asr #31 @
171 andhi r0, r0, #31 @
172 cmp lr, #31 @ clamp r
173 mvnhi lr, lr, asr #31 @
174 andhi lr, lr, #31 @
175 cmp r7, #63 @ clamp g
176 mvnhi r7, r7, asr #31 @
177 andhi r7, r7, #63 @
17815: @ no clamp @
179 @
180 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
181 @
182 @
183 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
184 orr r11, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
185 @
186 mov r0, r11, lsr #8 @
187 bic r11, r11, #0xff00 @
188 orr r11, r0, r11, lsl #8 @ swap bytes
189 @
190 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
191 add r12, r7, r7, asl #2 @
192 add r7, r12, r7, asl #5 @
193 @ compute R, G, and B
194 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
195 add lr, r9, r7, asr #8 @ lr = r = (Y >> 9) + rv
196 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
197 @
198 orr r12, r0, lr @ check if clamping is needed...
199 orr r12, r12, r7, asr #1 @ ...at all
200 cmp r12, #31 @
201 bls 15f @ no clamp @
202 cmp r0, #31 @ clamp b
203 mvnhi r0, r0, asr #31 @
204 andhi r0, r0, #31 @
205 cmp lr, #31 @ clamp r
206 mvnhi lr, lr, asr #31 @
207 andhi lr, lr, #31 @
208 cmp r7, #63 @ clamp g
209 mvnhi r7, r7, asr #31 @
210 andhi r7, r7, #63 @
21115: @ no clamp @
212 @
213 orr r0, r0, lr, lsl #11 @ r0 = (r << 11) | b
214 orr r0, r0, r7, lsl #5 @ r0 = (r << 11) | (g << 5) | b
215 @
216 mov r7, r0, lsr #8 @
217 bic r7, r7, #0xff00 @
218 orr r0, r7, r0, lsl #8 @ swap bytes
219 @
220 orr r0, r11, r0, lsl#16 @ pack with 2nd pixel
221 str r0, [r3, #0x10] @ write pixel
222 @
223 subs r1, r1, #2 @ subtract block from width
224 bgt 10b @ loop line @
225 @
2261: @ busy
227 @ writing at max 110*32 its (LCD_WIDTH/2), the fifo is bigger
228 @ so polling fifo empty after the loops is save
229 ldr r7, [r3,#0xc] @ r7 = DBOP_STATUS
230 tst r7, #DBOP_BUSY @ fifo not empty?
231 beq 1b @
232
233 ldmfd sp!, { r4-r11, pc } @ restore registers and return
234 bx lr @
235 .ltorg @ dump constant pool
236 .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
237
238/****************************************************************************
239 * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
240 * int width,
241 * int stride,
242 * int x_screen,
243 * int y_screen);
244 *
245 * |R| |1.000000 -0.000001 1.402000| |Y'|
246 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
247 * |B| |1.000000 1.772000 0.000000| |Pr|
248 * Red scaled at twice g & b but at same precision to place it in correct
249 * bit position after multiply and leave instruction count lower.
250 * |R| |258 0 408| |Y' - 16|
251 * |G| = |149 -49 -104| |Cb - 128|
252 * |B| |149 258 0| |Cr - 128|
253 *
254 * Write four RGB565 pixels in the following order on each loop:
255 * 1 3 + > down
256 * 2 4 \/ left
257 *
258 * Kernel pattern (raw|rotated|use order):
259 * 5 3 4 2 2 6 3 7 row0 row2 > down
260 * 1 7 0 6 | 4 0 5 1 | 2 4 6 0 3 5 7 1 col0 left
261 * 4 2 5 3 | 3 7 2 6 | 3 5 7 1 2 4 6 0 col2 \/
262 * 0 6 1 7 5 1 4 0
263 */
264 .section .icode, "ax", %progbits
265 .align 2
266 .global lcd_write_yuv420_lines_odither
267 .type lcd_write_yuv420_lines_odither, %function
268lcd_write_yuv420_lines_odither:
269 @ r0 = yuv_src
270 @ r1 = width
271 @ r2 = stride
272 @ r3 = x_screen
273 @ [sp] = y_screen
274 stmfd sp!, { r4-r11, lr } @ save non-scratch
275 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
276 @ r5 = yuv_src[1] = Cb_p
277 @ r6 = yuv_src[2] = Cr_p
278 @
279 ldr r14, [sp, #40] @ Line up pattern and kernel quadrant
280 sub r2, r2, #1 @ stride =- 1
281 eor r14, r14, r3 @
282 and r14, r14, #0x2 @
283 mov r14, r14, lsl #6 @ 0x00 or 0x80
284
285 mov r3, #0xC8000000 @
286 orr r3, r3, #0x120000 @ r3 = DBOP_BASE, need to be redone
287 @ due to lack of registers
28810: @ loop line @
289 @
290 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
291 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
292 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
293 @
294 eor r14, r14, #0x80 @ flip pattern quadrant
295 @
296 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
297 add r12, r7, r7, asl #2 @
298 add r12, r12, r12, asl #4 @
299 add r7, r12, r7, asl #6 @
300 @
301 sub r8, r8, #128 @ Cb -= 128
302 sub r9, r9, #128 @ Cr -= 128
303 @
304 add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
305 add r10, r10, r8, asl #5 @
306 add r10, r10, r9, asl #3 @
307 add r10, r10, r9, asl #5 @
308 add r10, r10, r9, asl #6 @
309 @
310 mov r8, r8, asl #1 @ r8 = bu = Cb*258
311 add r8, r8, r8, asl #7 @
312 @
313 add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
314 add r9, r9, r9, asl #4 @
315 mov r9, r9, asl #3 @
316 @
317 @ compute R, G, and B
318 add r0, r8, r7 @ r0 = b' = Y + bu
319 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
320 rsb r7, r10, r7 @ r7 = g' = Y + guv
321 @
322 @ r8 = bu, r9 = rv, r10 = guv
323 @
324 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
325 add r0, r12, r0, lsr #8 @
326 @
327 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
328 add r11, r12, r11, lsr #8 @
329 @
330 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
331 add r7, r12, r7, lsr #8 @
332 @
333 add r12, r14, #0x100 @
334 @
335 add r0, r0, r12 @ b = r0 + delta
336 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
337 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
338 @
339 orr r12, r0, r11, asr #1 @ check if clamping is needed...
340 orr r12, r12, r7 @ ...at all
341 movs r12, r12, asr #15 @
342 beq 15f @ no clamp @
343 movs r12, r0, asr #15 @ clamp b
344 mvnne r0, r12, lsr #15 @
345 andne r0, r0, #0x7c00 @ mask b only if clamped
346 movs r12, r11, asr #16 @ clamp r
347 mvnne r11, r12, lsr #16 @
348 movs r12, r7, asr #15 @ clamp g
349 mvnne r7, r12, lsr #15 @
35015: @ no clamp @
351 @
352 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
353 @
354 and r11, r11, #0xf800 @ pack pixel
355 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
356 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
357 orr r3, r11, r0, lsr #10 @ (b >> 10)
358 @
359 mov r7, r3, lsr #8 @
360 bic r3, r3, #0xff00 @
361 orr r3, r7, r3, lsl #8 @ swap pixel
362 @ save pixel
363 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
364 add r12, r7, r7, asl #2 @
365 add r12, r12, r12, asl #4 @
366 add r7, r12, r7, asl #6 @
367 @ compute R, G, and B
368 add r0, r8, r7 @ r0 = b' = Y + bu
369 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
370 rsb r7, r10, r7 @ r7 = g' = Y + guv
371 @
372 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
373 add r0, r12, r0, lsr #8 @
374 @
375 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
376 add r11, r12, r11, lsr #8 @
377 @
378 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
379 add r7, r12, r7, lsr #8 @
380 @
381 add r12, r14, #0x200 @
382 @
383 add r0, r0, r12 @ b = r0 + delta
384 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
385 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
386 @
387 orr r12, r0, r11, asr #1 @ check if clamping is needed...
388 orr r12, r12, r7 @ ...at all
389 movs r12, r12, asr #15 @
390 beq 15f @ no clamp @
391 movs r12, r0, asr #15 @ clamp b
392 mvnne r0, r12, lsr #15 @
393 andne r0, r0, #0x7c00 @ mask b only if clamped
394 movs r12, r11, asr #16 @ clamp r
395 mvnne r11, r12, lsr #16 @
396 movs r12, r7, asr #15 @ clamp g
397 mvnne r7, r12, lsr #15 @
39815: @ no clamp @
399 @
400 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
401
402 and r11, r11, #0xf800 @ pack pixel
403 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
404 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
405 orr r0, r11, r0, lsr #10 @ (b >> 10)
406 @
407 mov r7, r0, lsr #8 @
408 bic r0, r0, #0xff00 @
409 orr r0, r7, r0, lsl #8 @ swap pixel
410 orr r3, r3, r0, lsl#16 @ pack with 2nd pixel
411 mov r0, #0xC8000000 @
412 orr r0, r0, #0x120000 @ r3 = DBOP_BASE
413
414 str r3, [r0, #0x10] @ write pixel
415 @
416 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
417 add r12, r7, r7, asl #2 @
418 add r12, r12, r12, asl #4 @
419 add r7, r12, r7, asl #6 @
420 @ compute R, G, and B
421 add r0, r8, r7 @ r0 = b' = Y + bu
422 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
423 rsb r7, r10, r7 @ r7 = g' = Y + guv
424 @
425 @ r8 = bu, r9 = rv, r10 = guv
426 @
427 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
428 add r0, r12, r0, lsr #8 @
429 @
430 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
431 add r11, r12, r11, lsr #8 @
432 @
433 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
434 add r7, r12, r7, lsr #8 @
435 @
436 add r12, r14, #0x300 @
437 @
438 add r0, r0, r12 @ b = r0 + delta
439 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
440 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
441 @
442 orr r12, r0, r11, asr #1 @ check if clamping is needed...
443 orr r12, r12, r7 @ ...at all
444 movs r12, r12, asr #15 @
445 beq 15f @ no clamp @
446 movs r12, r0, asr #15 @ clamp b
447 mvnne r0, r12, lsr #15 @
448 andne r0, r0, #0x7c00 @ mask b only if clamped
449 movs r12, r11, asr #16 @ clamp r
450 mvnne r11, r12, lsr #16 @
451 movs r12, r7, asr #15 @ clamp g
452 mvnne r7, r12, lsr #15 @
45315: @ no clamp @
454 @
455 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
456 @
457 and r11, r11, #0xf800 @ pack pixel
458 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
459 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
460 orr r3, r11, r0, lsr #10 @ (b >> 10)
461 @
462 mov r7, r3, lsr #8 @
463 bic r3, r3, #0xff00 @
464 orr r3, r7, r3, lsl #8 @ swap pixel
465 @ save pixel
466 @
467 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
468 add r12, r7, r7, asl #2 @
469 add r12, r12, r12, asl #4 @
470 add r7, r12, r7, asl #6 @
471 @ compute R, G, and B
472 add r0, r8, r7 @ r0 = b' = Y + bu
473 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
474 rsb r7, r10, r7 @ r7 = g' = Y + guv
475 @
476 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
477 add r0, r12, r0, lsr #8 @
478 @
479 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
480 add r11, r12, r11, lsr #8 @
481 @
482 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
483 add r7, r12, r7, lsr #8 @
484 @
485 @ This element is zero - use r14 @
486 @
487 add r0, r0, r14 @ b = r0 + delta
488 add r11, r11, r14, lsl #1 @ r = r11 + delta*2
489 add r7, r7, r14, lsr #1 @ g = r7 + delta/2
490 @
491 orr r12, r0, r11, asr #1 @ check if clamping is needed...
492 orr r12, r12, r7 @ ...at all
493 movs r12, r12, asr #15 @
494 beq 15f @ no clamp @
495 movs r12, r0, asr #15 @ clamp b
496 mvnne r0, r12, lsr #15 @
497 andne r0, r0, #0x7c00 @ mask b only if clamped
498 movs r12, r11, asr #16 @ clamp r
499 mvnne r11, r12, lsr #16 @
500 movs r12, r7, asr #15 @ clamp g
501 mvnne r7, r12, lsr #15 @
50215: @ no clamp @
503 @
504 and r11, r11, #0xf800 @ pack pixel
505 and r7, r7, #0x7e00 @ r0 = pixel = (r & 0xf800) |
506 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
507 orr r0, r11, r0, lsr #10 @ (b >> 10)
508 @
509 mov r7, r0, lsr #8 @
510 bic r0, r0, #0xff00 @
511 orr r0, r7, r0, lsl #8 @ swap pixel
512 orr r3, r3, r0, lsl#16 @ pack with 2nd pixel
513 mov r0, #0xC8000000 @
514 orr r0, r0, #0x120000 @ r3 = DBOP_BASE
515
516 str r3, [r0, #0x10] @ write pixel
517 @
518 subs r1, r1, #2 @ subtract block from width
519 bgt 10b @ loop line @
520 @
5211: @ busy @
522 @ writing at max 110*32 its (LCD_WIDTH/2), the fifo is bigger
523 @ so polling fifo empty after the loops is save
524 ldr r7, [r0,#0xc] @ r7 = DBOP_STATUS
525 tst r7, #DBOP_BUSY @ fifo not empty?
526 beq 1b @
527
528 ldmfd sp!, { r4-r11, pc } @ restore registers and return
529 .ltorg @ dump constant pool
530 .size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
diff --git a/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c b/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c
index 5fa26c0eaf..d17149ee95 100644
--- a/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c
+++ b/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c
@@ -29,6 +29,7 @@
29#include "debug.h" 29#include "debug.h"
30#include "system.h" 30#include "system.h"
31#include "clock-target.h" 31#include "clock-target.h"
32#include "dbop-as3525.h"
32 33
33/* The controller is unknown, but some registers appear to be the same as the 34/* The controller is unknown, but some registers appear to be the same as the
34 HD66789R */ 35 HD66789R */
@@ -113,67 +114,13 @@ static void as3525_dbop_init(void)
113 DBOP_TIMPOL_23 = 0xA12FE037; 114 DBOP_TIMPOL_23 = 0xA12FE037;
114} 115}
115 116
116static inline void dbop_set_mode(int mode)
117{
118 unsigned long ctrl = DBOP_CTRL;
119 int words = (ctrl >> 13) & 3; // bits 14:13
120 if (mode == 32 && words != 2)
121 DBOP_CTRL = (ctrl & ~(1<<13)) | (1<<14); // 4 serial words
122 else if (mode == 16 && words != 1)
123 DBOP_CTRL = (ctrl & ~(1<<14)) | (1<<13); // 2 serial words
124 else
125 return;
126 lcd_delay(10);
127}
128
129static void dbop_write_data(const int16_t* p_bytes, int count)
130{
131 const int32_t *data;
132 if ((intptr_t)p_bytes & 0x3 || count == 1)
133 { /* need to do a single 16bit write beforehand if the address is
134 * not word aligned or count is 1, switch to 16bit mode if needed */
135 dbop_set_mode(16);
136 DBOP_DOUT16 = *p_bytes++;
137 if (!(--count))
138 return;
139 }
140 /* from here, 32bit transfers are save
141 * set it to transfer 4*(outputwidth) units at a time,
142 * if bit 12 is set it only does 2 halfwords though (we never set it)
143 * switch to 32bit output if needed */
144 dbop_set_mode(32);
145 data = (int32_t*)p_bytes;
146
147 while (count > 1)
148 {
149 DBOP_DOUT32 = *data++;
150 count -= 2;
151
152 /* Wait if push fifo is full */
153 while ((DBOP_STAT & (1<<6)) != 0);
154 }
155 /* While push fifo is not empty */
156 while ((DBOP_STAT & (1<<10)) == 0);
157
158 /* due to the 32bit alignment requirement or uneven count,
159 * we possibly need to do a 16bit transfer at the end also */
160 if (count > 0)
161 dbop_write_data((int16_t*)data, 1);
162}
163 117
164static void lcd_write_cmd(unsigned short cmd) 118static void lcd_write_cmd(unsigned short cmd)
165{ 119{
166 volatile int i; 120 unsigned short data = swap16(cmd);
167 lcd_delay(0x20);
168
169 DBOP_CTRL |= 1<<13;
170 DBOP_CTRL &= ~(1<<14); // 2 serial words
171 DBOP_CTRL &= ~(1<<12); // 8 bit data width
172 DBOP_TIMPOL_23 = 0xA12F0036; 121 DBOP_TIMPOL_23 = 0xA12F0036;
173 DBOP_DOUT = swap16(cmd); 122 dbop_write_data(&data, 1);
174 123 lcd_delay(32);
175 while ((DBOP_STAT & (1<<10)) == 0);
176 for(i=0;i<0x20;i++) asm volatile ("nop\n");
177 DBOP_TIMPOL_23 = 0xA12FE037; 124 DBOP_TIMPOL_23 = 0xA12FE037;
178} 125}
179 126
@@ -403,8 +350,6 @@ void lcd_blit_yuv(unsigned char * const src[3],
403 lcd_window_y(y, y + 1); 350 lcd_window_y(y, y + 1);
404 351
405 lcd_write_cmd(R_WRITE_DATA_2_GRAM); 352 lcd_write_cmd(R_WRITE_DATA_2_GRAM);
406
407 dbop_set_mode(32);
408 lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y); 353 lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y);
409 yuv_src[0] += stride << 1; /* Skip down two luma lines */ 354 yuv_src[0] += stride << 1; /* Skip down two luma lines */
410 yuv_src[1] += stride >> 1; /* Skip down one chroma line */ 355 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
@@ -420,8 +365,6 @@ void lcd_blit_yuv(unsigned char * const src[3],
420 lcd_window_y(y, y + 1); 365 lcd_window_y(y, y + 1);
421 366
422 lcd_write_cmd(R_WRITE_DATA_2_GRAM); 367 lcd_write_cmd(R_WRITE_DATA_2_GRAM);
423
424 dbop_set_mode(32);
425 lcd_write_yuv420_lines(yuv_src, width, stride); 368 lcd_write_yuv420_lines(yuv_src, width, stride);
426 yuv_src[0] += stride << 1; /* Skip down two luma lines */ 369 yuv_src[0] += stride << 1; /* Skip down two luma lines */
427 yuv_src[1] += stride >> 1; /* Skip down one chroma line */ 370 yuv_src[1] += stride >> 1; /* Skip down one chroma line */