diff options
Diffstat (limited to 'firmware/target/arm')
11 files changed, 131 insertions, 432 deletions
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c index 140e448630..8edc4b7758 100644 --- a/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c +++ b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c | |||
@@ -29,18 +29,14 @@ | |||
29 | #include "pinctrl-imx233.h" | 29 | #include "pinctrl-imx233.h" |
30 | #include "logf.h" | 30 | #include "logf.h" |
31 | 31 | ||
32 | extern bool lcd_on; /* lcd-memframe.c */ | ||
33 | |||
32 | /* Copies a rectangle from one framebuffer to another. Can be used in | 34 | /* Copies a rectangle from one framebuffer to another. Can be used in |
33 | single transfer mode with width = num pixels, and height = 1 which | 35 | single transfer mode with width = num pixels, and height = 1 which |
34 | allows a full-width rectangle to be copied more efficiently. */ | 36 | allows a full-width rectangle to be copied more efficiently. */ |
35 | extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, | 37 | extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, |
36 | int width, int height); | 38 | int width, int height); |
37 | 39 | ||
38 | static unsigned lcd_yuv_options = 0; | ||
39 | |||
40 | #ifdef HAVE_LCD_ENABLE | ||
41 | static bool lcd_on = true; | ||
42 | #endif | ||
43 | |||
44 | static enum lcd_kind_t | 40 | static enum lcd_kind_t |
45 | { | 41 | { |
46 | LCD_KIND_7783 = 0x7783, | 42 | LCD_KIND_7783 = 0x7783, |
@@ -386,6 +382,8 @@ void lcd_init_device(void) | |||
386 | lcd_kind = LCD_KIND_7783; | 382 | lcd_kind = LCD_KIND_7783; |
387 | lcd_init_seq_7783(); break; | 383 | lcd_init_seq_7783(); break; |
388 | } | 384 | } |
385 | |||
386 | lcd_on = true; | ||
389 | } | 387 | } |
390 | 388 | ||
391 | #ifdef HAVE_LCD_ENABLE | 389 | #ifdef HAVE_LCD_ENABLE |
@@ -469,6 +467,7 @@ void lcd_enable(bool enable) | |||
469 | { | 467 | { |
470 | if(lcd_on == enable) | 468 | if(lcd_on == enable) |
471 | return; | 469 | return; |
470 | |||
472 | lcd_on = enable; | 471 | lcd_on = enable; |
473 | 472 | ||
474 | if(enable) | 473 | if(enable) |
@@ -482,11 +481,6 @@ void lcd_enable(bool enable) | |||
482 | if(!enable) | 481 | if(!enable) |
483 | common_lcd_enable(false); | 482 | common_lcd_enable(false); |
484 | } | 483 | } |
485 | |||
486 | bool lcd_active(void) | ||
487 | { | ||
488 | return lcd_on; | ||
489 | } | ||
490 | #endif | 484 | #endif |
491 | 485 | ||
492 | void lcd_update(void) | 486 | void lcd_update(void) |
@@ -520,74 +514,3 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
520 | (void) height; | 514 | (void) height; |
521 | lcd_update(); | 515 | lcd_update(); |
522 | } | 516 | } |
523 | |||
524 | void lcd_yuv_set_options(unsigned options) | ||
525 | { | ||
526 | lcd_yuv_options = options; | ||
527 | } | ||
528 | |||
529 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
530 | extern void lcd_write_yuv420_lines(fb_data *dst, | ||
531 | unsigned char const * const src[3], | ||
532 | int width, | ||
533 | int stride); | ||
534 | extern void lcd_write_yuv420_lines_odither(fb_data *dst, | ||
535 | unsigned char const * const src[3], | ||
536 | int width, | ||
537 | int stride, | ||
538 | int x_screen, /* To align dither pattern */ | ||
539 | int y_screen); | ||
540 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
541 | /* So the LCD_WIDTH is now the height */ | ||
542 | void lcd_blit_yuv(unsigned char * const src[3], | ||
543 | int src_x, int src_y, int stride, | ||
544 | int x, int y, int width, int height) | ||
545 | { | ||
546 | /* Caches for chroma data so it only need be recaculated every other | ||
547 | line */ | ||
548 | unsigned char const * yuv_src[3]; | ||
549 | off_t z; | ||
550 | |||
551 | #ifdef HAVE_LCD_ENABLE | ||
552 | if (!lcd_on) | ||
553 | return; | ||
554 | #endif | ||
555 | |||
556 | /* Sorry, but width and height must be >= 2 or else */ | ||
557 | width &= ~1; | ||
558 | height >>= 1; | ||
559 | |||
560 | y = LCD_WIDTH - 1 - y; | ||
561 | fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + y; | ||
562 | |||
563 | z = stride*src_y; | ||
564 | yuv_src[0] = src[0] + z + src_x; | ||
565 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | ||
566 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
567 | |||
568 | if (lcd_yuv_options & LCD_YUV_DITHER) | ||
569 | { | ||
570 | do | ||
571 | { | ||
572 | lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); | ||
573 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
574 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
575 | yuv_src[2] += stride >> 1; | ||
576 | dst -= 2; | ||
577 | y -= 2; | ||
578 | } | ||
579 | while (--height > 0); | ||
580 | } | ||
581 | else | ||
582 | { | ||
583 | do | ||
584 | { | ||
585 | lcd_write_yuv420_lines(dst, yuv_src, width, stride); | ||
586 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
587 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
588 | yuv_src[2] += stride >> 1; | ||
589 | dst -= 2; | ||
590 | } | ||
591 | while (--height > 0); | ||
592 | } | ||
593 | } | ||
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/lcd-target.h b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-target.h new file mode 100644 index 0000000000..fe65b916a3 --- /dev/null +++ b/firmware/target/arm/imx233/sansa-fuzeplus/lcd-target.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (c) 2011 by Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef LCD_TARGET_H | ||
22 | #define LCD_TARGET_H | ||
23 | |||
24 | #define LCD_FRAMEBUF_ADDR(col, row) ((fb_data *)FRAME + (row)*LCD_WIDTH + (col)) | ||
25 | |||
26 | /* Not really optimized, but are unusual */ | ||
27 | #define LCD_OPTIMIZED_UPDATE | ||
28 | #define LCD_OPTIMIZED_UPDATE_RECT | ||
29 | |||
30 | #endif /* LCD_TARGET_H */ | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c index 1d27716d2a..f0a2764851 100644 --- a/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c +++ b/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c | |||
@@ -29,10 +29,9 @@ | |||
29 | #include "spi-imx31.h" | 29 | #include "spi-imx31.h" |
30 | #include "mc13783.h" | 30 | #include "mc13783.h" |
31 | 31 | ||
32 | extern void lcd_set_active(bool active); | ||
33 | |||
34 | #define MAIN_LCD_IDMAC_CHANNEL 14 | 32 | #define MAIN_LCD_IDMAC_CHANNEL 14 |
35 | 33 | ||
34 | extern bool lcd_on; /* lcd-memframe.c */ | ||
36 | static bool lcd_powered = true; | 35 | static bool lcd_powered = true; |
37 | 36 | ||
38 | /* Settings shadow regs */ | 37 | /* Settings shadow regs */ |
@@ -171,6 +170,8 @@ void INIT_ATTR lcd_init_device(void) | |||
171 | IPU_IPU_IMA_ADDR = ((0x1 << 16) | (MAIN_LCD_IDMAC_CHANNEL << 4)) + (1 << 3); | 170 | IPU_IPU_IMA_ADDR = ((0x1 << 16) | (MAIN_LCD_IDMAC_CHANNEL << 4)) + (1 << 3); |
172 | IPU_IPU_IMA_DATA = FRAME_PHYS_ADDR; | 171 | IPU_IPU_IMA_DATA = FRAME_PHYS_ADDR; |
173 | 172 | ||
173 | lcd_on = true; | ||
174 | |||
174 | lcd_enable_interface(true); | 175 | lcd_enable_interface(true); |
175 | lcd_sync_settings(); | 176 | lcd_sync_settings(); |
176 | } | 177 | } |
@@ -188,7 +189,7 @@ void lcd_sleep(void) | |||
188 | 189 | ||
189 | void lcd_enable(bool state) | 190 | void lcd_enable(bool state) |
190 | { | 191 | { |
191 | if (state == lcd_active()) | 192 | if (state == lcd_on) |
192 | return; | 193 | return; |
193 | 194 | ||
194 | if (state) | 195 | if (state) |
@@ -198,13 +199,13 @@ void lcd_enable(bool state) | |||
198 | IPU_IDMAC_CHA_EN |= 1ul << MAIN_LCD_IDMAC_CHANNEL; | 199 | IPU_IDMAC_CHA_EN |= 1ul << MAIN_LCD_IDMAC_CHANNEL; |
199 | lcd_sync_settings(); | 200 | lcd_sync_settings(); |
200 | sleep(HZ/50); | 201 | sleep(HZ/50); |
201 | lcd_set_active(true); | 202 | lcd_on = true; |
202 | lcd_update(); | 203 | lcd_update(); |
203 | send_event(LCD_EVENT_ACTIVATION, NULL); | 204 | send_event(LCD_EVENT_ACTIVATION, NULL); |
204 | } | 205 | } |
205 | else | 206 | else |
206 | { | 207 | { |
207 | lcd_set_active(false); | 208 | lcd_on = false; |
208 | } | 209 | } |
209 | } | 210 | } |
210 | 211 | ||
@@ -213,7 +214,7 @@ void lcd_set_contrast(int val) | |||
213 | { | 214 | { |
214 | reg0x0b = val & 0x3f; | 215 | reg0x0b = val & 0x3f; |
215 | 216 | ||
216 | if (!lcd_active()) | 217 | if (!lcd_on) |
217 | return; | 218 | return; |
218 | 219 | ||
219 | lcd_write_reg(0x0b, reg0x0b); | 220 | lcd_write_reg(0x0b, reg0x0b); |
@@ -230,7 +231,7 @@ void lcd_set_invert_display(bool yesno) | |||
230 | { | 231 | { |
231 | reg0x27 = yesno ? 0x10 : 0x00; | 232 | reg0x27 = yesno ? 0x10 : 0x00; |
232 | 233 | ||
233 | if (!lcd_active()) | 234 | if (!lcd_on) |
234 | return; | 235 | return; |
235 | 236 | ||
236 | lcd_write_reg(0x27, reg0x27); | 237 | lcd_write_reg(0x27, reg0x27); |
@@ -242,7 +243,7 @@ void lcd_set_flip(bool yesno) | |||
242 | { | 243 | { |
243 | reg0x06 = yesno ? 0x02 : 0x04; | 244 | reg0x06 = yesno ? 0x02 : 0x04; |
244 | 245 | ||
245 | if (!lcd_active()) | 246 | if (!lcd_on) |
246 | return; | 247 | return; |
247 | 248 | ||
248 | lcd_write_reg(0x06, reg0x06); | 249 | lcd_write_reg(0x06, reg0x06); |
diff --git a/firmware/target/arm/s3c2440/lcd-s3c2440.c b/firmware/target/arm/s3c2440/lcd-s3c2440.c index 06b67c7535..1631e350f3 100644 --- a/firmware/target/arm/s3c2440/lcd-s3c2440.c +++ b/firmware/target/arm/s3c2440/lcd-s3c2440.c | |||
@@ -24,8 +24,7 @@ | |||
24 | #include "lcd.h" | 24 | #include "lcd.h" |
25 | #include "lcd-target.h" | 25 | #include "lcd-target.h" |
26 | 26 | ||
27 | extern bool lcd_active(void); | 27 | extern bool lcd_on; /* lcd-memframe.c */ |
28 | extern void lcd_set_active(bool active); | ||
29 | 28 | ||
30 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | 29 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) |
31 | static bool lcd_powered = true; | 30 | static bool lcd_powered = true; |
@@ -242,6 +241,8 @@ void lcd_init_device(void) | |||
242 | #else | 241 | #else |
243 | LCD_CTRL_clock(true); | 242 | LCD_CTRL_clock(true); |
244 | #endif | 243 | #endif |
244 | |||
245 | lcd_on = true; | ||
245 | } | 246 | } |
246 | 247 | ||
247 | #if defined(HAVE_LCD_SLEEP) | 248 | #if defined(HAVE_LCD_SLEEP) |
@@ -262,9 +263,7 @@ void lcd_sleep(void) | |||
262 | if (lcd_powered) | 263 | if (lcd_powered) |
263 | { | 264 | { |
264 | /* "not powered" implies "disabled" */ | 265 | /* "not powered" implies "disabled" */ |
265 | if (!lcd_active()) | 266 | lcd_enable(false); |
266 | lcd_enable(false); | ||
267 | |||
268 | LCD_SPI_powerdown(); | 267 | LCD_SPI_powerdown(); |
269 | } | 268 | } |
270 | } | 269 | } |
@@ -284,7 +283,7 @@ static void LCD_SPI_powerup(void) | |||
284 | 283 | ||
285 | void lcd_enable(bool state) | 284 | void lcd_enable(bool state) |
286 | { | 285 | { |
287 | if (state == lcd_active()) | 286 | if (state == lcd_on) |
288 | return; | 287 | return; |
289 | 288 | ||
290 | if(state) | 289 | if(state) |
@@ -298,20 +297,21 @@ void lcd_enable(bool state) | |||
298 | sleep(HZ/5); | 297 | sleep(HZ/5); |
299 | } | 298 | } |
300 | 299 | ||
301 | lcd_set_active(true); | 300 | lcd_on = true; |
302 | lcd_update(); | 301 | lcd_update(); |
303 | send_event(LCD_EVENT_ACTIVATION, NULL); | 302 | send_event(LCD_EVENT_ACTIVATION, NULL); |
304 | } | 303 | } |
305 | else | 304 | else |
306 | { | 305 | { |
307 | lcd_set_active(false); | 306 | lcd_on = false; |
308 | } | 307 | } |
309 | } | 308 | } |
310 | #endif | 309 | #endif |
311 | 310 | ||
312 | #ifdef GIGABEAT_F | 311 | #ifdef GIGABEAT_F |
313 | void lcd_set_flip(bool yesno) { | 312 | void lcd_set_flip(bool yesno) |
314 | if (!lcd_active()) | 313 | { |
314 | if (!lcd_on) | ||
315 | return; | 315 | return; |
316 | 316 | ||
317 | LCD_SPI_start(); | 317 | LCD_SPI_start(); |
@@ -331,8 +331,9 @@ int lcd_default_contrast(void) | |||
331 | return DEFAULT_CONTRAST_SETTING; | 331 | return DEFAULT_CONTRAST_SETTING; |
332 | } | 332 | } |
333 | 333 | ||
334 | void lcd_set_contrast(int val) { | 334 | void lcd_set_contrast(int val) |
335 | if (!lcd_active()) | 335 | { |
336 | if (!lcd_on) | ||
336 | return; | 337 | return; |
337 | 338 | ||
338 | LCD_SPI_start(); | 339 | LCD_SPI_start(); |
@@ -340,8 +341,9 @@ void lcd_set_contrast(int val) { | |||
340 | LCD_SPI_stop(); | 341 | LCD_SPI_stop(); |
341 | } | 342 | } |
342 | 343 | ||
343 | void lcd_set_invert_display(bool yesno) { | 344 | void lcd_set_invert_display(bool yesno) |
344 | if (!lcd_active()) | 345 | { |
346 | if (!lcd_on) | ||
345 | return; | 347 | return; |
346 | 348 | ||
347 | LCD_SPI_start(); | 349 | LCD_SPI_start(); |
diff --git a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c index b3c05fb48c..39ceb9b8e0 100644 --- a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c +++ b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c | |||
@@ -27,11 +27,9 @@ | |||
27 | #include "lcd.h" | 27 | #include "lcd.h" |
28 | #include "lcd-target.h" | 28 | #include "lcd-target.h" |
29 | 29 | ||
30 | extern bool lcd_active(void); | ||
31 | extern void lcd_set_active(bool active); | ||
32 | |||
33 | /* Power and display status */ | 30 | /* Power and display status */ |
34 | static bool power_on = false; /* Is the power turned on? */ | 31 | extern bool lcd_on; /* lcd-memframe.c */ |
32 | static bool power_on = false; /* Is the power turned on? */ | ||
35 | 33 | ||
36 | /* Reverse Flag */ | 34 | /* Reverse Flag */ |
37 | #define R_DISP_CONTROL_NORMAL 0x0004 | 35 | #define R_DISP_CONTROL_NORMAL 0x0004 |
@@ -309,7 +307,7 @@ static void lcd_display_on(void) | |||
309 | lcd_send_msg(0x70, R_RAM_WRITE_DATA); | 307 | lcd_send_msg(0x70, R_RAM_WRITE_DATA); |
310 | 308 | ||
311 | /* tell that we're on now */ | 309 | /* tell that we're on now */ |
312 | lcd_set_active(true); | 310 | lcd_on = true; |
313 | } | 311 | } |
314 | 312 | ||
315 | 313 | ||
@@ -318,7 +316,7 @@ static void lcd_display_on(void) | |||
318 | static void lcd_display_off(void) | 316 | static void lcd_display_off(void) |
319 | { | 317 | { |
320 | /* block drawing operations and changing of first */ | 318 | /* block drawing operations and changing of first */ |
321 | lcd_set_active(false); | 319 | lcd_on = false; |
322 | 320 | ||
323 | /* NO2-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-0=0000 */ | 321 | /* NO2-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-0=0000 */ |
324 | lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x4000); | 322 | lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x4000); |
@@ -422,7 +420,7 @@ void lcd_init_device(void) | |||
422 | LCD_FB_BASE_REG = (long)lcd_driver_framebuffer; | 420 | LCD_FB_BASE_REG = (long)lcd_driver_framebuffer; |
423 | 421 | ||
424 | power_on = true; | 422 | power_on = true; |
425 | lcd_set_active(true); | 423 | lcd_on = true; |
426 | 424 | ||
427 | lcd_set_invert_display(false); | 425 | lcd_set_invert_display(false); |
428 | lcd_set_flip(false); | 426 | lcd_set_flip(false); |
@@ -434,7 +432,7 @@ void lcd_init_device(void) | |||
434 | #if defined(HAVE_LCD_ENABLE) | 432 | #if defined(HAVE_LCD_ENABLE) |
435 | void lcd_enable(bool on) | 433 | void lcd_enable(bool on) |
436 | { | 434 | { |
437 | if (on == lcd_active()) | 435 | if (on == lcd_on) |
438 | return; | 436 | return; |
439 | 437 | ||
440 | if (on) | 438 | if (on) |
@@ -465,9 +463,8 @@ void lcd_sleep(void) | |||
465 | if (power_on) | 463 | if (power_on) |
466 | { | 464 | { |
467 | /* Turn off display */ | 465 | /* Turn off display */ |
468 | if (lcd_active()) | 466 | if (lcd_on) |
469 | lcd_display_off(); | 467 | lcd_display_off(); |
470 | |||
471 | power_on = false; | 468 | power_on = false; |
472 | } | 469 | } |
473 | 470 | ||
@@ -499,7 +496,7 @@ void lcd_set_invert_display(bool yesno) | |||
499 | r_disp_control_rev = yesno ? R_DISP_CONTROL_REV : | 496 | r_disp_control_rev = yesno ? R_DISP_CONTROL_REV : |
500 | R_DISP_CONTROL_NORMAL; | 497 | R_DISP_CONTROL_NORMAL; |
501 | 498 | ||
502 | if (lcd_active()) | 499 | if (lcd_on) |
503 | { | 500 | { |
504 | /* PT1-0=00, VLE2-1=00, SPT=0, IB6(??)=1, GON=1, CL=0, | 501 | /* PT1-0=00, VLE2-1=00, SPT=0, IB6(??)=1, GON=1, CL=0, |
505 | DTE=1, REV=x, D1-0=11 */ | 502 | DTE=1, REV=x, D1-0=11 */ |
diff --git a/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c b/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c index ab50769983..b4c37b716c 100644 --- a/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c +++ b/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c | |||
@@ -24,9 +24,12 @@ | |||
24 | #include "hwcompat.h" | 24 | #include "hwcompat.h" |
25 | #include "kernel.h" | 25 | #include "kernel.h" |
26 | #include "lcd.h" | 26 | #include "lcd.h" |
27 | #include "lcd-target.h" | ||
27 | #include "system.h" | 28 | #include "system.h" |
28 | #include "cpu.h" | 29 | #include "cpu.h" |
29 | 30 | ||
31 | extern bool lcd_on; /* lcd-memframe.c */ | ||
32 | |||
30 | /* GPIO A pins for LCD panel SDI interface */ | 33 | /* GPIO A pins for LCD panel SDI interface */ |
31 | 34 | ||
32 | #define LTV250QV_CS (1<<24) | 35 | #define LTV250QV_CS (1<<24) |
@@ -51,11 +54,6 @@ | |||
51 | #define LCDC_I1OFF (*(volatile unsigned long *)0xF00000A8) | 54 | #define LCDC_I1OFF (*(volatile unsigned long *)0xF00000A8) |
52 | #define LCDC_I1SCALE (*(volatile unsigned long *)0xF00000AC) | 55 | #define LCDC_I1SCALE (*(volatile unsigned long *)0xF00000AC) |
53 | 56 | ||
54 | /* Power and display status */ | ||
55 | static bool display_on = false; /* Is the display turned on? */ | ||
56 | |||
57 | static unsigned lcd_yuv_options = 0; | ||
58 | |||
59 | /* Framebuffer copy as seen by the hardware */ | 57 | /* Framebuffer copy as seen by the hardware */ |
60 | fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]; | 58 | fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]; |
61 | 59 | ||
@@ -180,13 +178,13 @@ static void lcd_display_on(void) | |||
180 | udelay(10000); | 178 | udelay(10000); |
181 | 179 | ||
182 | /* tell that we're on now */ | 180 | /* tell that we're on now */ |
183 | display_on = true; | 181 | lcd_on = true; |
184 | } | 182 | } |
185 | 183 | ||
186 | static void lcd_display_off(void) | 184 | static void lcd_display_off(void) |
187 | { | 185 | { |
188 | /* block drawing operations and changing of first */ | 186 | /* block drawing operations and changing of first */ |
189 | display_on = false; | 187 | lcd_on = false; |
190 | 188 | ||
191 | /* LQV shutdown sequence */ | 189 | /* LQV shutdown sequence */ |
192 | lcd_write_reg(9, 0x55); | 190 | lcd_write_reg(9, 0x55); |
@@ -204,7 +202,7 @@ static void lcd_display_off(void) | |||
204 | 202 | ||
205 | void lcd_enable(bool on) | 203 | void lcd_enable(bool on) |
206 | { | 204 | { |
207 | if (on == display_on) | 205 | if (on == lcd_on) |
208 | return; | 206 | return; |
209 | 207 | ||
210 | if (on) | 208 | if (on) |
@@ -221,11 +219,6 @@ void lcd_enable(bool on) | |||
221 | } | 219 | } |
222 | } | 220 | } |
223 | 221 | ||
224 | bool lcd_active(void) | ||
225 | { | ||
226 | return display_on; | ||
227 | } | ||
228 | |||
229 | /* TODO: implement lcd_sleep() and separate out the power on/off functions */ | 222 | /* TODO: implement lcd_sleep() and separate out the power on/off functions */ |
230 | 223 | ||
231 | void lcd_init_device(void) | 224 | void lcd_init_device(void) |
@@ -278,67 +271,6 @@ void lcd_init_device(void) | |||
278 | 271 | ||
279 | 272 | ||
280 | /*** Update functions ***/ | 273 | /*** Update functions ***/ |
281 | |||
282 | |||
283 | /* Copies a rectangle from one framebuffer to another. Can be used in | ||
284 | single transfer mode with width = num pixels, and height = 1 which | ||
285 | allows a full-width rectangle to be copied more efficiently. */ | ||
286 | extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, | ||
287 | int width, int height); | ||
288 | |||
289 | /* Update the display. | ||
290 | This must be called after all other LCD functions that change the display. */ | ||
291 | void lcd_update(void) ICODE_ATTR; | ||
292 | void lcd_update(void) | ||
293 | { | ||
294 | if (!display_on) | ||
295 | return; | ||
296 | |||
297 | lcd_copy_buffer_rect(&lcd_driver_framebuffer[0][0], | ||
298 | &lcd_framebuffer[0][0], LCD_WIDTH*LCD_HEIGHT, 1); | ||
299 | } | ||
300 | |||
301 | /* Update a fraction of the display. */ | ||
302 | void lcd_update_rect(int, int, int, int) ICODE_ATTR; | ||
303 | void lcd_update_rect(int x, int y, int width, int height) | ||
304 | { | ||
305 | fb_data *dst, *src; | ||
306 | |||
307 | if (!display_on) | ||
308 | return; | ||
309 | |||
310 | if (x + width > LCD_WIDTH) | ||
311 | width = LCD_WIDTH - x; /* Clip right */ | ||
312 | if (x < 0) | ||
313 | width += x, x = 0; /* Clip left */ | ||
314 | if (width <= 0) | ||
315 | return; /* nothing left to do */ | ||
316 | |||
317 | if (y + height > LCD_HEIGHT) | ||
318 | height = LCD_HEIGHT - y; /* Clip bottom */ | ||
319 | if (y < 0) | ||
320 | height += y, y = 0; /* Clip top */ | ||
321 | if (height <= 0) | ||
322 | return; /* nothing left to do */ | ||
323 | |||
324 | /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer | ||
325 | * and lcd_framebuffer */ | ||
326 | dst = &lcd_driver_framebuffer[y][x]; | ||
327 | src = &lcd_framebuffer[y][x]; | ||
328 | |||
329 | /* Copy part of the Rockbox framebuffer to the second framebuffer */ | ||
330 | if (width < LCD_WIDTH) | ||
331 | { | ||
332 | /* Not full width - do line-by-line */ | ||
333 | lcd_copy_buffer_rect(dst, src, width, height); | ||
334 | } | ||
335 | else | ||
336 | { | ||
337 | /* Full width - copy as one line */ | ||
338 | lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); | ||
339 | } | ||
340 | } | ||
341 | |||
342 | void lcd_set_flip(bool yesno) | 274 | void lcd_set_flip(bool yesno) |
343 | { | 275 | { |
344 | // TODO | 276 | // TODO |
@@ -350,70 +282,3 @@ void lcd_set_invert_display(bool yesno) | |||
350 | // TODO | 282 | // TODO |
351 | (void)yesno; | 283 | (void)yesno; |
352 | } | 284 | } |
353 | |||
354 | void lcd_yuv_set_options(unsigned options) | ||
355 | { | ||
356 | lcd_yuv_options = options; | ||
357 | } | ||
358 | |||
359 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
360 | extern void lcd_write_yuv420_lines(fb_data *dst, | ||
361 | unsigned char const * const src[3], | ||
362 | int width, | ||
363 | int stride); | ||
364 | |||
365 | extern void lcd_write_yuv420_lines_odither(fb_data *dst, | ||
366 | unsigned char const * const src[3], | ||
367 | int width, | ||
368 | int stride, | ||
369 | int x_screen, /* To align dither pattern */ | ||
370 | int y_screen); | ||
371 | |||
372 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
373 | void lcd_blit_yuv(unsigned char * const src[3], | ||
374 | int src_x, int src_y, int stride, | ||
375 | int x, int y, int width, int height) | ||
376 | { | ||
377 | unsigned char const * yuv_src[3]; | ||
378 | off_t z; | ||
379 | |||
380 | if (!display_on) | ||
381 | return; | ||
382 | |||
383 | /* Sorry, but width and height must be >= 2 or else */ | ||
384 | width &= ~1; | ||
385 | height >>= 1; | ||
386 | |||
387 | fb_data *dst = &lcd_driver_framebuffer[y][x]; | ||
388 | |||
389 | z = stride*src_y; | ||
390 | yuv_src[0] = src[0] + z + src_x; | ||
391 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | ||
392 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
393 | |||
394 | if (lcd_yuv_options & LCD_YUV_DITHER) | ||
395 | { | ||
396 | do | ||
397 | { | ||
398 | lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); | ||
399 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
400 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
401 | yuv_src[2] += stride >> 1; | ||
402 | dst += 2*LCD_FBWIDTH; | ||
403 | y -= 2; | ||
404 | } | ||
405 | while (--height > 0); | ||
406 | } | ||
407 | else | ||
408 | { | ||
409 | do | ||
410 | { | ||
411 | lcd_write_yuv420_lines(dst, yuv_src, width, stride); | ||
412 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
413 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
414 | yuv_src[2] += stride >> 1; | ||
415 | dst += 2*LCD_FBWIDTH; | ||
416 | } | ||
417 | while (--height > 0); | ||
418 | } | ||
419 | } | ||
diff --git a/firmware/target/arm/tcc780x/cowond2/lcd-target.h b/firmware/target/arm/tcc780x/cowond2/lcd-target.h new file mode 100644 index 0000000000..52caf34a45 --- /dev/null +++ b/firmware/target/arm/tcc780x/cowond2/lcd-target.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Rob Purchase | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef LCD_TARGET_H | ||
22 | #define LCD_TARGET_H | ||
23 | |||
24 | extern fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]; | ||
25 | |||
26 | #define LCD_FRAMEBUF_ADDR(col, row) (&lcd_driver_framebuffer[row][col]) | ||
27 | |||
28 | #endif /* LCD_TARGET_H */ | ||
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/lcd-creativezvm.c b/firmware/target/arm/tms320dm320/creative-zvm/lcd-creativezvm.c index c92920337b..e6d9e034ed 100644 --- a/firmware/target/arm/tms320dm320/creative-zvm/lcd-creativezvm.c +++ b/firmware/target/arm/tms320dm320/creative-zvm/lcd-creativezvm.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include "ltv350qv.h" | 33 | #include "ltv350qv.h" |
34 | 34 | ||
35 | /* Power and display status */ | 35 | /* Power and display status */ |
36 | static bool display_on = false; /* Is the display turned on? */ | 36 | extern bool lcd_on; /* lcd-memframe.c */ |
37 | static bool direct_fb_access = false; /* Does the DM320 has direct access to the FB? */ | 37 | static bool direct_fb_access = false; /* Does the DM320 has direct access to the FB? */ |
38 | 38 | ||
39 | /* Copies a rectangle from one framebuffer to another. Can be used in | 39 | /* Copies a rectangle from one framebuffer to another. Can be used in |
@@ -189,7 +189,7 @@ static void lcd_display_on(bool reset) | |||
189 | IO_VID_ENC_VMOD |= VENC_VMOD_VENC; | 189 | IO_VID_ENC_VMOD |= VENC_VMOD_VENC; |
190 | } | 190 | } |
191 | /* tell that we're on now */ | 191 | /* tell that we're on now */ |
192 | display_on = true; | 192 | lcd_on = true; |
193 | } | 193 | } |
194 | 194 | ||
195 | #ifdef HAVE_LCD_ENABLE | 195 | #ifdef HAVE_LCD_ENABLE |
@@ -224,14 +224,14 @@ static void lcd_display_off(void) | |||
224 | 224 | ||
225 | enable_venc(false); | 225 | enable_venc(false); |
226 | 226 | ||
227 | display_on = false; | 227 | lcd_on = false; |
228 | } | 228 | } |
229 | 229 | ||
230 | void lcd_enable(bool on) | 230 | void lcd_enable(bool on) |
231 | { | 231 | { |
232 | /* Disabled until properly working */ | 232 | /* Disabled until properly working */ |
233 | return; | 233 | return; |
234 | if (on == display_on) | 234 | if (on == lcd_on) |
235 | return; | 235 | return; |
236 | 236 | ||
237 | if (on) | 237 | if (on) |
@@ -247,13 +247,6 @@ return; | |||
247 | } | 247 | } |
248 | #endif | 248 | #endif |
249 | 249 | ||
250 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | ||
251 | bool lcd_active(void) | ||
252 | { | ||
253 | return display_on; | ||
254 | } | ||
255 | #endif | ||
256 | |||
257 | void lcd_set_direct_fb(bool yes) | 250 | void lcd_set_direct_fb(bool yes) |
258 | { | 251 | { |
259 | unsigned int addr; | 252 | unsigned int addr; |
@@ -323,7 +316,7 @@ void lcd_init_device(void) | |||
323 | DM320_REG(0x0864) = 0; /* ???? */ | 316 | DM320_REG(0x0864) = 0; /* ???? */ |
324 | } | 317 | } |
325 | else | 318 | else |
326 | display_on = true; | 319 | lcd_on = true; |
327 | 320 | ||
328 | /* Based on lcd-mr500.c from Catalin Patulea */ | 321 | /* Based on lcd-mr500.c from Catalin Patulea */ |
329 | /* Clear the Frame */ | 322 | /* Clear the Frame */ |
@@ -369,7 +362,7 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
369 | { | 362 | { |
370 | register fb_data *dst, *src; | 363 | register fb_data *dst, *src; |
371 | 364 | ||
372 | if (!display_on || direct_fb_access) | 365 | if (!lcd_on || direct_fb_access) |
373 | return; | 366 | return; |
374 | 367 | ||
375 | if (x + width > LCD_WIDTH) | 368 | if (x + width > LCD_WIDTH) |
@@ -424,7 +417,7 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
424 | This must be called after all other LCD functions that change the display. */ | 417 | This must be called after all other LCD functions that change the display. */ |
425 | void lcd_update(void) | 418 | void lcd_update(void) |
426 | { | 419 | { |
427 | if (!display_on || direct_fb_access) | 420 | if (!lcd_on || direct_fb_access) |
428 | return; | 421 | return; |
429 | #if CONFIG_ORIENTATION == SCREEN_PORTRAIT | 422 | #if CONFIG_ORIENTATION == SCREEN_PORTRAIT |
430 | lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0], | 423 | lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0], |
@@ -433,50 +426,3 @@ void lcd_update(void) | |||
433 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | 426 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); |
434 | #endif | 427 | #endif |
435 | } | 428 | } |
436 | |||
437 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
438 | extern void lcd_write_yuv420_lines(fb_data *dst, | ||
439 | unsigned char chroma_buf[LCD_HEIGHT/2*3], | ||
440 | unsigned char const * const src[3], | ||
441 | int width, | ||
442 | int stride); | ||
443 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
444 | /* For the Gigabeat - show it rotated */ | ||
445 | /* So the LCD_WIDTH is now the height */ | ||
446 | void lcd_blit_yuv(unsigned char * const src[3], | ||
447 | int src_x, int src_y, int stride, | ||
448 | int x, int y, int width, int height) | ||
449 | { | ||
450 | /* Caches for chroma data so it only need be recalculated every other | ||
451 | line */ | ||
452 | unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */ | ||
453 | unsigned char const * yuv_src[3]; | ||
454 | off_t z; | ||
455 | |||
456 | if (!display_on || direct_fb_access) | ||
457 | return; | ||
458 | |||
459 | /* Sorry, but width and height must be >= 2 or else */ | ||
460 | width &= ~1; | ||
461 | height >>= 1; | ||
462 | |||
463 | fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; | ||
464 | |||
465 | z = stride*src_y; | ||
466 | yuv_src[0] = src[0] + z + src_x; | ||
467 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | ||
468 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
469 | |||
470 | do | ||
471 | { | ||
472 | lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, | ||
473 | stride); | ||
474 | |||
475 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
476 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
477 | yuv_src[2] += stride >> 1; | ||
478 | dst -= 2; | ||
479 | } | ||
480 | while (--height > 0); | ||
481 | } | ||
482 | |||
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/lcd-target.h b/firmware/target/arm/tms320dm320/creative-zvm/lcd-target.h index 720aa0cf19..456f0e3cfe 100644 --- a/firmware/target/arm/tms320dm320/creative-zvm/lcd-target.h +++ b/firmware/target/arm/tms320dm320/creative-zvm/lcd-target.h | |||
@@ -19,12 +19,20 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #ifndef _LCD_TARGET_H_ | 22 | #ifndef LCD_TARGET_H |
23 | #define _LCD_TARGET_H_ | 23 | #define LCD_TARGET_H |
24 | |||
25 | extern void lcd_enable(bool state); | ||
26 | 24 | ||
27 | void lcd_set_direct_fb(bool yes); | 25 | void lcd_set_direct_fb(bool yes); |
28 | bool lcd_get_direct_fb(void); | 26 | bool lcd_get_direct_fb(void); |
29 | 27 | ||
30 | #endif | 28 | /* Direct FB access disables regular updates */ |
29 | #define lcd_write_enabled() \ | ||
30 | ({ lcd_on && !lcd_get_direct_fb(); }) | ||
31 | |||
32 | /* Very strange functions */ | ||
33 | #define LCD_OPTIMIZED_UPDATE | ||
34 | #define LCD_OPTIMIZED_UPDATE_RECT | ||
35 | |||
36 | #define LCD_FRAMEBUF_ADDR(col, row) ((fb_data *)FRAME + (row)*LCD_WIDTH + (col)) | ||
37 | |||
38 | #endif /* LCD_TARGET_H */ | ||
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c index 308b4297c2..ad417663fe 100644 --- a/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c +++ b/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c | |||
@@ -30,18 +30,7 @@ | |||
30 | #include "lcd-target.h" | 30 | #include "lcd-target.h" |
31 | #include "avr-sansaconnect.h" | 31 | #include "avr-sansaconnect.h" |
32 | 32 | ||
33 | /* Copies a rectangle from one framebuffer to another. Can be used in | 33 | extern bool lcd_on; /* lcd-memframe.c */ |
34 | single transfer mode with width = num pixels, and height = 1 which | ||
35 | allows a full-width rectangle to be copied more efficiently. */ | ||
36 | extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, | ||
37 | int width, int height); | ||
38 | |||
39 | static bool lcd_on = true; | ||
40 | |||
41 | bool lcd_active(void) | ||
42 | { | ||
43 | return lcd_on; | ||
44 | } | ||
45 | 34 | ||
46 | #if defined(HAVE_LCD_SLEEP) | 35 | #if defined(HAVE_LCD_SLEEP) |
47 | void lcd_sleep(void) | 36 | void lcd_sleep(void) |
@@ -49,6 +38,7 @@ void lcd_sleep(void) | |||
49 | if (lcd_on) | 38 | if (lcd_on) |
50 | { | 39 | { |
51 | lcd_on = false; | 40 | lcd_on = false; |
41 | |||
52 | avr_hid_lcm_sleep(); | 42 | avr_hid_lcm_sleep(); |
53 | sleep(HZ/20); | 43 | sleep(HZ/20); |
54 | 44 | ||
@@ -67,6 +57,7 @@ void lcd_awake(void) | |||
67 | if (!lcd_on) | 57 | if (!lcd_on) |
68 | { | 58 | { |
69 | lcd_on = true; | 59 | lcd_on = true; |
60 | |||
70 | /* enable video encoder clock */ | 61 | /* enable video encoder clock */ |
71 | bitset16(&IO_CLK_MOD1, CLK_MOD1_VENC); | 62 | bitset16(&IO_CLK_MOD1, CLK_MOD1_VENC); |
72 | 63 | ||
@@ -159,56 +150,7 @@ void lcd_init_device(void) | |||
159 | /* Enable Video Encoder - RGB666, custom timing */ | 150 | /* Enable Video Encoder - RGB666, custom timing */ |
160 | IO_VID_ENC_VMOD = 0x2011; | 151 | IO_VID_ENC_VMOD = 0x2011; |
161 | avr_hid_lcm_wake(); | 152 | avr_hid_lcm_wake(); |
162 | } | 153 | lcd_on = true; |
163 | |||
164 | /* Update a fraction of the display. */ | ||
165 | void lcd_update_rect(int x, int y, int width, int height) | ||
166 | __attribute__ ((section(".icode"))); | ||
167 | void lcd_update_rect(int x, int y, int width, int height) | ||
168 | { | ||
169 | register fb_data *dst, *src; | ||
170 | |||
171 | if (!lcd_on) | ||
172 | return; | ||
173 | |||
174 | if ((width | height) < 0) | ||
175 | return; /* Nothing left to do */ | ||
176 | |||
177 | if (x + width > LCD_WIDTH) | ||
178 | width = LCD_WIDTH - x; /* Clip right */ | ||
179 | if (x < 0) | ||
180 | width += x, x = 0; /* Clip left */ | ||
181 | |||
182 | if (y + height > LCD_HEIGHT) | ||
183 | height = LCD_HEIGHT - y; /* Clip bottom */ | ||
184 | if (y < 0) | ||
185 | height += y, y = 0; /* Clip top */ | ||
186 | |||
187 | dst = FRAME + LCD_WIDTH*y + x; | ||
188 | src = &lcd_framebuffer[y][x]; | ||
189 | |||
190 | /* Copy part of the Rockbox framebuffer to the second framebuffer */ | ||
191 | if (width < LCD_WIDTH) | ||
192 | { | ||
193 | /* Not full width - do line-by-line */ | ||
194 | lcd_copy_buffer_rect(dst, src, width, height); | ||
195 | } | ||
196 | else | ||
197 | { | ||
198 | /* Full width - copy as one line */ | ||
199 | lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | /* Update the display. | ||
204 | This must be called after all other LCD functions that change the display. */ | ||
205 | void lcd_update(void) __attribute__ ((section(".icode"))); | ||
206 | void lcd_update(void) | ||
207 | { | ||
208 | if (!lcd_on) | ||
209 | return; | ||
210 | |||
211 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | ||
212 | } | 154 | } |
213 | 155 | ||
214 | void lcd_set_contrast(int val) { | 156 | void lcd_set_contrast(int val) { |
@@ -225,48 +167,3 @@ void lcd_set_flip(bool yesno) { | |||
225 | (void) yesno; | 167 | (void) yesno; |
226 | // TODO: | 168 | // TODO: |
227 | } | 169 | } |
228 | |||
229 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
230 | extern void lcd_write_yuv420_lines(fb_data *dst, | ||
231 | unsigned char chroma_buf[LCD_HEIGHT/2*3], | ||
232 | unsigned char const * const src[3], | ||
233 | int width, int stride); | ||
234 | |||
235 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
236 | void lcd_blit_yuv(unsigned char * const src[3], | ||
237 | int src_x, int src_y, int stride, | ||
238 | int x, int y, int width, int height) | ||
239 | { | ||
240 | /* Caches for chroma data so it only need be recalculated every other | ||
241 | line */ | ||
242 | unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */ | ||
243 | unsigned char const * yuv_src[3]; | ||
244 | off_t z; | ||
245 | |||
246 | if (!lcd_on) | ||
247 | return; | ||
248 | |||
249 | /* Sorry, but width and height must be >= 2 or else */ | ||
250 | width &= ~1; | ||
251 | height >>= 1; | ||
252 | |||
253 | fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; | ||
254 | |||
255 | z = stride*src_y; | ||
256 | yuv_src[0] = src[0] + z + src_x; | ||
257 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | ||
258 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
259 | |||
260 | do | ||
261 | { | ||
262 | lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, | ||
263 | stride); | ||
264 | |||
265 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
266 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
267 | yuv_src[2] += stride >> 1; | ||
268 | dst -= 2; | ||
269 | } | ||
270 | while (--height > 0); | ||
271 | } | ||
272 | |||
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h b/firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h index da82c8fe7d..60d5df69c8 100644 --- a/firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h +++ b/firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h | |||
@@ -19,9 +19,11 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #ifndef _LCD_TARGET_H_ | 22 | #ifndef LCD_TARGET_H |
23 | #define _LCD_TARGET_H_ | 23 | #define LCD_TARGET_H |
24 | |||
25 | #define LCD_FRAMEBUF_ADDR(col, row) ((fb_data *)FRAME + (row)*LCD_WIDTH + (col)) | ||
24 | 26 | ||
25 | void lcd_awake(void); | 27 | void lcd_awake(void); |
26 | 28 | ||
27 | #endif | 29 | #endif /* LCD_TARGET_H */ |