HDD6330: speedup lcd_blit_yuv() function (~4%).
[kugel-rb.git] / firmware / target / arm / philips / hdd6330 / lcd-as-hdd6330.S
blobc3a7992a2ec96ff721678b8b54be80badd29624b
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id:$
9  *
10  * Copyright (C) 2010 by Szymon Dziok
11  *
12  * Philips Gogear HDD6330 LCD assembly routine
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  ****************************************************************************/
24 #include "config.h"
25 #include "cpu.h"
27 /****************************************************************************
28    void lcd_yuv_write_inner_loop(unsigned char const * const ysrc,
29                                  unsigned char const * const usrc,
30                                  unsigned char const * const vsrc,
31                                  int width);
33     .section    .icode, "ax", %progbits
34     .align      2
35     .global     lcd_yuv_write_inner_loop
36     .type       lcd_yuv_write_inner_loop, %function
37 lcd_yuv_write_inner_loop:
38                                         @ r0 = ysrc
39                                         @ r1 = usrc
40                                         @ r2 = vsrc
41                                         @ r3 = width
42     stmfd sp!, { r4-r11, lr }           @ save regs
43     mov r4, #0x70000000                 @ r4 = LCD2_BLOCK_CTRL - 0x20
44     add r4, r4, #0x8a00                 @
45     add r5, r4, #0x100                  @ r5 = LCD2_BLOCK_DATA
46 10:                                     @ loop
48     ldrb r7, [r1], #1                   @ *usrc++
49     ldrb r8, [r2], #1                   @ *vsrc++
51     sub r7, r7, #128                    @ Cb -= 128
52     sub r8, r8, #128                    @ Cr -= 128
54     add r10, r8, r8, asl #2             @ Cr*101
55     add r10, r10, r8, asl #5
56     add r10, r10, r8, asl #6
58     add r11, r8, r8, asl #1             @ Cr*51 + Cb*24
59     add r11, r11, r11, asl #4
60     add r11, r11, r7, asl #3
61     add r11, r11, r7, asl #4
63     add r12, r7, #2                     @ r12 = bu = (Cb*128 + 256) >> 9
64     mov r12, r12, asr #2
65     add r10, r10, #256                  @ r10 = rv = (Cr*101 + 256) >> 9
66     mov r10, r10, asr #9
67     rsb r11, r11, #128                  @ r11 = guv = (-r11 + 128) >> 8
68     mov r11, r11, asr #8
70 @ pixel_1
71     ldrb r7, [r0], #1                   @ *ysrc++
72     sub r7, r7, #16                     @ Y = (Y' - 16) * 37
73     add r8, r7, r7, asl #2
74     add r7, r8, r7, asl #5
76     add r9, r10, r7, asr #8             @ R = (Y >> 8) + rv
77     add r8, r11, r7, asr #7             @ G = (Y >> 7) + guv
78     add r7, r12, r7, asr #8             @ B = (Y >> 8) + bu
80     cmp r9, #31                         @ clamp R
81     mvnhi r9, r9, asr #31
82     andhi r9, r9, #31
84     cmp r8, #63                         @ clamp G
85     mvnhi r8, r8, asr #31
86     andhi r8, r8, #63
88     cmp r7, #31                         @ clamp B
89     mvnhi r7, r7, asr #31
90     andhi r7, r7, #31
92     orr r6, r7, r8, lsl #5              @ pack pixel
93     orr r6, r6, r9, lsl #11
95     mov r7, r6, lsl #8                  @ swap bytes
96     and r7, r7, #0xff00
97     add r6, r7, r6, lsr #8
99 @ pixel_2
100     ldrb r7, [r0], #1                   @ *ysrc++
101     sub r7, r7, #16                     @ Y = (Y' - 16) * 37
102     add r8, r7, r7, asl #2
103     add r7, r8, r7, asl #5
105     add r9, r10, r7, asr #8             @ R = (Y >> 8) + rv
106     add r8, r11, r7, asr #7             @ G = (Y >> 7) + guv
107     add r7, r12, r7, asr #8             @ B = (Y >> 8) + bu
109     cmp r9, #31                         @ clamp R
110     mvnhi r9, r9, asr #31
111     andhi r9, r9, #31
113     cmp r8, #63                         @ clamp G
114     mvnhi r8, r8, asr #31
115     andhi r8, r8, #63
117     cmp r7, #31                         @ clamp B
118     mvnhi r7, r7, asr #31
119     andhi r7, r7, #31
121     orr r7, r7, r8, lsl #5              @ pack pixel
122     orr r7, r7, r9, lsl #11
124     orr r6, r6, r7, lsl #24             @ swap bytes and add pixels simultaneously
125     mov r7, r7, lsr #8
126     orr r6, r6, r7, lsl #16
128 11:                                     @ while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK));
129     ldr r11, [r4, #0x20]                @
130     tst r11, #0x1000000                 @
131     beq 11b                             @
133     str r6, [r5]                        @ send two pixels
135     subs r3, r3, #2                     @ decrease width
136     bgt 10b                             @ loop
138     ldmpc regs=r4-r11                   @ restore regs
139     .ltorg                              @ dump constant pool
140     .size   lcd_yuv_write_inner_loop, .-lcd_yuv_write_inner_loop