summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/lcd.c174
1 files changed, 97 insertions, 77 deletions
diff --git a/firmware/drivers/lcd.c b/firmware/drivers/lcd.c
index 0df831e259..68627f7c51 100644
--- a/firmware/drivers/lcd.c
+++ b/firmware/drivers/lcd.c
@@ -8,6 +8,7 @@
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2002 by Alan Korr, speedup by Jörg Hohensohn 10 * Copyright (C) 2002 by Alan Korr, speedup by Jörg Hohensohn
11 * Further speedup and reorganization by Jens Arnold
11 * 12 *
12 * All files in this archive are subject to the GNU General Public License. 13 * 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 * See the file COPYING in the source tree root for full license agreement.
@@ -136,7 +137,6 @@ void lcd_write_data(unsigned char* p_bytes, int count)
136 { 137 {
137 unsigned int byte; 138 unsigned int byte;
138 unsigned int sda1; /* precalculated SC=low,SD=1 */ 139 unsigned int sda1; /* precalculated SC=low,SD=1 */
139 unsigned int clk0sda0; /* precalculated SC and SD low */
140 140
141 byte = *p_bytes++ << 24; /* fetch to MSB position */ 141 byte = *p_bytes++ << 24; /* fetch to MSB position */
142 142
@@ -145,89 +145,108 @@ void lcd_write_data(unsigned char* p_bytes, int count)
145 145
146 /* precalculate the values for later bit toggling, init data write */ 146 /* precalculate the values for later bit toggling, init data write */
147 asm ( 147 asm (
148 "mov.b @%2,%0 \n" /* sda1 = PBDRL */ 148 "mov.b @%1,r0 \n" /* r0 = PBDRL */
149 "or %4,%0 \n" /* sda1 |= LCD_DS | LCD_SD DS and SD high, */ 149 "or %3,r0 \n" /* r0 |= LCD_DS | LCD_SD DS and SD high */
150 "and %3,%0 \n" /* sda1 &= ~(LCD_CS | LCD_SC) CS and SC low */ 150 "and %2,r0 \n" /* r0 &= ~(LCD_CS | LCD_SC) CS and SC low */
151 "mov %0,%1 \n" /* sda1 -> clk0sda0 */ 151 "mov.b r0,@%1 \n" /* PBDRL = r0 */
152 "and %5,%1 \n" /* clk0sda0 &= ~LCD_SD both low */ 152 "mov r0,%0 \n" /* sda1 = r0 */
153 "mov.b %1,@%2 \n" /* PBDRL = clk0sda0 */
154 : /* outputs */ 153 : /* outputs */
155 /* %0 */ "=r"(sda1), 154 /* %0 */ "=r"(sda1)
156 /* %1 */ "=r"(clk0sda0)
157 : /* inputs */ 155 : /* inputs */
158 /* %2 */ "r"(LCDR), 156 /* %1 */ "r"(LCDR),
159 /* %3 */ "r"(~(LCD_CS | LCD_SC)), 157 /* %2 */ "I"(~(LCD_CS | LCD_SC)),
160 /* %4 */ "r"(LCD_DS | LCD_SD), 158 /* %3 */ "I"(LCD_DS | LCD_SD)
161 /* %5 */ "r"(~LCD_SD) 159 : /* trashed */
160 "r0"
162 ); 161 );
163 162
164 /* unrolled loop to serialize the byte */ 163 /* unrolled loop to serialize the byte */
165 asm ( 164 asm (
166 "shll %0 \n" /* shift the MSB into carry */ 165 "shll %0 \n" /* shift the msb into carry */
167 166 ".align 2 \n"
168 "bf 1f \n" 167 "mov %1,r0 \n" /* copy precalculated port value */
169 "mov.b %1,@%4 \n" /* if it was a "1": set SD high, SC low still */ 168 "bt 1f \n" /* data bit = 1? */
170 "1: \n" 169 "and %5,r0 \n" /* no: r0 &= ~LCD_SD */
171 "or.b %2,@(r0,gbr) \n" /* rise SC (independent of SD level) */ 170 "1: \n"
172 "shll %0 \n" /* shift for next round, now for longer hold time */ 171 "shll %0 \n" /* next shift here for alignment */
173 "mov.b %3,@%4 \n" /* SC and SD low again */ 172 "mov.b r0,@%3 \n" /* set data to port */
174 173 "or %2,r0 \n" /* rise SC (independent of SD level) */
175 "bf 1f \n" 174 "mov.b r0,@%3 \n" /* set to port */
176 "mov.b %1,@%4 \n" 175
177 "1: \n" 176 "mov %1,r0 \n"
178 "or.b %2,@(r0,gbr) \n" 177 "bt 1f \n"
179 "shll %0 \n" 178 "and %5,r0 \n"
180 "mov.b %3,@%4 \n" 179 "1: \n"
181 180 "mov.b r0,@%3 \n"
182 "bf 1f \n" 181 "or %2,r0 \n"
183 "mov.b %1,@%4 \n" 182 "mov.b r0,@%3 \n"
184 "1: \n" 183
185 "or.b %2,@(r0,gbr) \n" 184 "shll %0 \n"
186 "shll %0 \n" 185 "mov %1,r0 \n"
187 "mov.b %3,@%4 \n" 186 "bt 1f \n"
188 187 "and %5,r0 \n"
189 "bf 1f \n" 188 "1: \n"
190 "mov.b %1,@%4 \n" 189 "shll %0 \n"
191 "1: \n" 190 "mov.b r0,@%3 \n"
192 "or.b %2,@(r0,gbr) \n" 191 "or %2,r0 \n"
193 "shll %0 \n" 192 "mov.b r0,@%3 \n"
194 "mov.b %3,@%4 \n" 193
195 194 "mov %1,r0 \n"
196 "bf 1f \n" 195 "bt 1f \n"
197 "mov.b %1,@%4 \n" 196 "and %5,r0 \n"
198 "1: \n" 197 "1: \n"
199 "or.b %2,@(r0,gbr) \n" 198 "mov.b r0,@%3 \n"
200 "shll %0 \n" 199 "or %2,r0 \n"
201 "mov.b %3,@%4 \n" 200 "mov.b r0,@%3 \n"
202 201
203 "bf 1f \n" 202 "shll %0 \n"
204 "mov.b %1,@%4 \n" 203 "mov %1,r0 \n"
205 "1: \n" 204 "bt 1f \n"
206 "or.b %2,@(r0,gbr) \n" 205 "and %5,r0 \n"
207 "shll %0 \n" 206 "1: \n"
208 "mov.b %3,@%4 \n" 207 "shll %0 \n"
209 208 "mov.b r0,@%3 \n"
210 "bf 1f \n" 209 "or %2,r0 \n"
211 "mov.b %1,@%4 \n" 210 "mov.b r0,@%3 \n"
212 "1: \n" 211
213 "or.b %2,@(r0,gbr) \n" 212 "mov %1,r0 \n"
214 "shll %0 \n" 213 "bt 1f \n"
215 "mov.b %3,@%4 \n" 214 "and %5,r0 \n"
216 215 "1: \n"
217 "bf 1f \n" 216 "mov.b r0,@%3 \n"
218 "mov.b %1,@%4 \n" /* set SD high, SC low still */ 217 "or %2,r0 \n"
219 "1: \n" 218 "mov.b r0,@%3 \n"
220 "or.b %2,@(r0,gbr) \n" /* rise SC (independent of SD level) */ 219
221 220 "shll %0 \n"
222 "or.b %5,@(r0,gbr) \n" /* restore port */ 221 "mov %1,r0 \n"
222 "bt 1f \n"
223 "and %5,r0 \n"
224 "1: \n"
225 "shll %0 \n"
226 "mov.b r0,@%3 \n"
227 "or %2,r0 \n"
228 "mov.b r0,@%3 \n"
229
230 "mov %1,r0 \n"
231 "bt 1f \n"
232 "and %5,r0 \n"
233 "1: \n"
234 "mov.b r0,@%3 \n"
235 "or %2,r0 \n"
236 "mov.b r0,@%3 \n"
237
238 "or %4,r0 \n" /* restore port */
239 "mov.b r0,@%3 \n"
223 : /* outputs */ 240 : /* outputs */
224 : /* inputs */ 241 : /* inputs */
225 /* %0 */ "r"(byte), 242 /* %0 */ "r"(byte),
226 /* %1 */ "r"(sda1), 243 /* %1 */ "r"(sda1),
227 /* %2 */ "I"(LCD_SC), 244 /* %2 */ "I"(LCD_SC),
228 /* %3 */ "r"(clk0sda0), 245 /* %3 */ "r"(LCDR),
229 /* %4 = r0 */ "z"(LCDR), 246 /* %4 */ "I"(LCD_CS | LCD_DS | LCD_SD | LCD_SC),
230 /* %5 */ "I"(LCD_CS|LCD_DS|LCD_SD|LCD_SC) 247 /* %5 */ "I"(~(LCD_SD))
248 : /* trashed */
249 "r0"
231 ); 250 );
232 251
233 /* This is the place to reenable the interrupts, if we have disabled 252 /* This is the place to reenable the interrupts, if we have disabled
@@ -272,12 +291,13 @@ void lcd_write_data(unsigned char* p_bytes, int count)
272 /* unrolled loop to serialize the byte */ 291 /* unrolled loop to serialize the byte */
273 asm ( 292 asm (
274 "shll %0 \n" /* shift the MSB into carry */ 293 "shll %0 \n" /* shift the MSB into carry */
294 ".align 2 \n"
275 "negc %1, r0 \n" /* carry to SD, SC low */ 295 "negc %1, r0 \n" /* carry to SD, SC low */
296 "shll %0 \n" /* next shift here for alignment */
276 "mov.b r0,@%3 \n" /* set data to port */ 297 "mov.b r0,@%3 \n" /* set data to port */
277 "or %2, r0 \n" /* rise SC (independent of SD level) */ 298 "or %2, r0 \n" /* rise SC (independent of SD level) */
278 "mov.b r0,@%3 \n" /* set to port */ 299 "mov.b r0,@%3 \n" /* set to port */
279 300
280 "shll %0 \n"
281 "negc %1, r0 \n" 301 "negc %1, r0 \n"
282 "mov.b r0,@%3 \n" 302 "mov.b r0,@%3 \n"
283 "or %2, r0 \n" 303 "or %2, r0 \n"
@@ -285,11 +305,11 @@ void lcd_write_data(unsigned char* p_bytes, int count)
285 305
286 "shll %0 \n" 306 "shll %0 \n"
287 "negc %1, r0 \n" 307 "negc %1, r0 \n"
308 "shll %0 \n"
288 "mov.b r0,@%3 \n" 309 "mov.b r0,@%3 \n"
289 "or %2, r0 \n" 310 "or %2, r0 \n"
290 "mov.b r0,@%3 \n" 311 "mov.b r0,@%3 \n"
291 312
292 "shll %0 \n"
293 "negc %1, r0 \n" 313 "negc %1, r0 \n"
294 "mov.b r0,@%3 \n" 314 "mov.b r0,@%3 \n"
295 "or %2, r0 \n" 315 "or %2, r0 \n"
@@ -297,11 +317,11 @@ void lcd_write_data(unsigned char* p_bytes, int count)
297 317
298 "shll %0 \n" 318 "shll %0 \n"
299 "negc %1, r0 \n" 319 "negc %1, r0 \n"
320 "shll %0 \n"
300 "mov.b r0,@%3 \n" 321 "mov.b r0,@%3 \n"
301 "or %2, r0 \n" 322 "or %2, r0 \n"
302 "mov.b r0,@%3 \n" 323 "mov.b r0,@%3 \n"
303 324
304 "shll %0 \n"
305 "negc %1, r0 \n" 325 "negc %1, r0 \n"
306 "mov.b r0,@%3 \n" 326 "mov.b r0,@%3 \n"
307 "or %2, r0 \n" 327 "or %2, r0 \n"
@@ -309,11 +329,11 @@ void lcd_write_data(unsigned char* p_bytes, int count)
309 329
310 "shll %0 \n" 330 "shll %0 \n"
311 "negc %1, r0 \n" 331 "negc %1, r0 \n"
332 "shll %0 \n"
312 "mov.b r0,@%3 \n" 333 "mov.b r0,@%3 \n"
313 "or %2, r0 \n" 334 "or %2, r0 \n"
314 "mov.b r0,@%3 \n" 335 "mov.b r0,@%3 \n"
315 336
316 "shll %0 \n"
317 "negc %1, r0 \n" 337 "negc %1, r0 \n"
318 "mov.b r0,@%3 \n" 338 "mov.b r0,@%3 \n"
319 "or %2, r0 \n" 339 "or %2, r0 \n"