summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-01-12 00:59:18 +0000
committerJens Arnold <amiconn@rockbox.org>2008-01-12 00:59:18 +0000
commit41cd44caa7b4799dcc14eda33f0f5cf93152a6e0 (patch)
treefcaa7a94441ace95ba74faa9f01397a7d720a7d7
parent9f686700d47e8fcfa0fec65bfbfcf5d5cde3f752 (diff)
downloadrockbox-41cd44caa7b4799dcc14eda33f0f5cf93152a6e0.tar.gz
rockbox-41cd44caa7b4799dcc14eda33f0f5cf93152a6e0.zip
Greyscale ipod lcd driver: * Assembler optimised low level functions. PP5002 targets benefit most (lcd_update() speedup >50%, and the greyscale overlay no longer makes mp3 playback skip). * Consistent brace placement style.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16060 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES5
-rw-r--r--firmware/target/arm/ipod/lcd-as-gray.S290
-rw-r--r--firmware/target/arm/ipod/lcd-gray.c176
3 files changed, 338 insertions, 133 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index ca06d8602f..0f943a0017 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -694,6 +694,7 @@ target/arm/ata-pp5020.c
694target/arm/ipod/adc-ipod-pcf.c 694target/arm/ipod/adc-ipod-pcf.c
695target/arm/ipod/backlight-4g_color.c 695target/arm/ipod/backlight-4g_color.c
696target/arm/ipod/button-clickwheel.c 696target/arm/ipod/button-clickwheel.c
697target/arm/ipod/lcd-as-gray.S
697target/arm/ipod/lcd-gray.c 698target/arm/ipod/lcd-gray.c
698target/arm/ipod/power-ipod.c 699target/arm/ipod/power-ipod.c
699target/arm/ipod/powermgmt-ipod-pcf.c 700target/arm/ipod/powermgmt-ipod-pcf.c
@@ -762,6 +763,7 @@ target/arm/i2s-pp.c
762target/arm/ipod/adc-ipod-pcf.c 763target/arm/ipod/adc-ipod-pcf.c
763target/arm/ipod/3g/backlight-3g.c 764target/arm/ipod/3g/backlight-3g.c
764target/arm/ipod/button-1g-3g.c 765target/arm/ipod/button-1g-3g.c
766target/arm/ipod/lcd-as-gray.S
765target/arm/ipod/lcd-gray.c 767target/arm/ipod/lcd-gray.c
766target/arm/ipod/power-ipod.c 768target/arm/ipod/power-ipod.c
767target/arm/ipod/powermgmt-ipod-pcf.c 769target/arm/ipod/powermgmt-ipod-pcf.c
@@ -778,6 +780,7 @@ target/arm/ipod/1g2g/adc-ipod-1g2g.c
778target/arm/ipod/1g2g/backlight-1g2g.c 780target/arm/ipod/1g2g/backlight-1g2g.c
779target/arm/ipod/1g2g/powermgmt-1g2g.c 781target/arm/ipod/1g2g/powermgmt-1g2g.c
780target/arm/ipod/button-1g-3g.c 782target/arm/ipod/button-1g-3g.c
783target/arm/ipod/lcd-as-gray.S
781target/arm/ipod/lcd-gray.c 784target/arm/ipod/lcd-gray.c
782target/arm/ipod/power-ipod.c 785target/arm/ipod/power-ipod.c
783target/arm/usb-fw-pp5002.c 786target/arm/usb-fw-pp5002.c
@@ -794,6 +797,7 @@ target/arm/i2s-pp.c
794target/arm/ipod/adc-ipod-pcf.c 797target/arm/ipod/adc-ipod-pcf.c
795target/arm/ipod/backlight-mini1g_mini2g.c 798target/arm/ipod/backlight-mini1g_mini2g.c
796target/arm/ipod/button-mini1g.c 799target/arm/ipod/button-mini1g.c
800target/arm/ipod/lcd-as-gray.S
797target/arm/ipod/lcd-gray.c 801target/arm/ipod/lcd-gray.c
798target/arm/ipod/power-ipod.c 802target/arm/ipod/power-ipod.c
799target/arm/ipod/powermgmt-ipod-pcf.c 803target/arm/ipod/powermgmt-ipod-pcf.c
@@ -811,6 +815,7 @@ target/arm/i2s-pp.c
811target/arm/ipod/adc-ipod-pcf.c 815target/arm/ipod/adc-ipod-pcf.c
812target/arm/ipod/backlight-mini1g_mini2g.c 816target/arm/ipod/backlight-mini1g_mini2g.c
813target/arm/ipod/button-clickwheel.c 817target/arm/ipod/button-clickwheel.c
818target/arm/ipod/lcd-as-gray.S
814target/arm/ipod/lcd-gray.c 819target/arm/ipod/lcd-gray.c
815target/arm/ipod/power-ipod.c 820target/arm/ipod/power-ipod.c
816target/arm/ipod/powermgmt-ipod-pcf.c 821target/arm/ipod/powermgmt-ipod-pcf.c
diff --git a/firmware/target/arm/ipod/lcd-as-gray.S b/firmware/target/arm/ipod/lcd-as-gray.S
new file mode 100644
index 0000000000..d16d09b8e2
--- /dev/null
+++ b/firmware/target/arm/ipod/lcd-as-gray.S
@@ -0,0 +1,290 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Jens Arnold
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "config.h"
21#include "cpu.h"
22
23#if CONFIG_CPU == PP5002
24 .section .icode,"ax",%progbits
25#else
26 .text
27#endif
28 .align 2
29
30
31 .global lcd_write_data
32 .type lcd_write_data,%function
33
34lcd_write_data:
35 stmfd sp!, {r4, lr}
36 ldr r2, =LCD1_BASE
37
38.loop:
39 ldrb r3, [r0], #1
40
41#ifdef IPOD_MINI2G
42 ldrb r4, [r0], #1
43 orr r3, r4, r3, lsl #8
44 orr r3, r3, #0x760000
451:
46 ldr r4, [r2]
47 tst r4, #0x8000
48 bne 1b
49 str r3, [r2, #0x08]
50#else
511:
52 ldr r4, [r2]
53 tst r4, #0x8000
54 bne 1b
55 str r3, [r2, #0x10]
56
57 ldrb r3, [r0], #1
581:
59 ldr r4, [r2]
60 tst r4, #0x8000
61 bne 1b
62 str r3, [r2, #0x10]
63#endif
64
65 subs r1, r1, #1
66 bne .loop
67
68 ldmfd sp!, {r4, pc}
69
70.wd_end:
71 .size lcd_write_data,.wd_end-lcd_write_data
72
73
74#ifdef IPOD_MINI2G
75
76 .global lcd_write_data_shifted
77 .type lcd_write_data_shifted,%function
78
79lcd_write_data_shifted:
80 stmfd sp!, {r4-r6, lr}
81 ldr r2, =LCD1_BASE
82 mov r6, #0x760000
83 ldrb r3, [r0], #1
84
85.sloop:
86 ldrb r4, [r0], #1
87 orr r3, r4, r3, lsl #8
88 ldrb r4, [r0], #1
89 orr r3, r4, r3, lsl #8
90 mov r5, r3, lsl #12
91 orr r5, r6, r5, lsr #16
921:
93 ldr r4, [r2]
94 tst r4, #0x8000
95 bne 1b
96 str r5, [r2, #0x08]
97
98 subs r1, r1, #1
99 bne .sloop
100
101 ldmfd sp!, {r4-r6, pc}
102
103.wds_end:
104 .size lcd_write_data_shifted,.wds_end-lcd_write_data_shifted
105
106#elif defined IPOD_MINI
107
108 .global lcd_write_data_shifted
109 .type lcd_write_data_shifted,%function
110
111lcd_write_data_shifted:
112 stmfd sp!, {r4, r5, lr}
113 ldr r2, =LCD1_BASE
114 ldrb r3, [r0], #1
115
116.sloop:
117 ldrb r4, [r0], #1
118 orr r3, r4, r3, lsl #8
119 mov r5, r3, lsr #4
1201:
121 ldr r4, [r2]
122 tst r4, #0x8000
123 bne 1b
124 str r5, [r2, #0x10]
125
126 ldrb r4, [r0], #1
127 orr r3, r4, r3, lsl #8
128 mov r5, r3, lsr #4
1291:
130 ldr r4, [r2]
131 tst r4, #0x8000
132 bne 1b
133 str r5, [r2, #0x10]
134
135 subs r1, r1, #1
136 bne .sloop
137
138 ldmfd sp!, {r4, r5, pc}
139.wds_end:
140 .size lcd_write_data_shifted,.wds_end-lcd_write_data_shifted
141
142#endif
143
144 .global lcd_mono_data
145 .type lcd_mono_data,%function
146
147lcd_mono_data:
148 stmfd sp!, {r4-r6, lr}
149 ldr r2, =LCD1_BASE
150 adr r6, .dibits
151
152.mloop:
153 ldrb r3, [r0], #1
154 mov r4, r3, lsr #4
155 ldrb r5, [r6, r4]
156
157#ifdef IPOD_MINI2G
158 and r4, r3, #0x0f
159 ldrb r4, [r6, r4]
160 orr r5, r4, r5, lsl #8
161 orr r5, r5, #0x760000
1621:
163 ldr r4, [r2]
164 tst r4, #0x8000
165 bne 1b
166 str r5, [r2, #0x08]
167#else
1681:
169 ldr r4, [r2]
170 tst r4, #0x8000
171 bne 1b
172 str r5, [r2, #0x10]
173
174 and r4, r3, #0x0f
175 ldrb r5, [r6, r4]
1761:
177 ldr r4, [r2]
178 tst r4, #0x8000
179 bne 1b
180 str r5, [r2, #0x10]
181#endif
182
183 subs r1, r1, #1
184 bne .mloop
185
186 ldmfd sp!, {r4-r6, pc}
187
188.dibits:
189 .byte 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F
190 .byte 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF
191
192.md_end:
193 .size lcd_mono_data,.md_end-lcd_mono_data
194
195
196 .global lcd_grey_data
197 .type lcd_grey_data,%function
198
199/* A high performance function to write grey phase data to the display,
200 * one or multiple pixels.
201 *
202 * Arguments:
203 * r0 - pixel value data address
204 * r1 - pixel phase data address
205 * r2 - pixel block count
206 *
207 * Register usage:
208 * r3/r4 - current block of phases
209 * r5/r6 - current block of values
210 * r7 - lcd data accumulator
211 * r8 - phase signs mask
212 * r9 - lcd bridge address
213 */
214
215lcd_grey_data:
216 stmfd sp!, {r4-r9, lr}
217 mov r8, #0x80
218 orr r8, r8, r8, lsl #8
219 orr r8, r8, r8, lsl #16
220 ldr r9, =LCD1_BASE
221
222.greyloop:
223 ldmia r1, {r3-r4} /* Fetch 8 pixel phases */
224 ldmia r0!, {r5-r6} /* Fetch 8 pixel values */
225
226#ifdef IPOD_MINI2G /* Serial bridge mode */
227 mov r7, #0x760000
228 tst r3, #0x80
229 orreq r7, r7, #0xc000
230 tst r3, #0x8000
231 orreq r7, r7, #0x3000
232 tst r3, #0x800000
233 orreq r7, r7, #0x0c00
234 tst r3, #0x80000000
235 orreq r7, r7, #0x0300
236 bic r3, r3, r8
237 add r3, r3, r5
238#else /* Parallel bridge mode */
239 mov r7, #0
240 tst r3, #0x80
241 orreq r7, r7, #0xc0
242 tst r3, #0x8000
243 orreq r7, r7, #0x30
244 tst r3, #0x800000
245 orreq r7, r7, #0x0c
246 tst r3, #0x80000000
247 orreq r7, r7, #0x03
248 bic r3, r3, r8
249 add r3, r3, r5
250
2511:
252 ldr r5, [r9]
253 tst r5, #0x8000
254 bne 1b
255
256 str r7, [r9, #0x10]
257 mov r7, #0
258#endif
259
260 tst r4, #0x80
261 orreq r7, r7, #0xc0
262 tst r4, #0x8000
263 orreq r7, r7, #0x30
264 tst r4, #0x800000
265 orreq r7, r7, #0x0c
266 tst r4, #0x80000000
267 orreq r7, r7, #0x03
268 bic r4, r4, r8
269 add r4, r4, r6
270
271 stmia r1!, {r3-r4}
272
2731:
274 ldr r5, [r9]
275 tst r5, #0x8000
276 bne 1b
277#ifdef IPOD_MINI2G
278 str r7, [r9, #0x08]
279#else
280 str r7, [r9, #0x10]
281#endif
282
283 subs r2, r2, #1
284 bne .greyloop
285
286 ldmfd sp!, {r4-r9, pc}
287
288.gd_end:
289 .size lcd_grey_data,.gd_end-lcd_grey_data
290
diff --git a/firmware/target/arm/ipod/lcd-gray.c b/firmware/target/arm/ipod/lcd-gray.c
index 5734480bee..b77d3eb7f6 100644
--- a/firmware/target/arm/ipod/lcd-gray.c
+++ b/firmware/target/arm/ipod/lcd-gray.c
@@ -74,56 +74,47 @@ static unsigned short contrast_reg_h;
74static int addr_offset; 74static int addr_offset;
75#if defined(IPOD_MINI) || defined(IPOD_MINI2G) 75#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
76static int pix_offset; 76static int pix_offset;
77void lcd_write_data_shifted(const fb_data* p_bytes, int count);
77#endif 78#endif
78 79
79static const unsigned char dibits[16] ICONST_ATTR = {
80 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F,
81 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF
82};
83
84/* wait for LCD with timeout */ 80/* wait for LCD with timeout */
85static inline void lcd_wait_write(void) 81static inline void lcd_wait_write(void)
86{ 82{
87 while (LCD1_CONTROL & LCD1_BUSY_MASK); 83 while (LCD1_CONTROL & LCD1_BUSY_MASK);
88} 84}
89 85
90/* send LCD data */ 86/* send LCD command */
91#if CONFIG_CPU == PP5002 87static void lcd_prepare_cmd(unsigned cmd)
92STATICIRAM void ICODE_ATTR lcd_send_data(unsigned data)
93#else
94static void lcd_send_data(unsigned data)
95#endif
96{ 88{
97 lcd_wait_write(); 89 lcd_wait_write();
98#ifdef IPOD_MINI2G 90#ifdef IPOD_MINI2G
99 LCD1_CMD = data | 0x760000; 91 LCD1_CMD = cmd | 0x740000;
100#else 92#else
101 LCD1_DATA = data >> 8; 93 LCD1_CMD = 0;
102 lcd_wait_write(); 94 lcd_wait_write();
103 LCD1_DATA = data & 0xff; 95 LCD1_CMD = cmd;
104#endif 96#endif
105} 97}
106 98
107/* send LCD command */ 99/* send LCD command and data */
108static void lcd_prepare_cmd(unsigned cmd) 100static void lcd_cmd_and_data(unsigned cmd, unsigned data)
109{ 101{
110 lcd_wait_write(); 102 lcd_wait_write();
111#ifdef IPOD_MINI2G 103#ifdef IPOD_MINI2G
112 LCD1_CMD = cmd | 0x740000; 104 LCD1_CMD = cmd | 0x740000;
105 lcd_wait_write();
106 LCD1_CMD = data | 0x760000;
113#else 107#else
114 LCD1_CMD = 0; 108 LCD1_CMD = 0;
115 lcd_wait_write(); 109 lcd_wait_write();
116 LCD1_CMD = cmd; 110 LCD1_CMD = cmd;
111 lcd_wait_write();
112 LCD1_DATA = data >> 8;
113 lcd_wait_write();
114 LCD1_DATA = data & 0xff;
117#endif 115#endif
118} 116}
119 117
120/* send LCD command and data */
121static void lcd_cmd_and_data(unsigned cmd, unsigned data)
122{
123 lcd_prepare_cmd(cmd);
124 lcd_send_data(data);
125}
126
127/* LCD init */ 118/* LCD init */
128void lcd_init_device(void) 119void lcd_init_device(void)
129{ 120{
@@ -230,27 +221,29 @@ void lcd_set_invert_display(bool yesno)
230void lcd_set_flip(bool yesno) 221void lcd_set_flip(bool yesno)
231{ 222{
232#if defined(IPOD_MINI) || defined(IPOD_MINI2G) 223#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
233 if (yesno) { 224 if (yesno)
234 /* 168x112, inverse COM order */ 225 { /* 168x112, inverse COM order */
235 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020d); 226 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020d);
236 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8316); /* 22..131 */ 227 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8316); /* 22..131 */
237 addr_offset = (22 << 5) | (20 - 4); 228 addr_offset = (22 << 5) | (20 - 4);
238 pix_offset = -2; 229 pix_offset = -2;
239 } else { 230 }
240 /* 168x112, inverse SEG order */ 231 else
232 { /* 168x112, inverse SEG order */
241 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010d); 233 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010d);
242 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00); /* 0..109 */ 234 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00); /* 0..109 */
243 addr_offset = 20; 235 addr_offset = 20;
244 pix_offset = 0; 236 pix_offset = 0;
245 } 237 }
246#else 238#else
247 if (yesno) { 239 if (yesno)
248 /* 168x128, inverse SEG & COM order */ 240 { /* 168x128, inverse SEG & COM order */
249 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030f); 241 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030f);
250 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304); /* 4..131 */ 242 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304); /* 4..131 */
251 addr_offset = (4 << 5) | (20 - 1); 243 addr_offset = (4 << 5) | (20 - 1);
252 } else { 244 }
253 /* 168x128 */ 245 else
246 { /* 168x128 */
254 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000f); 247 lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000f);
255 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00); /* 0..127 */ 248 lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00); /* 0..127 */
256 addr_offset = 20; 249 addr_offset = 20;
@@ -279,108 +272,38 @@ void lcd_enable(bool on)
279 272
280/*** update functions ***/ 273/*** update functions ***/
281 274
275/* Helper function. */
276void lcd_mono_data(const unsigned char *data, int count);
277
282/* Performance function that works with an external buffer 278/* Performance function that works with an external buffer
283 note that x, bwidtht and stride are in 8-pixel units! */ 279 note that x, bwidtht and stride are in 8-pixel units! */
284void lcd_blit(const unsigned char* data, int bx, int y, int bwidth, 280void lcd_blit(const unsigned char* data, int bx, int y, int bwidth,
285 int height, int stride) 281 int height, int stride)
286{ 282{
287 const unsigned char *src, *src_end; 283 while (height--)
288 284 {
289 while (height--) {
290 src = data;
291 src_end = data + bwidth;
292 lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx); 285 lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx);
293 lcd_prepare_cmd(R_RAM_DATA); 286 lcd_prepare_cmd(R_RAM_DATA);
294 do { 287
295 unsigned byte = *src++; 288 lcd_mono_data(data, bwidth);
296 lcd_send_data((dibits[byte>>4] << 8) | dibits[byte&0x0f]);
297 } while (src < src_end);
298 data += stride; 289 data += stride;
299 } 290 }
300} 291}
301 292
293/* Helper function for lcd_grey_phase_blit(). */
294void lcd_grey_data(unsigned char *values, unsigned char *phases, int count);
295
302/* Performance function that works with an external buffer 296/* Performance function that works with an external buffer
303 note that bx and bwidth are in 8-pixel units! */ 297 note that bx and bwidth are in 8-pixel units! */
304void lcd_grey_phase_blit(unsigned char *values, unsigned char *phases, 298void lcd_grey_phase_blit(unsigned char *values, unsigned char *phases,
305 int bx, int y, int bwidth, int height, int stride) 299 int bx, int y, int bwidth, int height, int stride)
306{ 300{
307 unsigned char *val, *ph; 301 while (height--)
308 int bw; 302 {
309
310 while (height--) {
311 lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx); 303 lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx);
312 lcd_prepare_cmd(R_RAM_DATA); 304 lcd_prepare_cmd(R_RAM_DATA);
313 305
314 val = values; 306 lcd_grey_data(values, phases, bwidth);
315 ph = phases;
316 bw = bwidth;
317 asm volatile (
318 "10: \n"
319 "ldmia %[ph], {r0-r1} \n" /* Fetch 8 pixel phases */
320 "ldmia %[val]!, {r2-r3} \n" /* Fetch 8 pixel values */
321#ifdef IPOD_MINI2G
322 "mov r4, #0x7600 \n"
323#else
324 "mov r4, #0 \n"
325#endif
326 "tst r0, #0x80 \n"
327 "orreq r4, r4, #0xc0 \n"
328 "tst r0, #0x8000 \n"
329 "orreq r4, r4, #0x30 \n"
330 "tst r0, #0x800000 \n"
331 "orreq r4, r4, #0x0c \n"
332 "tst r0, #0x80000000 \n"
333 "orreq r4, r4, #0x03 \n"
334 "bic r0, r0, %[clbt] \n"
335 "add r0, r0, r2 \n"
336
337#ifdef IPOD_MINI2G
338 "mov r4, r4, lsl #8 \n"
339#else
340 "1: \n"
341 "ldr r2, [%[lcdb]] \n"
342 "tst r2, #0x8000 \n"
343 "bne 1b \n"
344
345 "str r4, [%[lcdb], #0x10] \n"
346 "mov r4, #0 \n"
347#endif
348
349 "tst r1, #0x80 \n"
350 "orreq r4, r4, #0xc0 \n"
351 "tst r1, #0x8000 \n"
352 "orreq r4, r4, #0x30 \n"
353 "tst r1, #0x800000 \n"
354 "orreq r4, r4, #0x0c \n"
355 "tst r1, #0x80000000 \n"
356 "orreq r4, r4, #0x03 \n"
357 "bic r1, r1, %[clbt] \n"
358 "add r1, r1, r3 \n"
359
360 "stmia %[ph]!, {r0-r1} \n"
361
362 "1: \n"
363 "ldr r2, [%[lcdb]] \n"
364 "tst r2, #0x8000 \n"
365 "bne 1b \n"
366#ifdef IPOD_MINI2G
367 "str r4, [%[lcdb], #0x08] \n"
368#else
369 "str r4, [%[lcdb], #0x10] \n"
370#endif
371
372 "subs %[bw], %[bw], #1 \n"
373 "bne 10b \n"
374 : /* outputs */
375 [val]"+r"(val),
376 [ph] "+r"(ph),
377 [bw] "+r"(bw)
378 : /* inputs */
379 [clbt]"r"(0x80808080),
380 [lcdb]"r"(LCD1_BASE)
381 : /* clobbers */
382 "r0", "r1", "r2", "r3", "r4"
383 );
384 values += stride; 307 values += stride;
385 phases += stride; 308 phases += stride;
386 } 309 }
@@ -407,30 +330,17 @@ void lcd_update_rect(int x, int y, int width, int height)
407 x >>= 3; 330 x >>= 3;
408 width = xmax - x + 1; 331 width = xmax - x + 1;
409 332
410 for (; y <= ymax; y++) { 333 for (; y <= ymax; y++)
411 unsigned char *data, *data_end; 334 {
412
413 lcd_cmd_and_data(R_RAM_ADDR_SET, (y << 5) + addr_offset - x); 335 lcd_cmd_and_data(R_RAM_ADDR_SET, (y << 5) + addr_offset - x);
414 lcd_prepare_cmd(R_RAM_DATA); 336 lcd_prepare_cmd(R_RAM_DATA);
415 337
416 data = &lcd_framebuffer[y][2*x];
417 data_end = data + 2 * width;
418#if defined(IPOD_MINI) || defined(IPOD_MINI2G) 338#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
419 if (pix_offset == -2) { 339 if (pix_offset == -2)
420 unsigned cur_word = *data++; 340 lcd_write_data_shifted(&lcd_framebuffer[y][2*x], width);
421 do { 341 else
422 cur_word = (cur_word << 8) | *data++;
423 cur_word = (cur_word << 8) | *data++;
424 lcd_send_data((cur_word >> 4) & 0xffff);
425 } while (data <= data_end);
426 } else
427#endif 342#endif
428 { 343 lcd_write_data(&lcd_framebuffer[y][2*x], width);
429 do {
430 unsigned highbyte = *data++;
431 lcd_send_data((highbyte << 8) | *data++);
432 } while (data < data_end);
433 }
434 } 344 }
435} 345}
436 346