Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
| 8 | * $Id$ |
| 9 | * |
| 10 | * Copyright (C) 2007 by Andree Buschmann |
| 11 | * |
Daniel Stenberg | 2acc0ac | 2008-06-28 18:10:04 +0000 | [diff] [blame^] | 12 | * This program is free software; you can redistribute it and/or |
| 13 | * modify it under the terms of the GNU General Public License |
| 14 | * as published by the Free Software Foundation; either version 2 |
| 15 | * of the License, or (at your option) any later version. |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 16 | * |
| 17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| 18 | * KIND, either express or implied. |
| 19 | * |
| 20 | ****************************************************************************/ |
| 21 | |
Jens Arnold | b05066d | 2007-10-28 12:09:46 +0000 | [diff] [blame] | 22 | .section .icode, "ax", %progbits |
| 23 | |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 24 | /**************************************************************************** |
| 25 | * void lcd_write_data(const fb_data *addr, |
| 26 | * int pixelcount); |
| 27 | * |
| 28 | * Writes pixelcount pixels from src-pointer (lcd_framebuffer) to BCM dataport. |
| 29 | */ |
Jens Arnold | b05066d | 2007-10-28 12:09:46 +0000 | [diff] [blame] | 30 | .align 2 |
| 31 | .global lcd_write_data |
| 32 | .type lcd_write_data, %function |
Jens Arnold | ef8a7ea | 2007-11-02 00:07:45 +0000 | [diff] [blame] | 33 | /* r0 = addr, must be aligned */ |
| 34 | lcd_write_data: /* r1 = pixel count, must be even */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 35 | stmfd sp!, {r4-r5, lr} |
| 36 | mov lr, #0x30000000 /* LCD data port */ |
Jens Arnold | b05066d | 2007-10-28 12:09:46 +0000 | [diff] [blame] | 37 | |
Jens Arnold | b05066d | 2007-10-28 12:09:46 +0000 | [diff] [blame] | 38 | subs r1, r1, #16 |
| 39 | .loop16: |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 40 | ldmgeia r0!, {r2-r5} |
| 41 | stmgeia lr, {r2-r5} |
| 42 | ldmgeia r0!, {r2-r5} |
| 43 | stmgeia lr, {r2-r5} |
Jens Arnold | b05066d | 2007-10-28 12:09:46 +0000 | [diff] [blame] | 44 | subges r1, r1, #16 |
| 45 | bge .loop16 |
| 46 | |
| 47 | /* no need to correct the count, we're just checking bits from now */ |
| 48 | tst r1, #8 |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 49 | ldmneia r0!, {r2-r5} |
| 50 | stmneia lr, {r2-r5} |
Jens Arnold | b05066d | 2007-10-28 12:09:46 +0000 | [diff] [blame] | 51 | tst r1, #4 |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 52 | ldmneia r0!, {r2-r3} |
| 53 | stmneia lr, {r2-r3} |
Jens Arnold | b05066d | 2007-10-28 12:09:46 +0000 | [diff] [blame] | 54 | tst r1, #2 |
| 55 | ldrne r3, [r0], #4 |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 56 | strne r3, [lr] |
Jens Arnold | b05066d | 2007-10-28 12:09:46 +0000 | [diff] [blame] | 57 | |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 58 | ldmfd sp!, {r4-r5, pc} |
Jens Arnold | b05066d | 2007-10-28 12:09:46 +0000 | [diff] [blame] | 59 | |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 60 | /**************************************************************************** |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 61 | * extern void lcd_write_yuv420_lines(unsigned char const * const src[3], |
| 62 | * unsigned bcmaddr |
| 63 | * int width, |
| 64 | * int stride); |
Jens Arnold | ef8a7ea | 2007-11-02 00:07:45 +0000 | [diff] [blame] | 65 | * |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 66 | * Conversion from Motion JPEG and MPEG Y'PbPr to RGB is: |
| 67 | * |R| |1.164 0.000 1.596| |Y' - 16| |
| 68 | * |G| = |1.164 -0.391 -0.813| |Pb - 128| |
| 69 | * |B| |1.164 2.018 0.000| |Pr - 128| |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 70 | * |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 71 | * Scaled, normalized, rounded and tweaked to yield RGB 565: |
| 72 | * |R| |74 0 101| |Y' - 16| >> 9 |
| 73 | * |G| = |74 -24 -51| |Cb - 128| >> 8 |
| 74 | * |B| |74 128 0| |Cr - 128| >> 9 |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 75 | * |
| 76 | * Converts two lines from YUV to RGB565 and writes to BCM at once. First loop |
| 77 | * loads Cb/Cr, calculates the chroma offset and saves them to buffer. Within |
| 78 | * the second loop these chroma offset are reloaded from buffer. |
| 79 | * Within each loop two pixels are calculated and written to BCM. Before each |
| 80 | * loop the desired destination address is transmitted to BCM. |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 81 | */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 82 | .align 2 |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 83 | .global lcd_write_yuv420_lines |
| 84 | .type lcd_write_yuv420_lines, %function |
| 85 | lcd_write_yuv420_lines: |
| 86 | /* r0 = src = yuv_src */ |
| 87 | /* r1 = dst = bcmaddr */ |
Jens Arnold | ef8a7ea | 2007-11-02 00:07:45 +0000 | [diff] [blame] | 88 | /* r2 = width */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 89 | /* r3 = stride */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 90 | stmfd sp!, { r4-r11, lr } /* save non-scratch */ |
| 91 | ldmia r0, { r9-r11 } /* r9 = yuv_src[0] = Y'_p */ |
| 92 | /* r10 = yuv_src[1] = Cb_p */ |
| 93 | /* r11 = yuv_src[2] = Cr_p */ |
| 94 | add r3, r9, r3 /* r3 = &ysrc[stride] */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 95 | add r4, r2, r2, asr #1 /* chroma buffer lenght = width/2 *3 */ |
| 96 | mov r4, r4, asl #2 /* use words for str/ldm possibility */ |
| 97 | add r4, r4, #19 /* plus room for 4 additional words, */ |
| 98 | bic r4, r4, #3 /* rounded up to multiples of 4 byte */ |
| 99 | sub sp, sp, r4 /* and allocate on stack */ |
| 100 | stmia sp, {r1-r4} /* bcmaddr, width, &ysrc[stride], stack_alloc */ |
| 101 | |
Jens Arnold | ef8a7ea | 2007-11-02 00:07:45 +0000 | [diff] [blame] | 102 | mov r7, r2 /* r7 = loop count */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 103 | add r8, sp, #16 /* chroma buffer */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 104 | mov lr, #0x30000000 /* LCD data port */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 105 | |
| 106 | /* The following writes dest address to BCM and waits for write ready */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 107 | orr r2, lr, #0x00010000 /* r2 = BCM_WR_ADDR32 */ |
| 108 | orr r6, lr, #0x00030000 /* r6 = BCM_CONTROL */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 109 | str r1, [r2] /* BCM_WR_ADDR32 = bcmaddr */ |
| 110 | .busy_1: |
| 111 | ldrh r1, [r6] /* while (!(BCM_CONTROL & 0x2)) */ |
| 112 | tst r1, #0x2 |
| 113 | beq .busy_1 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 114 | |
| 115 | /* 1st loop start */ |
| 116 | 10: /* loop start */ |
| 117 | |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 118 | ldrb r0, [r10], #1 /* r0 = *usrc++ = *Cb_p++ */ |
| 119 | ldrb r1, [r11], #1 /* r1 = *vsrc++ = *Cr_p++ */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 120 | |
| 121 | sub r0, r0, #128 /* r0 = Cb-128 */ |
| 122 | sub r1, r1, #128 /* r1 = Cr-128 */ |
| 123 | |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 124 | add r2, r1, r1, asl #1 /* r2 = Cr*51 + Cb*24 */ |
| 125 | add r2, r2, r2, asl #4 |
| 126 | add r2, r2, r0, asl #3 |
| 127 | add r2, r2, r0, asl #4 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 128 | |
| 129 | add r4, r1, r1, asl #2 /* r1 = Cr*101 */ |
| 130 | add r4, r4, r1, asl #5 |
| 131 | add r1, r4, r1, asl #6 |
| 132 | |
| 133 | add r1, r1, #256 /* r1 = rv = (r1 + 256) >> 9 */ |
| 134 | mov r1, r1, asr #9 |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 135 | rsb r2, r2, #128 /* r2 = guv = (-r2 + 128) >> 8 */ |
| 136 | mov r2, r2, asr #8 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 137 | add r0, r0, #2 /* r0 = bu = (Cb*128 + 256) >> 9 */ |
| 138 | mov r0, r0, asr #2 |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 139 | stmia r8!, {r0-r2} /* store r0, r1 and r2 to chroma buffer */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 140 | |
| 141 | /* 1st loop, first pixel */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 142 | ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 143 | sub r5, r5, #16 /* r5 = (Y'-16) * 74 */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 144 | add r3, r5, r5, asl #2 |
| 145 | add r5, r3, r5, asl #5 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 146 | |
| 147 | add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 148 | add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 149 | add r4, r0, r5, asr #8 /* r4 = b = (Y >> 9) + bu */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 150 | |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 151 | orr r5, r6, r4 /* check if clamping is needed... */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 152 | orr r5, r5, r3, asr #1 /* ...at all */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 153 | cmp r5, #31 |
| 154 | bls 15f /* -> no clamp */ |
| 155 | cmp r6, #31 /* clamp r */ |
| 156 | mvnhi r6, r6, asr #31 |
| 157 | andhi r6, r6, #31 |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 158 | cmp r3, #63 /* clamp g */ |
| 159 | mvnhi r3, r3, asr #31 |
| 160 | andhi r3, r3, #63 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 161 | cmp r4, #31 /* clamp b */ |
| 162 | mvnhi r4, r4, asr #31 |
| 163 | andhi r4, r4, #31 |
| 164 | 15: /* no clamp */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 165 | |
| 166 | /* calculate pixel_1 and save to r5 for later pixel packing */ |
| 167 | orr r4, r4, r3, lsl #5 /* pixel_1 = r<<11 | g<<5 | b */ |
| 168 | orr r5, r4, r6, lsl #11 /* r5 = pixel_1 */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 169 | |
| 170 | /* 1st loop, second pixel */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 171 | ldrb r4, [r9], #1 /* r4 = *ysrc++ = *Y'_p++ */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 172 | sub r4, r4, #16 /* r4 = (Y'-16) * 74 */ |
| 173 | add r3, r4, r4, asl #2 |
| 174 | add r4, r3, r4, asl #5 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 175 | |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 176 | add r6, r1, r4, asr #8 /* r6 = r = (Y >> 9) + rv */ |
| 177 | add r3, r2, r4, asr #7 /* r3 = g = (Y >> 8) + guv */ |
| 178 | add r4, r0, r4, asr #8 /* r4 = b = (Y >> 9) + bu */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 179 | |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 180 | orr r0, r6, r4 /* check if clamping is needed... */ |
| 181 | orr r0, r0, r3, asr #1 /* ...at all */ |
| 182 | cmp r0, #31 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 183 | bls 15f /* -> no clamp */ |
| 184 | cmp r6, #31 /* clamp r */ |
| 185 | mvnhi r6, r6, asr #31 |
| 186 | andhi r6, r6, #31 |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 187 | cmp r3, #63 /* clamp g */ |
| 188 | mvnhi r3, r3, asr #31 |
| 189 | andhi r3, r3, #63 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 190 | cmp r4, #31 /* clamp b */ |
| 191 | mvnhi r4, r4, asr #31 |
| 192 | andhi r4, r4, #31 |
| 193 | 15: /* no clamp */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 194 | |
| 195 | /* calculate pixel_2 and pack with pixel_1 before writing */ |
| 196 | orr r4, r4, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */ |
| 197 | orr r4, r4, r6, lsl #11 /* r4 = pixel_2 */ |
| 198 | orr r4, r5, r4, lsl #16 /* r4 = pixel_2<<16 | pixel_1 */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 199 | str r4, [lr] /* write packed pixels */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 200 | |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 201 | subs r7, r7, #2 /* check for loop end */ |
| 202 | bgt 10b /* back to beginning */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 203 | /* 1st loop end */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 204 | |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 205 | /* Reload several registers for pointer rewinding for next loop */ |
| 206 | add r8, sp, #16 /* chroma buffer */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 207 | ldmia sp, { r1, r7, r9} /* r1 = bcmaddr */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 208 | /* r7 = loop count */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 209 | /* r9 = &ysrc[stride] */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 210 | |
| 211 | /* The following writes dest address to BCM and waits for write ready */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 212 | orr r2, lr, #0x00010000 /* r2 = BCM_WR_ADDR32 */ |
| 213 | orr r6, lr, #0x00030000 /* r6 = BCM_CONTROL */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 214 | add r1, r1, #640 /* dst += (LCD_WIDTH*2) */ |
| 215 | str r1, [r2] /* BCM_WR_ADDR32 = dst */ |
| 216 | .busy_2: |
| 217 | ldrh r1, [r6] /* while (!(BCM_CONTROL & 0x2)) */ |
| 218 | tst r1, #0x2 |
| 219 | beq .busy_2 |
| 220 | |
| 221 | |
| 222 | /* 2nd loop start */ |
| 223 | 20: /* loop start */ |
| 224 | /* restore r0 (bu), r1 (rv) and r2 (guv) from chroma buffer */ |
| 225 | ldmia r8!, {r0-r2} |
| 226 | |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 227 | /* 2nd loop, first pixel */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 228 | ldrb r5, [r9], #1 /* r5 = *ysrc++ = *Y'_p++ */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 229 | sub r5, r5, #16 /* r5 = (Y'-16) * 74 */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 230 | add r3, r5, r5, asl #2 |
| 231 | add r5, r3, r5, asl #5 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 232 | |
| 233 | add r6, r1, r5, asr #8 /* r6 = r = (Y >> 9) + rv */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 234 | add r3, r2, r5, asr #7 /* r3 = g = (Y >> 8) + guv */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 235 | add r4, r0, r5, asr #8 /* r4 = b = (Y >> 9) + bu */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 236 | |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 237 | orr r5, r6, r4 /* check if clamping is needed... */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 238 | orr r5, r5, r3, asr #1 /* ...at all */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 239 | cmp r5, #31 |
| 240 | bls 15f /* -> no clamp */ |
| 241 | cmp r6, #31 /* clamp r */ |
| 242 | mvnhi r6, r6, asr #31 |
| 243 | andhi r6, r6, #31 |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 244 | cmp r3, #63 /* clamp g */ |
| 245 | mvnhi r3, r3, asr #31 |
| 246 | andhi r3, r3, #63 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 247 | cmp r4, #31 /* clamp b */ |
| 248 | mvnhi r4, r4, asr #31 |
| 249 | andhi r4, r4, #31 |
| 250 | 15: /* no clamp */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 251 | /* calculate pixel_1 and save to r5 for later pixel packing */ |
| 252 | orr r4, r4, r3, lsl #5 /* pixel_1 = r<<11 | g<<5 | b */ |
| 253 | orr r5, r4, r6, lsl #11 /* r5 = pixel_1 */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 254 | |
| 255 | /* 2nd loop, second pixel */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 256 | ldrb r4, [r9], #1 /* r4 = *ysrc++ = *Y'_p++ */ |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 257 | sub r4, r4, #16 /* r4 = (Y'-16) * 74 */ |
| 258 | add r3, r4, r4, asl #2 |
| 259 | add r4, r3, r4, asl #5 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 260 | |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 261 | add r6, r1, r4, asr #8 /* r6 = r = (Y >> 9) + rv */ |
| 262 | add r3, r2, r4, asr #7 /* r3 = g = (Y >> 8) + guv */ |
| 263 | add r4, r0, r4, asr #8 /* r4 = b = (Y >> 9) + bu */ |
| 264 | |
| 265 | orr r0, r6, r4 /* check if clamping is needed... */ |
| 266 | orr r0, r0, r3, asr #1 /* ...at all */ |
| 267 | cmp r0, #31 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 268 | bls 15f /* -> no clamp */ |
| 269 | cmp r6, #31 /* clamp r */ |
| 270 | mvnhi r6, r6, asr #31 |
| 271 | andhi r6, r6, #31 |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 272 | cmp r3, #63 /* clamp g */ |
| 273 | mvnhi r3, r3, asr #31 |
| 274 | andhi r3, r3, #63 |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 275 | cmp r4, #31 /* clamp b */ |
| 276 | mvnhi r4, r4, asr #31 |
| 277 | andhi r4, r4, #31 |
| 278 | 15: /* no clamp */ |
| 279 | |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 280 | /* calculate pixel_2 and pack with pixel_1 before writing */ |
| 281 | orr r4, r4, r3, lsl #5 /* pixel_2 = r<<11 | g<<5 | b */ |
| 282 | orr r4, r4, r6, lsl #11 /* r4 = pixel_2 */ |
| 283 | orr r4, r5, r4, lsl #16 /* r4 = pixel_2<<16 | pixel_1 */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 284 | str r4, [lr] /* write packed pixels */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 285 | |
| 286 | subs r7, r7, #2 /* check for loop end */ |
| 287 | bgt 20b /* back to beginning */ |
| 288 | /* 2nd loop end */ |
| 289 | |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 290 | ldr r3, [sp, #12] |
| 291 | add sp, sp, r3 /* deallocate buffer */ |
Andree Buschmann | 2364bc2 | 2008-03-27 07:46:04 +0000 | [diff] [blame] | 292 | ldmfd sp!, { r4-r11, pc } /* restore registers */ |
Jens Arnold | 3c1b9d9 | 2007-10-22 00:37:50 +0000 | [diff] [blame] | 293 | |
| 294 | .ltorg |
Jens Arnold | 120fb4f | 2007-11-26 23:48:23 +0000 | [diff] [blame] | 295 | .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines |