diff options
author | Jens Arnold <amiconn@rockbox.org> | 2008-01-12 00:59:18 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2008-01-12 00:59:18 +0000 |
commit | 41cd44caa7b4799dcc14eda33f0f5cf93152a6e0 (patch) | |
tree | fcaa7a94441ace95ba74faa9f01397a7d720a7d7 | |
parent | 9f686700d47e8fcfa0fec65bfbfcf5d5cde3f752 (diff) | |
download | rockbox-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/SOURCES | 5 | ||||
-rw-r--r-- | firmware/target/arm/ipod/lcd-as-gray.S | 290 | ||||
-rw-r--r-- | firmware/target/arm/ipod/lcd-gray.c | 176 |
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 | |||
694 | target/arm/ipod/adc-ipod-pcf.c | 694 | target/arm/ipod/adc-ipod-pcf.c |
695 | target/arm/ipod/backlight-4g_color.c | 695 | target/arm/ipod/backlight-4g_color.c |
696 | target/arm/ipod/button-clickwheel.c | 696 | target/arm/ipod/button-clickwheel.c |
697 | target/arm/ipod/lcd-as-gray.S | ||
697 | target/arm/ipod/lcd-gray.c | 698 | target/arm/ipod/lcd-gray.c |
698 | target/arm/ipod/power-ipod.c | 699 | target/arm/ipod/power-ipod.c |
699 | target/arm/ipod/powermgmt-ipod-pcf.c | 700 | target/arm/ipod/powermgmt-ipod-pcf.c |
@@ -762,6 +763,7 @@ target/arm/i2s-pp.c | |||
762 | target/arm/ipod/adc-ipod-pcf.c | 763 | target/arm/ipod/adc-ipod-pcf.c |
763 | target/arm/ipod/3g/backlight-3g.c | 764 | target/arm/ipod/3g/backlight-3g.c |
764 | target/arm/ipod/button-1g-3g.c | 765 | target/arm/ipod/button-1g-3g.c |
766 | target/arm/ipod/lcd-as-gray.S | ||
765 | target/arm/ipod/lcd-gray.c | 767 | target/arm/ipod/lcd-gray.c |
766 | target/arm/ipod/power-ipod.c | 768 | target/arm/ipod/power-ipod.c |
767 | target/arm/ipod/powermgmt-ipod-pcf.c | 769 | target/arm/ipod/powermgmt-ipod-pcf.c |
@@ -778,6 +780,7 @@ target/arm/ipod/1g2g/adc-ipod-1g2g.c | |||
778 | target/arm/ipod/1g2g/backlight-1g2g.c | 780 | target/arm/ipod/1g2g/backlight-1g2g.c |
779 | target/arm/ipod/1g2g/powermgmt-1g2g.c | 781 | target/arm/ipod/1g2g/powermgmt-1g2g.c |
780 | target/arm/ipod/button-1g-3g.c | 782 | target/arm/ipod/button-1g-3g.c |
783 | target/arm/ipod/lcd-as-gray.S | ||
781 | target/arm/ipod/lcd-gray.c | 784 | target/arm/ipod/lcd-gray.c |
782 | target/arm/ipod/power-ipod.c | 785 | target/arm/ipod/power-ipod.c |
783 | target/arm/usb-fw-pp5002.c | 786 | target/arm/usb-fw-pp5002.c |
@@ -794,6 +797,7 @@ target/arm/i2s-pp.c | |||
794 | target/arm/ipod/adc-ipod-pcf.c | 797 | target/arm/ipod/adc-ipod-pcf.c |
795 | target/arm/ipod/backlight-mini1g_mini2g.c | 798 | target/arm/ipod/backlight-mini1g_mini2g.c |
796 | target/arm/ipod/button-mini1g.c | 799 | target/arm/ipod/button-mini1g.c |
800 | target/arm/ipod/lcd-as-gray.S | ||
797 | target/arm/ipod/lcd-gray.c | 801 | target/arm/ipod/lcd-gray.c |
798 | target/arm/ipod/power-ipod.c | 802 | target/arm/ipod/power-ipod.c |
799 | target/arm/ipod/powermgmt-ipod-pcf.c | 803 | target/arm/ipod/powermgmt-ipod-pcf.c |
@@ -811,6 +815,7 @@ target/arm/i2s-pp.c | |||
811 | target/arm/ipod/adc-ipod-pcf.c | 815 | target/arm/ipod/adc-ipod-pcf.c |
812 | target/arm/ipod/backlight-mini1g_mini2g.c | 816 | target/arm/ipod/backlight-mini1g_mini2g.c |
813 | target/arm/ipod/button-clickwheel.c | 817 | target/arm/ipod/button-clickwheel.c |
818 | target/arm/ipod/lcd-as-gray.S | ||
814 | target/arm/ipod/lcd-gray.c | 819 | target/arm/ipod/lcd-gray.c |
815 | target/arm/ipod/power-ipod.c | 820 | target/arm/ipod/power-ipod.c |
816 | target/arm/ipod/powermgmt-ipod-pcf.c | 821 | target/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 | |||
34 | lcd_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 | ||
45 | 1: | ||
46 | ldr r4, [r2] | ||
47 | tst r4, #0x8000 | ||
48 | bne 1b | ||
49 | str r3, [r2, #0x08] | ||
50 | #else | ||
51 | 1: | ||
52 | ldr r4, [r2] | ||
53 | tst r4, #0x8000 | ||
54 | bne 1b | ||
55 | str r3, [r2, #0x10] | ||
56 | |||
57 | ldrb r3, [r0], #1 | ||
58 | 1: | ||
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 | |||
79 | lcd_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 | ||
92 | 1: | ||
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 | |||
111 | lcd_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 | ||
120 | 1: | ||
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 | ||
129 | 1: | ||
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 | |||
147 | lcd_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 | ||
162 | 1: | ||
163 | ldr r4, [r2] | ||
164 | tst r4, #0x8000 | ||
165 | bne 1b | ||
166 | str r5, [r2, #0x08] | ||
167 | #else | ||
168 | 1: | ||
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] | ||
176 | 1: | ||
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 | |||
215 | lcd_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 | |||
251 | 1: | ||
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 | |||
273 | 1: | ||
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; | |||
74 | static int addr_offset; | 74 | static int addr_offset; |
75 | #if defined(IPOD_MINI) || defined(IPOD_MINI2G) | 75 | #if defined(IPOD_MINI) || defined(IPOD_MINI2G) |
76 | static int pix_offset; | 76 | static int pix_offset; |
77 | void lcd_write_data_shifted(const fb_data* p_bytes, int count); | ||
77 | #endif | 78 | #endif |
78 | 79 | ||
79 | static 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 */ |
85 | static inline void lcd_wait_write(void) | 81 | static 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 | 87 | static void lcd_prepare_cmd(unsigned cmd) |
92 | STATICIRAM void ICODE_ATTR lcd_send_data(unsigned data) | ||
93 | #else | ||
94 | static 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 */ |
108 | static void lcd_prepare_cmd(unsigned cmd) | 100 | static 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 */ | ||
121 | static 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 */ |
128 | void lcd_init_device(void) | 119 | void lcd_init_device(void) |
129 | { | 120 | { |
@@ -230,27 +221,29 @@ void lcd_set_invert_display(bool yesno) | |||
230 | void lcd_set_flip(bool yesno) | 221 | void 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. */ | ||
276 | void 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! */ |
284 | void lcd_blit(const unsigned char* data, int bx, int y, int bwidth, | 280 | void 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(). */ | ||
294 | void 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! */ |
304 | void lcd_grey_phase_blit(unsigned char *values, unsigned char *phases, | 298 | void 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 | ||