summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2006-10-16 02:24:06 +0000
committerMichael Sevakis <jethead71@rockbox.org>2006-10-16 02:24:06 +0000
commit1102afb0b033245fe57ecef931ab19cdd7893aa9 (patch)
tree4c8b0e0b276de307981191c730d86314d7e195ce
parent1ea2027d63de7df49ab7fffd2e6085db58eaa3ce (diff)
downloadrockbox-1102afb0b033245fe57ecef931ab19cdd7893aa9.tar.gz
rockbox-1102afb0b033245fe57ecef931ab19cdd7893aa9.zip
Disables hard dither mode on the x5 for routine drawing. Display driver automatically enables it when needed. Full screen frame rate up to 48 at normal CPU frequency from about 45 putting it about where it was when everything including the framebuffer was in IRAM due to the shorter and simpler lcd_write_data. Please advise if this works differently on any x5 as this might be considered a hack since nothing in the datasheet specifies using the chip this way. It is perfectly functional on mine.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11233 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/coldfire/iaudio/x5/lcd-as-x5.S115
-rwxr-xr-xfirmware/target/coldfire/iaudio/x5/lcd-x5.c24
2 files changed, 64 insertions, 75 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
index 7c89fb925e..54c1110d2a 100644
--- a/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
+++ b/firmware/target/coldfire/iaudio/x5/lcd-as-x5.S
@@ -290,6 +290,9 @@ lcd_write_yuv420_lines:
290 lea.l (36,%sp),%sp /* restore registers */ 290 lea.l (36,%sp),%sp /* restore registers */
291 291
292 rts 292 rts
293
294.yuv_end:
295 .size lcd_write_yuv420_lines,.yuv_end-lcd_write_yuv420_lines
293/* end lcd_write_yuv420_lines */ 296/* end lcd_write_yuv420_lines */
294 297
295 298
@@ -304,22 +307,19 @@ lcd_write_data:
304 add.l %a0,%d0 /* -> end address */ 307 add.l %a0,%d0 /* -> end address */
305 lea.l 0xf0008002,%a1 /* LCD data port */ 308 lea.l 0xf0008002,%a1 /* LCD data port */
306 309
307 lea.l (-24,%sp),%sp /* free up some registers */ 310 lea.l (-20,%sp),%sp /* free up some registers */
308 movem.l %d2-%d6/%a2,(%sp) 311 movem.l %d2-%d5/%a2,(%sp)
309 312
310 move.l %a0,%d1 313 move.l %a0,%d1
311 btst.l #1,%d1 /* already longword aligned? */ 314 btst.l #1,%d1 /* already longword aligned? */
312 beq.b .wd_wordl_end /* yes: skip initial word copy */ 315 beq.b .wd_wordl_end /* yes: skip initial word copy */
313 /* transfer initial word */ 316 /* transfer initial word */
314 move.w (%a0)+,%d1 /* |????????|????????|rrrrrggg|gggbbbbb| */ 317 move.w (%a0)+,%d2 /* |????????|????????|rrrrrggg|gggbbbbb| */
315 move.l %d1,%d2 318 move.l %d2,%d1
316 and.l #0xfffff800,%d2 /* |????????|????????|rrrrr000|00000000| */ 319 lsr.l #7,%d1 /* |0000000?|????????|???????r|rrrrgggg| */
317 add.l %d2,%d1 /* |????????|???????r|rrrr0ggg|gggbbbbb| */ 320 move.w %d1,(%a1) /* ^ ^^^^^^^ */
318 move.l %d1,%d2 321 lsl.l #1,%d2 /* |????????|???????r|rrrrgggg|ggbbbbb0| */
319 lsr.l #8,%d1 /* |00000000|????????|???????r|rrrr0ggg| */ 322 move.w %d2,(%a1) /* ^ ^^^^^^^ */
320 move.w %d1,(%a1)
321 lsl.l #1,%d2 /* |????????|??????rr|rrr0gggg|ggbbbbb0| */
322 move.w %d2,(%a1)
323 323
324.wd_wordl_end: /* now longword aligned */ 324.wd_wordl_end: /* now longword aligned */
325 moveq.l #28,%d1 325 moveq.l #28,%d1
@@ -335,22 +335,17 @@ lcd_write_data:
335 bls.b .wd_long1_end /* no: skip leading long loop */ 335 bls.b .wd_long1_end /* no: skip leading long loop */
336 336
337.wd_long1_loop: 337.wd_long1_loop:
338 move.l (%a0)+,%d2 /* read longword */ 338 move.l (%a0)+,%d2 /* read longword */
339 swap %d2 /* unstuff two pixels and correct order */ 339 swap %d2 /* |rrrrrggg|gggbbbbb|RRRRRGGG|GGGBBBBB| */
340 move.l %d2,%d5 340 move.l %d2,%d5
341 and.l #0xff00ff00,%d5 /* |rrrrrggg|00000000|rrrrrggg|00000000| */ 341 lsr.l #7,%d5 /* |0000000r|rrrrgggg|ggbbbbbR|RRRRGGGG| */
342 eor.l %d5,%d2 /* |00000000|gggbbbbb|00000000|gggbbbbb| */ 342 move.w %d5,(%a1) /* ^ ^^^^^^^ */
343 lsr.l #8,%d5 /* |00000000|rrrrrggg|00000000|rrrrrggg| */ 343 lsl.l #1,%d2 /* |rrrrgggg|ggbbbbbR|RRRRBGGG|GGBBBBB0| */
344 move.l %d5,%d6 344 move.w %d2,(%a1) /* ^ ^^^^^^^ */
345 and.l #0x00f800f8,%d5 /* |00000000|rrrrr000|00000000|rrrrr000| */ 345 swap %d5 /* |ggbbbbbR|RRRRGGGG|0000000r|rrrrgggg| */
346 add.l %d6,%d5 /* |0000000r|rrrr0ggg|0000000r|rrrr0ggg| */ 346 move.w %d5,(%a1) /* ^ ^^^^^^^ */
347 move.w %d5,(%a1) 347 swap %d2 /* |RRRRBGGG|GGBBBBB0|rrrrgggg|ggbbbbbR| */
348 lsl.l #1,%d2 /* |0000000g|ggbbbbb0|0000000g|ggbbbbb0| */ 348 move.w %d2,(%a1) /* ^ ^^^^^^^ */
349 move.w %d2,(%a1)
350 swap %d5
351 move.w %d5,(%a1)
352 swap %d2
353 move.w %d2,(%a1)
354 cmp.l %a0,%d1 349 cmp.l %a0,%d1
355 bhi.b .wd_long1_loop 350 bhi.b .wd_long1_loop
356 351
@@ -363,15 +358,9 @@ lcd_write_data:
363 lea.l (16,%a0),%a0 /* increment address */ 358 lea.l (16,%a0),%a0 /* increment address */
364 359
365 /* transfer four pairs of longs to display */ 360 /* transfer four pairs of longs to display */
366 /* same procedure for each as in leading long loop */
367 swap %d1 361 swap %d1
368 move.l %d1,%d5 362 move.l %d1,%d5
369 and.l #0xff00ff00,%d5 363 lsr.l #7,%d5
370 eor.l %d5,%d1
371 lsr.l #8,%d5
372 move.l %d5,%d6
373 and.l #0x00f800f8,%d5
374 add.l %d6,%d5
375 move.w %d5,(%a1) 364 move.w %d5,(%a1)
376 lsl.l #1,%d1 365 lsl.l #1,%d1
377 move.w %d1,(%a1) 366 move.w %d1,(%a1)
@@ -380,14 +369,9 @@ lcd_write_data:
380 swap %d1 369 swap %d1
381 move.w %d1,(%a1) 370 move.w %d1,(%a1)
382 371
383 swap %d2 372 swap %d2
384 move.l %d2,%d5 373 move.l %d2,%d5
385 and.l #0xff00ff00,%d5 374 lsr.l #7,%d5
386 eor.l %d5,%d2
387 lsr.l #8,%d5
388 move.l %d5,%d6
389 and.l #0x00f800f8,%d5
390 add.l %d6,%d5
391 move.w %d5,(%a1) 375 move.w %d5,(%a1)
392 lsl.l #1,%d2 376 lsl.l #1,%d2
393 move.w %d2,(%a1) 377 move.w %d2,(%a1)
@@ -396,14 +380,9 @@ lcd_write_data:
396 swap %d2 380 swap %d2
397 move.w %d2,(%a1) 381 move.w %d2,(%a1)
398 382
399 swap %d3 383 swap %d3
400 move.l %d3,%d5 384 move.l %d3,%d5
401 and.l #0xff00ff00,%d5 385 lsr.l #7,%d5
402 eor.l %d5,%d3
403 lsr.l #8,%d5
404 move.l %d5,%d6
405 and.l #0x00f800f8,%d5
406 add.l %d6,%d5
407 move.w %d5,(%a1) 386 move.w %d5,(%a1)
408 lsl.l #1,%d3 387 lsl.l #1,%d3
409 move.w %d3,(%a1) 388 move.w %d3,(%a1)
@@ -412,14 +391,9 @@ lcd_write_data:
412 swap %d3 391 swap %d3
413 move.w %d3,(%a1) 392 move.w %d3,(%a1)
414 393
415 swap %d4 394 swap %d4
416 move.l %d4,%d5 395 move.l %d4,%d5
417 and.l #0xff00ff00,%d5 396 lsr.l #7,%d5
418 eor.l %d5,%d4
419 lsr.l #8,%d5
420 move.l %d5,%d6
421 and.l #0x00f800f8,%d5
422 add.l %d6,%d5
423 move.w %d5,(%a1) 397 move.w %d5,(%a1)
424 lsl.l #1,%d4 398 lsl.l #1,%d4
425 move.w %d4,(%a1) 399 move.w %d4,(%a1)
@@ -437,15 +411,10 @@ lcd_write_data:
437 bls.b .wd_long2_end /* no: skip trailing longword loop */ 411 bls.b .wd_long2_end /* no: skip trailing longword loop */
438 412
439.wd_long2_loop: 413.wd_long2_loop:
440 move.l (%a0)+,%d2 /* read longword */ 414 move.l (%a0)+,%d2 /* read longword */
441 swap %d2 415 swap %d2
442 move.l %d2,%d5 416 move.l %d2,%d5
443 and.l #0xff00ff00,%d5 417 lsr.l #7,%d5
444 eor.l %d5,%d2
445 lsr.l #8,%d5
446 move.l %d5,%d6
447 and.l #0x00f800f8,%d5
448 add.l %d6,%d5
449 move.w %d5,(%a1) 418 move.w %d5,(%a1)
450 lsl.l #1,%d2 419 lsl.l #1,%d2
451 move.w %d2,(%a1) 420 move.w %d2,(%a1)
@@ -459,18 +428,18 @@ lcd_write_data:
459.wd_long2_end: 428.wd_long2_end:
460 blo.b .wd_word2_end /* no final word: skip */ 429 blo.b .wd_word2_end /* no final word: skip */
461 430
462 move.w (%a0),%d1 /* transfer final word */ 431 move.w (%a0)+,%d2 /* transfer final word */
463 move.l %d1,%d2 432 move.l %d2,%d1
464 and.l #0xfffff800,%d2 433 lsr.l #7,%d1
465 add.l %d2,%d1 434 move.w %d1,(%a1)
466 move.l %d1,%d2 435 lsl.l #1,%d2
467 lsr.l #8,%d1 436 move.w %d2,(%a1)
468 move.w %d1,(%a1)
469 lsl.l #1,%d2
470 move.w %d2,(%a1)
471 437
472.wd_word2_end: 438.wd_word2_end:
473 movem.l (%sp),%d2-%d6/%a2 439 movem.l (%sp),%d2-%d5/%a2
474 lea.l (24,%sp),%sp /* restore registers */ 440 lea.l (20,%sp),%sp /* restore registers */
475 rts 441 rts
442
443.wd_end:
444 .size lcd_write_data,.wd_end-lcd_write_data
476/* end lcd_write_data */ 445/* end lcd_write_data */
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-x5.c b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
index c00dc74b0c..e1fac1e2ac 100755
--- a/firmware/target/coldfire/iaudio/x5/lcd-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
@@ -44,6 +44,9 @@ static unsigned short disp_control_rev;
44/* Contrast setting << 8 */ 44/* Contrast setting << 8 */
45static int lcd_contrast; 45static int lcd_contrast;
46 46
47/* Hardware dither bit */
48static unsigned short hw_dit = 0x0000;
49
47/* Forward declarations */ 50/* Forward declarations */
48static void lcd_display_off(void); 51static void lcd_display_off(void);
49 52
@@ -102,6 +105,13 @@ static inline void lcd_begin_write_gram(void)
102 LCD_CMD = R_WRITE_DATA_2_GRAM << 1; 105 LCD_CMD = R_WRITE_DATA_2_GRAM << 1;
103} 106}
104 107
108static void hw_dither(bool on)
109{
110 /* DIT=x, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */
111 hw_dit = on ? 0x8000 : 0x0000;
112 lcd_write_reg(R_ENTRY_MODE, 0x1038 | hw_dit);
113}
114
105/*** hardware configuration ***/ 115/*** hardware configuration ***/
106 116
107int lcd_default_contrast(void) 117int lcd_default_contrast(void)
@@ -224,8 +234,8 @@ static void lcd_power_on(void)
224 lcd_write_reg(R_DRV_OUTPUT_CONTROL, y_offset ? 0x0013 : 0x0313); 234 lcd_write_reg(R_DRV_OUTPUT_CONTROL, y_offset ? 0x0013 : 0x0313);
225 /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */ 235 /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */
226 lcd_write_reg(R_DRV_AC_CONTROL, 0x0700); 236 lcd_write_reg(R_DRV_AC_CONTROL, 0x0700);
227 /* DIT=1, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */ 237 /* DIT=x, BGR=1, HWM=0, I/D1-0=11, AM=1, LG2-0=000 */
228 lcd_write_reg(R_ENTRY_MODE, 0x9038); 238 lcd_write_reg(R_ENTRY_MODE, 0x1038 | hw_dit);
229 /* CP15-0=0000000000000000 */ 239 /* CP15-0=0000000000000000 */
230 lcd_write_reg(R_COMPARE_REG, 0x0000); 240 lcd_write_reg(R_COMPARE_REG, 0x0000);
231 /* NO1-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-00000 */ 241 /* NO1-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-00000 */
@@ -379,6 +389,7 @@ void lcd_init_device(void)
379 lcd_roll(0); 389 lcd_roll(0);
380 lcd_set_invert_display(false); 390 lcd_set_invert_display(false);
381 lcd_set_contrast(DEFAULT_CONTRAST_SETTING); 391 lcd_set_contrast(DEFAULT_CONTRAST_SETTING);
392 hw_dither(false); /* do this or all bootloaders will need reflashing */
382#endif 393#endif
383} 394}
384 395
@@ -455,6 +466,9 @@ void lcd_yuv_blit(unsigned char * const src[3],
455 if (!display_on) 466 if (!display_on)
456 return; 467 return;
457 468
469 if (hw_dit == 0x0000)
470 hw_dither(true);
471
458 width = (width + 1) & ~1; 472 width = (width + 1) & ~1;
459 height = (height + 1) & ~1; 473 height = (height + 1) & ~1;
460 474
@@ -493,6 +507,9 @@ void lcd_update(void)
493 if (!display_on) 507 if (!display_on)
494 return; 508 return;
495 509
510 if (hw_dit != 0x0000)
511 hw_dither(false);
512
496 /* Set start position and window */ 513 /* Set start position and window */
497 /* Just add roll offset to start address. CP will roll back around. */ 514 /* Just add roll offset to start address. CP will roll back around. */
498 lcd_write_reg(R_RAM_ADDR_SET, y_offset + roll_offset); /* X == 0 */ 515 lcd_write_reg(R_RAM_ADDR_SET, y_offset + roll_offset); /* X == 0 */
@@ -513,6 +530,9 @@ void lcd_update_rect(int x, int y, int width, int height)
513 if (!display_on) 530 if (!display_on)
514 return; 531 return;
515 532
533 if (hw_dit != 0x0000)
534 hw_dither(false);
535
516 if (x + width > LCD_WIDTH) 536 if (x + width > LCD_WIDTH)
517 width = LCD_WIDTH - x; /* Clip right */ 537 width = LCD_WIDTH - x; /* Clip right */
518 if (x < 0) 538 if (x < 0)