diff options
Diffstat (limited to 'firmware/target/arm/s3c2440/lcd-s3c2440.c')
-rw-r--r-- | firmware/target/arm/s3c2440/lcd-s3c2440.c | 158 |
1 files changed, 8 insertions, 150 deletions
diff --git a/firmware/target/arm/s3c2440/lcd-s3c2440.c b/firmware/target/arm/s3c2440/lcd-s3c2440.c index 77be29f556..cbf4784064 100644 --- a/firmware/target/arm/s3c2440/lcd-s3c2440.c +++ b/firmware/target/arm/s3c2440/lcd-s3c2440.c | |||
@@ -19,36 +19,16 @@ | |||
19 | * KIND, either express or implied. | 19 | * KIND, either express or implied. |
20 | * | 20 | * |
21 | ****************************************************************************/ | 21 | ****************************************************************************/ |
22 | #include <sys/types.h> /* off_t */ | ||
23 | |||
24 | #include "config.h" | 22 | #include "config.h" |
25 | #include "system.h" | 23 | #include "system.h" |
26 | #include "cpu.h" | ||
27 | #include "string.h" | ||
28 | #include "lcd.h" | 24 | #include "lcd.h" |
29 | #include "kernel.h" | ||
30 | #include "lcd-target.h" | 25 | #include "lcd-target.h" |
31 | 26 | ||
32 | #define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) | 27 | extern void lcd_set_active(bool active); |
33 | 28 | ||
34 | static bool lcd_on = true; | ||
35 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | 29 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) |
36 | static bool lcd_powered = true; | 30 | static bool lcd_powered = true; |
37 | #endif | 31 | #endif |
38 | static unsigned lcd_yuv_options = 0; | ||
39 | |||
40 | /* Copies a rectangle from one framebuffer to another. Can be used in | ||
41 | single transfer mode with width = num pixels, and height = 1 which | ||
42 | allows a full-width rectangle to be copied more efficiently. */ | ||
43 | extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, | ||
44 | int width, int height); | ||
45 | |||
46 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | ||
47 | bool lcd_active(void) | ||
48 | { | ||
49 | return lcd_on; | ||
50 | } | ||
51 | #endif | ||
52 | 32 | ||
53 | static unsigned int LCDBANK(unsigned int address) | 33 | static unsigned int LCDBANK(unsigned int address) |
54 | { | 34 | { |
@@ -281,7 +261,7 @@ void lcd_sleep(void) | |||
281 | if (lcd_powered) | 261 | if (lcd_powered) |
282 | { | 262 | { |
283 | /* "not powered" implies "disabled" */ | 263 | /* "not powered" implies "disabled" */ |
284 | if (lcd_on) | 264 | if (!lcd_active()) |
285 | lcd_enable(false); | 265 | lcd_enable(false); |
286 | 266 | ||
287 | LCD_SPI_powerdown(); | 267 | LCD_SPI_powerdown(); |
@@ -303,7 +283,7 @@ static void LCD_SPI_powerup(void) | |||
303 | 283 | ||
304 | void lcd_enable(bool state) | 284 | void lcd_enable(bool state) |
305 | { | 285 | { |
306 | if (state == lcd_on) | 286 | if (state == lcd_active()) |
307 | return; | 287 | return; |
308 | 288 | ||
309 | if(state) | 289 | if(state) |
@@ -317,20 +297,20 @@ void lcd_enable(bool state) | |||
317 | sleep(HZ/5); | 297 | sleep(HZ/5); |
318 | } | 298 | } |
319 | 299 | ||
320 | lcd_on = true; | 300 | lcd_set_active(true); |
321 | lcd_update(); | 301 | lcd_update(); |
322 | send_event(LCD_EVENT_ACTIVATION, NULL); | 302 | send_event(LCD_EVENT_ACTIVATION, NULL); |
323 | } | 303 | } |
324 | else | 304 | else |
325 | { | 305 | { |
326 | lcd_on = false; | 306 | lcd_set_active(false); |
327 | } | 307 | } |
328 | } | 308 | } |
329 | #endif | 309 | #endif |
330 | 310 | ||
331 | #ifdef GIGABEAT_F | 311 | #ifdef GIGABEAT_F |
332 | void lcd_set_flip(bool yesno) { | 312 | void lcd_set_flip(bool yesno) { |
333 | if (!lcd_on) | 313 | if (!lcd_active()) |
334 | return; | 314 | return; |
335 | 315 | ||
336 | LCD_SPI_start(); | 316 | LCD_SPI_start(); |
@@ -351,7 +331,7 @@ int lcd_default_contrast(void) | |||
351 | } | 331 | } |
352 | 332 | ||
353 | void lcd_set_contrast(int val) { | 333 | void lcd_set_contrast(int val) { |
354 | if (!lcd_on) | 334 | if (!lcd_active()) |
355 | return; | 335 | return; |
356 | 336 | ||
357 | LCD_SPI_start(); | 337 | LCD_SPI_start(); |
@@ -360,7 +340,7 @@ void lcd_set_contrast(int val) { | |||
360 | } | 340 | } |
361 | 341 | ||
362 | void lcd_set_invert_display(bool yesno) { | 342 | void lcd_set_invert_display(bool yesno) { |
363 | if (!lcd_on) | 343 | if (!lcd_active()) |
364 | return; | 344 | return; |
365 | 345 | ||
366 | LCD_SPI_start(); | 346 | LCD_SPI_start(); |
@@ -399,125 +379,3 @@ void lcd_set_invert_display(bool yesno) | |||
399 | } | 379 | } |
400 | 380 | ||
401 | #endif | 381 | #endif |
402 | |||
403 | /* Update a fraction of the display. */ | ||
404 | void lcd_update_rect(int x, int y, int width, int height) | ||
405 | { | ||
406 | fb_data *dst, *src; | ||
407 | |||
408 | if (!lcd_on) | ||
409 | return; | ||
410 | |||
411 | if (x + width > LCD_WIDTH) | ||
412 | width = LCD_WIDTH - x; /* Clip right */ | ||
413 | if (x < 0) | ||
414 | width += x, x = 0; /* Clip left */ | ||
415 | if (width <= 0) | ||
416 | return; /* nothing left to do */ | ||
417 | |||
418 | if (y + height > LCD_HEIGHT) | ||
419 | height = LCD_HEIGHT - y; /* Clip bottom */ | ||
420 | if (y < 0) | ||
421 | height += y, y = 0; /* Clip top */ | ||
422 | if (height <= 0) | ||
423 | return; /* nothing left to do */ | ||
424 | |||
425 | /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer | ||
426 | * and lcd_framebuffer */ | ||
427 | dst = (fb_data *)FRAME + LCD_WIDTH*y + x; | ||
428 | src = &lcd_framebuffer[y][x]; | ||
429 | |||
430 | /* Copy part of the Rockbox framebuffer to the second framebuffer */ | ||
431 | if (width < LCD_WIDTH) | ||
432 | { | ||
433 | /* Not full width - do line-by-line */ | ||
434 | lcd_copy_buffer_rect(dst, src, width, height); | ||
435 | } | ||
436 | else | ||
437 | { | ||
438 | /* Full width - copy as one line */ | ||
439 | lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); | ||
440 | } | ||
441 | } | ||
442 | |||
443 | /* Update the display. | ||
444 | This must be called after all other LCD functions that change the display. */ | ||
445 | void lcd_update(void) | ||
446 | { | ||
447 | if (!lcd_on) | ||
448 | return; | ||
449 | |||
450 | lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0], | ||
451 | LCD_WIDTH*LCD_HEIGHT, 1); | ||
452 | } | ||
453 | |||
454 | void lcd_yuv_set_options(unsigned options) | ||
455 | { | ||
456 | lcd_yuv_options = options; | ||
457 | } | ||
458 | |||
459 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
460 | extern void lcd_write_yuv420_lines(fb_data *dst, | ||
461 | unsigned char const * const src[3], | ||
462 | int width, | ||
463 | int stride); | ||
464 | extern void lcd_write_yuv420_lines_odither(fb_data *dst, | ||
465 | unsigned char const * const src[3], | ||
466 | int width, | ||
467 | int stride, | ||
468 | int x_screen, /* To align dither pattern */ | ||
469 | int y_screen); | ||
470 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
471 | /* For the Gigabeat - show it rotated */ | ||
472 | /* So the LCD_WIDTH is now the height */ | ||
473 | void lcd_blit_yuv(unsigned char * const src[3], | ||
474 | int src_x, int src_y, int stride, | ||
475 | int x, int y, int width, int height) | ||
476 | { | ||
477 | /* Caches for chroma data so it only need be recaculated every other | ||
478 | line */ | ||
479 | unsigned char const * yuv_src[3]; | ||
480 | off_t z; | ||
481 | |||
482 | if (!lcd_on) | ||
483 | return; | ||
484 | |||
485 | /* Sorry, but width and height must be >= 2 or else */ | ||
486 | width &= ~1; | ||
487 | height >>= 1; | ||
488 | |||
489 | y = LCD_WIDTH - 1 - y; | ||
490 | fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + y; | ||
491 | |||
492 | z = stride*src_y; | ||
493 | yuv_src[0] = src[0] + z + src_x; | ||
494 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | ||
495 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
496 | |||
497 | if (lcd_yuv_options & LCD_YUV_DITHER) | ||
498 | { | ||
499 | do | ||
500 | { | ||
501 | lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); | ||
502 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
503 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
504 | yuv_src[2] += stride >> 1; | ||
505 | dst -= 2; | ||
506 | y -= 2; | ||
507 | } | ||
508 | while (--height > 0); | ||
509 | } | ||
510 | else | ||
511 | { | ||
512 | do | ||
513 | { | ||
514 | lcd_write_yuv420_lines(dst, yuv_src, width, stride); | ||
515 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
516 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
517 | yuv_src[2] += stride >> 1; | ||
518 | dst -= 2; | ||
519 | } | ||
520 | while (--height > 0); | ||
521 | } | ||
522 | } | ||
523 | |||