summaryrefslogtreecommitdiff
path: root/firmware/target/arm/samsung/yh820/lcd-as-yh820.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/samsung/yh820/lcd-as-yh820.S')
-rw-r--r--firmware/target/arm/samsung/yh820/lcd-as-yh820.S551
1 files changed, 551 insertions, 0 deletions
diff --git a/firmware/target/arm/samsung/yh820/lcd-as-yh820.S b/firmware/target/arm/samsung/yh820/lcd-as-yh820.S
new file mode 100644
index 0000000000..e466624d04
--- /dev/null
+++ b/firmware/target/arm/samsung/yh820/lcd-as-yh820.S
@@ -0,0 +1,551 @@
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 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#include "config.h"
24#include "cpu.h"
25
26/****************************************************************************
27 * void lcd_write_yuv_420_lines(unsigned char const * const src[3],
28 * int width,
29 * int stride);
30 *
31 * |R| |1.000000 -0.000001 1.402000| |Y'|
32 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
33 * |B| |1.000000 1.772000 0.000000| |Pr|
34 * Scaled, normalized, rounded and tweaked to yield RGB 565:
35 * |R| |74 0 101| |Y' - 16| >> 9
36 * |G| = |74 -24 -51| |Cb - 128| >> 8
37 * |B| |74 128 0| |Cr - 128| >> 9
38 *
39 * Write four RGB565 pixels in the following order on each loop:
40 * 1 3 + > down
41 * 2 4 \/ left
42 */
43 .section .icode, "ax", %progbits
44 .align 2
45 .global lcd_write_yuv420_lines
46 .type lcd_write_yuv420_lines, %function
47lcd_write_yuv420_lines:
48 @ r0 = yuv_src
49 @ r1 = width
50 @ r2 = stride
51 stmfd sp!, { r4-r12 } @ save non-scratch
52 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
53 @ r5 = yuv_src[1] = Cb_p
54 @ r6 = yuv_src[2] = Cr_p
55 @ r0 = scratch
56 sub r2, r2, #1 @
57 mov r3, #0x70000000 @
58 orr r3, r3, #0x3000 @ r3 = LCD1_BASE
5910: @ loop line @
60 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
61 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
62 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
63 @
64 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
65 add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
66 add r7, r12, r7, asl #5 @ by one less when adding - same for all
67 @
68 sub r8, r8, #128 @ Cb -= 128
69 sub r9, r9, #128 @ Cr -= 128
70 @
71 add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
72 add r10, r10, r10, asl #4 @
73 add r10, r10, r8, asl #3 @
74 add r10, r10, r8, asl #4 @
75 @
76 add r11, r9, r9, asl #2 @ r9 = Cr*101
77 add r11, r11, r9, asl #5 @
78 add r9, r11, r9, asl #6 @
79 @
80 add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
81 mov r8, r8, asr #2 @
82 add r9, r9, #256 @ r9 = rv = (r9 + 256) >> 9
83 mov r9, r9, asr #9 @
84 rsb r10, r10, #128 @ r10 = guv = (-r10 + 128) >> 8
85 mov r10, r10, asr #8 @
86 @ compute R, G, and B
87 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
88 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
89 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
90 @
91 orr r12, r0, r11 @ check if clamping is needed...
92 orr r12, r12, r7, asr #1 @ ...at all
93 cmp r12, #31 @
94 bls 15f @ no clamp @
95 cmp r0, #31 @ clamp b
96 mvnhi r0, r0, asr #31 @
97 andhi r0, r0, #31 @
98 cmp r11, #31 @ clamp r
99 mvnhi r11, r11, asr #31 @
100 andhi r11, r11, #31 @
101 cmp r7, #63 @ clamp g
102 mvnhi r7, r7, asr #31 @
103 andhi r7, r7, #63 @
10415: @ no clamp @
105 @
106 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
107 @
108 mov r11, r11, lsl #3 @
109 orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
110 orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
1111: @ busy @
112 ldr r7, [r3] @ r7 = LCD1_BASE
113 tst r7, #LCD1_BUSY_MASK @ bridge busy?
114 bne 1b @
115 str r11, [r3, #0x10] @ send MSB
1161: @busy @
117 ldr r7, [r3] @ r7 = LCD1_BASE
118 tst r7, #LCD1_BUSY_MASK @ bridge busy?
119 bne 1b @
120 str r0, [r3, #0x10] @ send LSB
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 r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
128 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
129 @
130 orr r12, r0, r11 @ 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 r11, #31 @ clamp r
138 mvnhi r11, r11, asr #31 @
139 andhi r11, r11, #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 mov r11, r11, lsl #3 @
148 orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
149 orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
1501: @ busy @
151 ldr r7, [r3] @ r7 = LCD1_BASE
152 tst r7, #LCD1_BUSY_MASK @ bridge busy?
153 bne 1b @
154 str r11, [r3, #0x10] @ send MSB
1551: @ busy @
156 ldr r7, [r3] @ r7 = LCD1_BASE
157 tst r7, #LCD1_BUSY_MASK @ bridge busy?
158 bne 1b @
159 str r0, [r3, #0x10] @ send LSB
160 @
161 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
162 add r12, r7, r7, asl #2 @
163 add r7, r12, r7, asl #5 @
164 @ compute R, G, and B
165 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
166 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
167 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
168 @
169 orr r12, r0, r11 @ check if clamping is needed...
170 orr r12, r12, r7, asr #1 @ ...at all
171 cmp r12, #31 @
172 bls 15f @ no clamp @
173 cmp r0, #31 @ clamp b
174 mvnhi r0, r0, asr #31 @
175 andhi r0, r0, #31 @
176 cmp r11, #31 @ clamp r
177 mvnhi r11, r11, asr #31 @
178 andhi r11, r11, #31 @
179 cmp r7, #63 @ clamp g
180 mvnhi r7, r7, asr #31 @
181 andhi r7, r7, #63 @
18215: @ no clamp @
183 @
184 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
185 @
186 @
187 mov r11, r11, lsl #3 @
188 orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
189 orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
1901: @ busy @
191 ldr r7, [r3] @ r7 = LCD1_BASE
192 tst r7, #LCD1_BUSY_MASK @ bridge busy?
193 bne 1b @
194 str r11, [r3, #0x10] @ send MSB
1951: @ busy @
196 ldr r7, [r3] @ r7 = LCD1_BASE
197 tst r7, #LCD1_BUSY_MASK @ bridge busy?
198 bne 1b @
199 str r0, [r3, #0x10] @ send LSB
200 @
201 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
202 add r12, r7, r7, asl #2 @
203 add r7, r12, r7, asl #5 @
204 @ compute R, G, and B
205 add r0, r8, r7, asr #8 @ r0 = b = (Y >> 9) + bu
206 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
207 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
208 @
209 orr r12, r0, r11 @ check if clamping is needed...
210 orr r12, r12, r7, asr #1 @ ...at all
211 cmp r12, #31 @
212 bls 15f @ no clamp @
213 cmp r0, #31 @ clamp b
214 mvnhi r0, r0, asr #31 @
215 andhi r0, r0, #31 @
216 cmp r11, #31 @ clamp r
217 mvnhi r11, r11, asr #31 @
218 andhi r11, r11, #31 @
219 cmp r7, #63 @ clamp g
220 mvnhi r7, r7, asr #31 @
221 andhi r7, r7, #63 @
22215: @ no clamp @
223 @
224 mov r11, r11, lsl #3 @
225 orr r11, r11, r7, lsr #3 @ r11 = (r << 3) | (g >> 3)
226 orr r0, r0, r7, lsl #5 @ r0 = (g << 5) | b
2271: @ busy @
228 ldr r7, [r3] @ r7 = LCD1_BASE
229 tst r7, #LCD1_BUSY_MASK @ bridge busy?
230 bne 1b @
231 str r11, [r3, #0x10] @ send MSB
2321: @ busy @
233 ldr r7, [r3] @ r7 = LCD1_BASE
234 tst r7, #LCD1_BUSY_MASK @ bridge busy?
235 bne 1b @
236 str r0, [r3, #0x10] @ send LSB
237 @
238 subs r1, r1, #2 @ subtract block from width
239 bgt 10b @ loop line @
240 @
241 ldmfd sp!, { r4-r12 } @ restore registers and return
242 bx lr @
243 .ltorg @ dump constant pool
244 .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
245
246/****************************************************************************
247 * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
248 * int width,
249 * int stride,
250 * int x_screen,
251 * int y_screen);
252 *
253 * |R| |1.000000 -0.000001 1.402000| |Y'|
254 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
255 * |B| |1.000000 1.772000 0.000000| |Pr|
256 * Red scaled at twice g & b but at same precision to place it in correct
257 * bit position after multiply and leave instruction count lower.
258 * |R| |258 0 408| |Y' - 16|
259 * |G| = |149 -49 -104| |Cb - 128|
260 * |B| |149 258 0| |Cr - 128|
261 *
262 * Write four RGB565 pixels in the following order on each loop:
263 * 1 3 + > down
264 * 2 4 \/ left
265 *
266 * Kernel pattern (raw|rotated|use order):
267 * 5 3 4 2 2 6 3 7 row0 row2 > down
268 * 1 7 0 6 | 4 0 5 1 | 2 4 6 0 3 5 7 1 col0 left
269 * 4 2 5 3 | 3 7 2 6 | 3 5 7 1 2 4 6 0 col2 \/
270 * 0 6 1 7 5 1 4 0
271 */
272 .section .icode, "ax", %progbits
273 .align 2
274 .global lcd_write_yuv420_lines_odither
275 .type lcd_write_yuv420_lines_odither, %function
276lcd_write_yuv420_lines_odither:
277 @ r0 = yuv_src
278 @ r1 = width
279 @ r2 = stride
280 @ r3 = x_screen
281 @ [sp] = y_screen
282 stmfd sp!, { r4-r12, lr } @ save non-scratch
283 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
284 @ r5 = yuv_src[1] = Cb_p
285 @ r6 = yuv_src[2] = Cr_p
286 @
287 sub r2, r2, #1 @
288 ldr r14, [sp, #40] @ Line up pattern and kernel quadrant
289 eor r14, r14, r3 @
290 and r14, r14, #0x2 @
291 mov r14, r14, lsl #6 @ 0x00 or 0x80
292 mov r3, #0x70000000 @
293 orr r3, r3, #0x3000 @ r3 = LCD1_BASE
29410: @ loop line @
295 @
296 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
297 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
298 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
299 @
300 eor r14, r14, #0x80 @ flip pattern quadrant
301 @
302 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
303 add r12, r7, r7, asl #2 @
304 add r12, r12, r12, asl #4 @
305 add r7, r12, r7, asl #6 @
306 @
307 sub r8, r8, #128 @ Cb -= 128
308 sub r9, r9, #128 @ Cr -= 128
309 @
310 add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
311 add r10, r10, r8, asl #5 @
312 add r10, r10, r9, asl #3 @
313 add r10, r10, r9, asl #5 @
314 add r10, r10, r9, asl #6 @
315 @
316 mov r8, r8, asl #1 @ r8 = bu = Cb*258
317 add r8, r8, r8, asl #7 @
318 @
319 add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
320 add r9, r9, r9, asl #4 @
321 mov r9, r9, asl #3 @
322 @
323 @ compute R, G, and B
324 add r0, r8, r7 @ r0 = b' = Y + bu
325 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
326 rsb r7, r10, r7 @ r7 = g' = Y + guv
327 @
328 @ r8 = bu, r9 = rv, r10 = guv
329 @
330 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
331 add r0, r12, r0, lsr #8 @
332 @
333 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
334 add r11, r12, r11, lsr #8 @
335 @
336 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
337 add r7, r12, r7, lsr #8 @
338 @
339 add r12, r14, #0x100 @
340 @
341 add r0, r0, r12 @ b = r0 + delta
342 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
343 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
344 @
345 orr r12, r0, r11, asr #1 @ check if clamping is needed...
346 orr r12, r12, r7 @ ...at all
347 movs r12, r12, asr #15 @
348 beq 15f @ no clamp @
349 movs r12, r0, asr #15 @ clamp b
350 mvnne r0, r12, lsr #15 @
351 andne r0, r0, #0x7c00 @ mask b only if clamped
352 movs r12, r11, asr #16 @ clamp r
353 mvnne r11, r12, lsr #16 @
354 movs r12, r7, asr #15 @ clamp g
355 mvnne r7, r12, lsr #15 @
35615: @ no clamp @
357 @
358 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
359 @
360
361 and r11, r11, #0xf800 @ pack pixel
362 mov r11, r11, lsr #8
363 and r7, r7, #0x7e00
364 orr r11, r11, r7, lsr #12
365 mov r7, r7, lsr#4
366 orr r0, r7, r0, lsr #10
3671: @ busy @
368 ldr r7, [r3] @ r7 = LCD1_BASE
369 tst r7, #LCD1_BUSY_MASK @ bridge busy?
370 bne 1b @
371 str r11, [r3, #0x10] @ send MSB
3721: @ busy @
373 ldr r7, [r3] @ r7 = LCD1_BASE
374 tst r7, #LCD1_BUSY_MASK @ bridge busy?
375 bne 1b @
376 str r0, [r3, #0x10] @ send LSB
377 @
378 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
379 add r12, r7, r7, asl #2 @
380 add r12, r12, r12, asl #4 @
381 add r7, r12, r7, asl #6 @
382 @ compute R, G, and B
383 add r0, r8, r7 @ r0 = b' = Y + bu
384 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
385 rsb r7, r10, r7 @ r7 = g' = Y + guv
386 @
387 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
388 add r0, r12, r0, lsr #8 @
389 @
390 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
391 add r11, r12, r11, lsr #8 @
392 @
393 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
394 add r7, r12, r7, lsr #8 @
395 @
396 add r12, r14, #0x200 @
397 @
398 add r0, r0, r12 @ b = r0 + delta
399 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
400 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
401 @
402 orr r12, r0, r11, asr #1 @ check if clamping is needed...
403 orr r12, r12, r7 @ ...at all
404 movs r12, r12, asr #15 @
405 beq 15f @ no clamp @
406 movs r12, r0, asr #15 @ clamp b
407 mvnne r0, r12, lsr #15 @
408 andne r0, r0, #0x7c00 @ mask b only if clamped
409 movs r12, r11, asr #16 @ clamp r
410 mvnne r11, r12, lsr #16 @
411 movs r12, r7, asr #15 @ clamp g
412 mvnne r7, r12, lsr #15 @
41315: @ no clamp @
414 @
415 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
416
417 and r11, r11, #0xf800 @ pack pixel
418 mov r11, r11, lsr #8
419 and r7, r7, #0x7e00
420 orr r11, r11, r7, lsr #12
421 mov r7, r7, lsr#4
422 orr r0, r7, r0, lsr #10
4231: @ busy @
424 ldr r7, [r3] @ r7 = LCD1_BASE
425 tst r7, #LCD1_BUSY_MASK @ bridge busy?
426 bne 1b @
427 str r11, [r3, #0x10] @ send MSB
4281: @ busy @
429 ldr r7, [r3] @ r7 = LCD1_BASE
430 tst r7, #LCD1_BUSY_MASK @ bridge busy?
431 bne 1b @
432 str r0, [r3, #0x10] @ send LSB
433
434 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
435 add r12, r7, r7, asl #2 @
436 add r12, r12, r12, asl #4 @
437 add r7, r12, r7, asl #6 @
438 @ compute R, G, and B
439 add r0, r8, r7 @ r0 = b' = Y + bu
440 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
441 rsb r7, r10, r7 @ r7 = g' = Y + guv
442 @
443 @ r8 = bu, r9 = rv, r10 = guv
444 @
445 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b' + b'/256
446 add r0, r12, r0, lsr #8 @
447 @
448 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
449 add r11, r12, r11, lsr #8 @
450 @
451 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
452 add r7, r12, r7, lsr #8 @
453 @
454 add r12, r14, #0x300 @
455 @
456 add r0, r0, r12 @ b = r0 + delta
457 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
458 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
459 @
460 orr r12, r0, r11, asr #1 @ check if clamping is needed...
461 orr r12, r12, r7 @ ...at all
462 movs r12, r12, asr #15 @
463 beq 15f @ no clamp @
464 movs r12, r0, asr #15 @ clamp b
465 mvnne r0, r12, lsr #15 @
466 andne r0, r0, #0x7c00 @ mask b only if clamped
467 movs r12, r11, asr #16 @ clamp r
468 mvnne r11, r12, lsr #16 @
469 movs r12, r7, asr #15 @ clamp g
470 mvnne r7, r12, lsr #15 @
47115: @ no clamp @
472 @
473 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
474
475 and r11, r11, #0xf800 @ pack pixel
476 mov r11, r11, lsr #8
477 and r7, r7, #0x7e00
478 orr r11, r11, r7, lsr #12
479 mov r7, r7, lsr#4
480 orr r0, r7, r0, lsr #10
4811: @ busy @
482 ldr r7, [r3] @ r7 = LCD1_BASE
483 tst r7, #LCD1_BUSY_MASK @ bridge busy?
484 bne 1b @
485 str r11, [r3, #0x10] @ send MSB
4861: @ busy @
487 ldr r7, [r3] @ r7 = LCD1_BASE
488 tst r7, #LCD1_BUSY_MASK @ bridge busy?
489 bne 1b @
490 str r0, [r3, #0x10] @ send LSB
491
492 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
493 add r12, r7, r7, asl #2 @
494 add r12, r12, r12, asl #4 @
495 add r7, r12, r7, asl #6 @
496 @ compute R, G, and B
497 add r0, r8, r7 @ r0 = b' = Y + bu
498 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
499 rsb r7, r10, r7 @ r7 = g' = Y + guv
500 @
501 sub r12, r0, r0, lsr #5 @ r0 = 31/32*b + b/256
502 add r0, r12, r0, lsr #8 @
503 @
504 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
505 add r11, r12, r11, lsr #8 @
506 @
507 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
508 add r7, r12, r7, lsr #8 @
509 @
510 @ This element is zero - use r14 @
511 @
512 add r0, r0, r14 @ b = r0 + delta
513 add r11, r11, r14, lsl #1 @ r = r11 + delta*2
514 add r7, r7, r14, lsr #1 @ g = r7 + delta/2
515 @
516 orr r12, r0, r11, asr #1 @ check if clamping is needed...
517 orr r12, r12, r7 @ ...at all
518 movs r12, r12, asr #15 @
519 beq 15f @ no clamp @
520 movs r12, r0, asr #15 @ clamp b
521 mvnne r0, r12, lsr #15 @
522 andne r0, r0, #0x7c00 @ mask b only if clamped
523 movs r12, r11, asr #16 @ clamp r
524 mvnne r11, r12, lsr #16 @
525 movs r12, r7, asr #15 @ clamp g
526 mvnne r7, r12, lsr #15 @
52715: @ no clamp @
528
529 and r11, r11, #0xf800 @ pack pixel
530 mov r11, r11, lsr #8
531 and r7, r7, #0x7e00
532 orr r11, r11, r7, lsr #12
533 mov r7, r7, lsr#4
534 orr r0, r7, r0, lsr #10
5351: @ busy @
536 ldr r7, [r3] @ r7 = LCD1_BASE
537 tst r7, #LCD1_BUSY_MASK @ bridge busy?
538 bne 1b @
539 str r11, [r3, #0x10] @ send MSB
5401: @ busy @
541 ldr r7, [r3] @ r7 = LCD1_BASE
542 tst r7, #LCD1_BUSY_MASK @ bridge busy?
543 bne 1b @
544 str r0, [r3, #0x10] @ send LSB
545
546 subs r1, r1, #2 @ subtract block from width
547 bgt 10b @ loop line @
548 @
549 ldmfd sp!, { r4-r12, pc } @ restore registers and return
550 .ltorg @ dump constant pool
551 .size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither