From 95e6043d5e256df72c20db39c3be59a3ba977b19 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Fri, 16 Dec 2011 23:40:39 +0000 Subject: Convert remaining memframe LCDs that can be convert to common code. Massage the way it interfaces a bit to make things more flexible. The chroma_buf scheme on Sansa Connect and Creative ZVx calling the lcd_write_yuv420_lines implementation in lcd-as-memframe.S with five params with a chroma buffer that the function can't use wouldn't work anyway so just have them use the stock implementation (really, how was that working?). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31335 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 5 +- firmware/drivers/lcd-memframe.c | 73 +++++++--- firmware/export/lcd.h | 9 ++ .../arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c | 87 +----------- .../target/arm/imx233/sansa-fuzeplus/lcd-target.h | 30 +++++ .../target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c | 17 +-- firmware/target/arm/s3c2440/lcd-s3c2440.c | 30 +++-- firmware/target/arm/sandisk/sansa-e200/lcd-e200.c | 19 ++- firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c | 147 +-------------------- firmware/target/arm/tcc780x/cowond2/lcd-target.h | 28 ++++ .../arm/tms320dm320/creative-zvm/lcd-creativezvm.c | 68 +--------- .../arm/tms320dm320/creative-zvm/lcd-target.h | 18 ++- .../tms320dm320/sansa-connect/lcd-sansaconnect.c | 111 +--------------- .../arm/tms320dm320/sansa-connect/lcd-target.h | 8 +- 14 files changed, 197 insertions(+), 453 deletions(-) create mode 100644 firmware/target/arm/imx233/sansa-fuzeplus/lcd-target.h create mode 100644 firmware/target/arm/tcc780x/cowond2/lcd-target.h diff --git a/firmware/SOURCES b/firmware/SOURCES index 7f9f3319ad..85e6fe3757 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -856,7 +856,6 @@ target/arm/sandisk/sansa-c200/powermgmt-c200.c #endif /* SANSA_C200 */ #ifdef SANSA_VIEW -target/arm/lcd-as-memframe.S target/arm/sandisk/sansa-view/backlight-view.c target/arm/sandisk/sansa-view/adc-view.c target/arm/sandisk/sansa-view/power-view.c @@ -1113,6 +1112,7 @@ target/arm/tms320dm320/mrobe-500/usb-mr500.c #endif /* MROBE_500 */ #ifdef CREATIVE_ZVx +drivers/lcd-memframe.c target/arm/lcd-as-memframe.S target/arm/tms320dm320/creative-zvm/adc-creativezvm.c target/arm/tms320dm320/creative-zvm/ata-creativezvm.c @@ -1126,6 +1126,7 @@ target/arm/tms320dm320/creative-zvm/usb-creativezvm.c #endif /* CREATIVE_ZVx */ #ifdef SANSA_CONNECT +drivers/lcd-memframe.c target/arm/lcd-as-memframe.S target/arm/tms320dm320/sdmmc-dm320.c target/arm/tms320dm320/sansa-connect/crt0-board.S @@ -1332,6 +1333,7 @@ target/arm/as3525/lcd-as-e200v2-fuze-fuzev2.S #endif /* SANSA_FUZEV2 */ #ifdef SANSA_FUZEPLUS +drivers/lcd-memframe.c drivers/synaptics-rmi.c drivers/generic_i2c.c target/arm/lcd-as-memframe.S @@ -1370,6 +1372,7 @@ target/arm/tcc77x/iaudio7/audio-iaudio7.c #endif /* IAUDIO_7 */ #ifdef COWON_D2 +drivers/lcd-memframe.c drivers/nand_id.c drivers/pcf50606.c drivers/pcf50635.c diff --git a/firmware/drivers/lcd-memframe.c b/firmware/drivers/lcd-memframe.c index 304f0a7e9e..dd878876bf 100644 --- a/firmware/drivers/lcd-memframe.c +++ b/firmware/drivers/lcd-memframe.c @@ -20,20 +20,15 @@ * KIND, either express or implied. * ****************************************************************************/ -#include /* off_t */ #include "config.h" #include "system.h" #include "lcd.h" #include "lcd-target.h" /*** Misc. functions ***/ +bool lcd_on SHAREDBSS_ATTR = false; #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) -static bool lcd_on SHAREDBSS_ATTR = false; /* Is the display turned on? */ -#else -static bool lcd_on SHAREDBSS_ATTR = true; /* Is the display turned on? */ -#endif - bool lcd_active(void) { return lcd_on; @@ -45,6 +40,15 @@ void lcd_set_active(bool active) lcd_on = active; } +#else +#define lcd_on true +#endif + +#ifndef lcd_write_enabled +#define lcd_write_enabled() lcd_on +#endif + + /*** Blitting functions ***/ /* Copies a rectangle from one framebuffer to another. Can be used in @@ -53,23 +57,27 @@ void lcd_set_active(bool active) extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, int width, int height); +#ifndef LCD_OPTIMIZED_UPDATE /* Update the display. This must be called after all other LCD functions that change the display. */ void lcd_update(void) { - if (!lcd_on) + if (!lcd_write_enabled()) return; /* Copy the Rockbox framebuffer to the second framebuffer */ lcd_copy_buffer_rect(LCD_FRAMEBUF_ADDR(0, 0), &lcd_framebuffer[0][0], LCD_WIDTH*LCD_HEIGHT, 1); } +#endif /* LCD_OPTIMIZED_UPDATE */ +#ifndef LCD_OPTIMIZED_UPDATE_RECT +/* Update a fraction of the display. */ void lcd_update_rect(int x, int y, int width, int height) { fb_data *dst, *src; - if (!lcd_on) + if (!lcd_write_enabled()) return; if (x + width > LCD_WIDTH) @@ -101,6 +109,7 @@ void lcd_update_rect(int x, int y, int width, int height) lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); } } +#endif /* LCD_OPTIMIZED_UPDATE_RECT */ /*** YUV functions ***/ @@ -124,27 +133,50 @@ void lcd_yuv_set_options(unsigned options) lcd_yuv_options = options; } -/* Performance function to blit a YUV bitmap directly to the LCD */ -/* For the e200 - show it rotated */ -/* So the LCD_WIDTH is now the height */ +#ifndef LCD_OPTIMIZED_BLIT_YUV +/* Performance function to blit a YUV bitmap directly to the LCD + * src_x, src_y, width and height should be even and within the LCD's + * boundaries. + * + * For portrait LCDs, show it rotated counterclockwise by 90 degrees + */ void lcd_blit_yuv(unsigned char * const src[3], int src_x, int src_y, int stride, int x, int y, int width, int height) { - unsigned char const * yuv_src[3]; - off_t z; + /* Macrofy the bits that change between orientations */ +#if CONFIG_ORIENTATION == SCREEN_PORTRAIT + #define LCD_FRAMEBUF_ADDR_ORIENTED(col, row) \ + LCD_FRAMEBUF_ADDR(row, col) + #define lcd_write_yuv420_lines_odither_oriented(dst, src, w, s, col, row) \ + lcd_write_yuv420_lines_odither(dst, src, w, s, row, col) + #define YUV_NEXTLINE() dst -= 2 + #define YUV_DITHER_NEXTLINE() dst -= 2, y -= 2 +#else + #define LCD_FRAMEBUF_ADDR_ORIENTED(col, row) \ + LCD_FRAMEBUF_ADDR(col, row) + #define lcd_write_yuv420_lines_odither_oriented(dst, src, w, s, col, row) \ + lcd_write_yuv420_lines_odither(dst, src, w, s, col, row) + #define YUV_NEXTLINE() dst += 2*LCD_FBWIDTH + #define YUV_DITHER_NEXTLINE() dst += 2*LCD_FBWIDTH, y += 2 +#endif - if (!lcd_on) + if (!lcd_write_enabled()) return; /* Sorry, but width and height must be >= 2 or else */ width &= ~1; height >>= 1; +#if CONFIG_ORIENTATION == SCREEN_PORTRAIT + /* Adjust portrait coordinates to make (0, 0) the upper right corner */ y = LCD_WIDTH - 1 - y; - fb_data *dst = LCD_FRAMEBUF_ADDR(y, x); +#endif - z = stride*src_y; + fb_data *dst = LCD_FRAMEBUF_ADDR_ORIENTED(x, y); + int z = stride*src_y; + + unsigned char const * yuv_src[3]; yuv_src[0] = src[0] + z + src_x; yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); yuv_src[2] = src[2] + (yuv_src[1] - src[1]); @@ -153,12 +185,12 @@ void lcd_blit_yuv(unsigned char * const src[3], { do { - lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); + lcd_write_yuv420_lines_odither_oriented(dst, yuv_src, width, + stride, x, y); yuv_src[0] += stride << 1; /* Skip down two luma lines */ yuv_src[1] += stride >> 1; /* Skip down one chroma line */ yuv_src[2] += stride >> 1; - dst -= 2; - y -= 2; + YUV_DITHER_NEXTLINE(); } while (--height > 0); } @@ -170,8 +202,9 @@ void lcd_blit_yuv(unsigned char * const src[3], yuv_src[0] += stride << 1; /* Skip down two luma lines */ yuv_src[1] += stride >> 1; /* Skip down one chroma line */ yuv_src[2] += stride >> 1; - dst -= 2; + YUV_NEXTLINE(); } while (--height > 0); } } +#endif /* LCD_OPTIMIZED_BLIT_YUV */ diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 2d0123cfe3..abe5f74ee1 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -442,6 +442,15 @@ enum { }; extern bool lcd_active(void); + +/* Set the active flag - to be called by target drivers only! */ +extern void lcd_set_active(bool active); +#else +/* NULL versions for no sleeping */ +static inline bool lcd_active(void) + { return true; } +static inline void lcd_set_active(bool active) + { (void)active; } #endif #ifdef HAVE_LCD_SHUTDOWN 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 @@ #include "pinctrl-imx233.h" #include "logf.h" +extern bool lcd_on; /* lcd-memframe.c */ + /* Copies a rectangle from one framebuffer to another. Can be used in single transfer mode with width = num pixels, and height = 1 which allows a full-width rectangle to be copied more efficiently. */ extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, int width, int height); -static unsigned lcd_yuv_options = 0; - -#ifdef HAVE_LCD_ENABLE -static bool lcd_on = true; -#endif - static enum lcd_kind_t { LCD_KIND_7783 = 0x7783, @@ -386,6 +382,8 @@ void lcd_init_device(void) lcd_kind = LCD_KIND_7783; lcd_init_seq_7783(); break; } + + lcd_on = true; } #ifdef HAVE_LCD_ENABLE @@ -469,6 +467,7 @@ void lcd_enable(bool enable) { if(lcd_on == enable) return; + lcd_on = enable; if(enable) @@ -482,11 +481,6 @@ void lcd_enable(bool enable) if(!enable) common_lcd_enable(false); } - -bool lcd_active(void) -{ - return lcd_on; -} #endif void lcd_update(void) @@ -520,74 +514,3 @@ void lcd_update_rect(int x, int y, int width, int height) (void) height; lcd_update(); } - -void lcd_yuv_set_options(unsigned options) -{ - lcd_yuv_options = options; -} - -/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ -extern void lcd_write_yuv420_lines(fb_data *dst, - unsigned char const * const src[3], - int width, - int stride); -extern void lcd_write_yuv420_lines_odither(fb_data *dst, - unsigned char const * const src[3], - int width, - int stride, - int x_screen, /* To align dither pattern */ - int y_screen); -/* Performance function to blit a YUV bitmap directly to the LCD */ -/* So the LCD_WIDTH is now the height */ -void lcd_blit_yuv(unsigned char * const src[3], - int src_x, int src_y, int stride, - int x, int y, int width, int height) -{ - /* Caches for chroma data so it only need be recaculated every other - line */ - unsigned char const * yuv_src[3]; - off_t z; - -#ifdef HAVE_LCD_ENABLE - if (!lcd_on) - return; -#endif - - /* Sorry, but width and height must be >= 2 or else */ - width &= ~1; - height >>= 1; - - y = LCD_WIDTH - 1 - y; - fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + y; - - z = stride*src_y; - yuv_src[0] = src[0] + z + src_x; - yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); - yuv_src[2] = src[2] + (yuv_src[1] - src[1]); - - if (lcd_yuv_options & LCD_YUV_DITHER) - { - do - { - lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); - yuv_src[0] += stride << 1; /* Skip down two luma lines */ - yuv_src[1] += stride >> 1; /* Skip down one chroma line */ - yuv_src[2] += stride >> 1; - dst -= 2; - y -= 2; - } - while (--height > 0); - } - else - { - do - { - lcd_write_yuv420_lines(dst, yuv_src, width, stride); - yuv_src[0] += stride << 1; /* Skip down two luma lines */ - yuv_src[1] += stride >> 1; /* Skip down one chroma line */ - yuv_src[2] += stride >> 1; - dst -= 2; - } - while (--height > 0); - } -} 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 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (c) 2011 by Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef LCD_TARGET_H +#define LCD_TARGET_H + +#define LCD_FRAMEBUF_ADDR(col, row) ((fb_data *)FRAME + (row)*LCD_WIDTH + (col)) + +/* Not really optimized, but are unusual */ +#define LCD_OPTIMIZED_UPDATE +#define LCD_OPTIMIZED_UPDATE_RECT + +#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 @@ #include "spi-imx31.h" #include "mc13783.h" -extern void lcd_set_active(bool active); - #define MAIN_LCD_IDMAC_CHANNEL 14 +extern bool lcd_on; /* lcd-memframe.c */ static bool lcd_powered = true; /* Settings shadow regs */ @@ -171,6 +170,8 @@ void INIT_ATTR lcd_init_device(void) IPU_IPU_IMA_ADDR = ((0x1 << 16) | (MAIN_LCD_IDMAC_CHANNEL << 4)) + (1 << 3); IPU_IPU_IMA_DATA = FRAME_PHYS_ADDR; + lcd_on = true; + lcd_enable_interface(true); lcd_sync_settings(); } @@ -188,7 +189,7 @@ void lcd_sleep(void) void lcd_enable(bool state) { - if (state == lcd_active()) + if (state == lcd_on) return; if (state) @@ -198,13 +199,13 @@ void lcd_enable(bool state) IPU_IDMAC_CHA_EN |= 1ul << MAIN_LCD_IDMAC_CHANNEL; lcd_sync_settings(); sleep(HZ/50); - lcd_set_active(true); + lcd_on = true; lcd_update(); send_event(LCD_EVENT_ACTIVATION, NULL); } else { - lcd_set_active(false); + lcd_on = false; } } @@ -213,7 +214,7 @@ void lcd_set_contrast(int val) { reg0x0b = val & 0x3f; - if (!lcd_active()) + if (!lcd_on) return; lcd_write_reg(0x0b, reg0x0b); @@ -230,7 +231,7 @@ void lcd_set_invert_display(bool yesno) { reg0x27 = yesno ? 0x10 : 0x00; - if (!lcd_active()) + if (!lcd_on) return; lcd_write_reg(0x27, reg0x27); @@ -242,7 +243,7 @@ void lcd_set_flip(bool yesno) { reg0x06 = yesno ? 0x02 : 0x04; - if (!lcd_active()) + if (!lcd_on) return; 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 @@ #include "lcd.h" #include "lcd-target.h" -extern bool lcd_active(void); -extern void lcd_set_active(bool active); +extern bool lcd_on; /* lcd-memframe.c */ #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) static bool lcd_powered = true; @@ -242,6 +241,8 @@ void lcd_init_device(void) #else LCD_CTRL_clock(true); #endif + + lcd_on = true; } #if defined(HAVE_LCD_SLEEP) @@ -262,9 +263,7 @@ void lcd_sleep(void) if (lcd_powered) { /* "not powered" implies "disabled" */ - if (!lcd_active()) - lcd_enable(false); - + lcd_enable(false); LCD_SPI_powerdown(); } } @@ -284,7 +283,7 @@ static void LCD_SPI_powerup(void) void lcd_enable(bool state) { - if (state == lcd_active()) + if (state == lcd_on) return; if(state) @@ -298,20 +297,21 @@ void lcd_enable(bool state) sleep(HZ/5); } - lcd_set_active(true); + lcd_on = true; lcd_update(); send_event(LCD_EVENT_ACTIVATION, NULL); } else { - lcd_set_active(false); + lcd_on = false; } } #endif #ifdef GIGABEAT_F -void lcd_set_flip(bool yesno) { - if (!lcd_active()) +void lcd_set_flip(bool yesno) +{ + if (!lcd_on) return; LCD_SPI_start(); @@ -331,8 +331,9 @@ int lcd_default_contrast(void) return DEFAULT_CONTRAST_SETTING; } -void lcd_set_contrast(int val) { - if (!lcd_active()) +void lcd_set_contrast(int val) +{ + if (!lcd_on) return; LCD_SPI_start(); @@ -340,8 +341,9 @@ void lcd_set_contrast(int val) { LCD_SPI_stop(); } -void lcd_set_invert_display(bool yesno) { - if (!lcd_active()) +void lcd_set_invert_display(bool yesno) +{ + if (!lcd_on) return; 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 @@ #include "lcd.h" #include "lcd-target.h" -extern bool lcd_active(void); -extern void lcd_set_active(bool active); - /* Power and display status */ -static bool power_on = false; /* Is the power turned on? */ +extern bool lcd_on; /* lcd-memframe.c */ +static bool power_on = false; /* Is the power turned on? */ /* Reverse Flag */ #define R_DISP_CONTROL_NORMAL 0x0004 @@ -309,7 +307,7 @@ static void lcd_display_on(void) lcd_send_msg(0x70, R_RAM_WRITE_DATA); /* tell that we're on now */ - lcd_set_active(true); + lcd_on = true; } @@ -318,7 +316,7 @@ static void lcd_display_on(void) static void lcd_display_off(void) { /* block drawing operations and changing of first */ - lcd_set_active(false); + lcd_on = false; /* NO2-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-0=0000 */ lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x4000); @@ -422,7 +420,7 @@ void lcd_init_device(void) LCD_FB_BASE_REG = (long)lcd_driver_framebuffer; power_on = true; - lcd_set_active(true); + lcd_on = true; lcd_set_invert_display(false); lcd_set_flip(false); @@ -434,7 +432,7 @@ void lcd_init_device(void) #if defined(HAVE_LCD_ENABLE) void lcd_enable(bool on) { - if (on == lcd_active()) + if (on == lcd_on) return; if (on) @@ -465,9 +463,8 @@ void lcd_sleep(void) if (power_on) { /* Turn off display */ - if (lcd_active()) + if (lcd_on) lcd_display_off(); - power_on = false; } @@ -499,7 +496,7 @@ void lcd_set_invert_display(bool yesno) r_disp_control_rev = yesno ? R_DISP_CONTROL_REV : R_DISP_CONTROL_NORMAL; - if (lcd_active()) + if (lcd_on) { /* PT1-0=00, VLE2-1=00, SPT=0, IB6(??)=1, GON=1, CL=0, 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 @@ #include "hwcompat.h" #include "kernel.h" #include "lcd.h" +#include "lcd-target.h" #include "system.h" #include "cpu.h" +extern bool lcd_on; /* lcd-memframe.c */ + /* GPIO A pins for LCD panel SDI interface */ #define LTV250QV_CS (1<<24) @@ -51,11 +54,6 @@ #define LCDC_I1OFF (*(volatile unsigned long *)0xF00000A8) #define LCDC_I1SCALE (*(volatile unsigned long *)0xF00000AC) -/* Power and display status */ -static bool display_on = false; /* Is the display turned on? */ - -static unsigned lcd_yuv_options = 0; - /* Framebuffer copy as seen by the hardware */ fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]; @@ -180,13 +178,13 @@ static void lcd_display_on(void) udelay(10000); /* tell that we're on now */ - display_on = true; + lcd_on = true; } static void lcd_display_off(void) { /* block drawing operations and changing of first */ - display_on = false; + lcd_on = false; /* LQV shutdown sequence */ lcd_write_reg(9, 0x55); @@ -204,7 +202,7 @@ static void lcd_display_off(void) void lcd_enable(bool on) { - if (on == display_on) + if (on == lcd_on) return; if (on) @@ -221,11 +219,6 @@ void lcd_enable(bool on) } } -bool lcd_active(void) -{ - return display_on; -} - /* TODO: implement lcd_sleep() and separate out the power on/off functions */ void lcd_init_device(void) @@ -278,67 +271,6 @@ void lcd_init_device(void) /*** Update functions ***/ - - -/* Copies a rectangle from one framebuffer to another. Can be used in - single transfer mode with width = num pixels, and height = 1 which - allows a full-width rectangle to be copied more efficiently. */ -extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, - int width, int height); - -/* Update the display. - This must be called after all other LCD functions that change the display. */ -void lcd_update(void) ICODE_ATTR; -void lcd_update(void) -{ - if (!display_on) - return; - - lcd_copy_buffer_rect(&lcd_driver_framebuffer[0][0], - &lcd_framebuffer[0][0], LCD_WIDTH*LCD_HEIGHT, 1); -} - -/* Update a fraction of the display. */ -void lcd_update_rect(int, int, int, int) ICODE_ATTR; -void lcd_update_rect(int x, int y, int width, int height) -{ - fb_data *dst, *src; - - if (!display_on) - return; - - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; /* Clip right */ - if (x < 0) - width += x, x = 0; /* Clip left */ - if (width <= 0) - return; /* nothing left to do */ - - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; /* Clip bottom */ - if (y < 0) - height += y, y = 0; /* Clip top */ - if (height <= 0) - return; /* nothing left to do */ - - /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer - * and lcd_framebuffer */ - dst = &lcd_driver_framebuffer[y][x]; - src = &lcd_framebuffer[y][x]; - - /* Copy part of the Rockbox framebuffer to the second framebuffer */ - if (width < LCD_WIDTH) - { - /* Not full width - do line-by-line */ - lcd_copy_buffer_rect(dst, src, width, height); - } - else - { - /* Full width - copy as one line */ - lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); - } -} - void lcd_set_flip(bool yesno) { // TODO @@ -350,70 +282,3 @@ void lcd_set_invert_display(bool yesno) // TODO (void)yesno; } - -void lcd_yuv_set_options(unsigned options) -{ - lcd_yuv_options = options; -} - -/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ -extern void lcd_write_yuv420_lines(fb_data *dst, - unsigned char const * const src[3], - int width, - int stride); - -extern void lcd_write_yuv420_lines_odither(fb_data *dst, - unsigned char const * const src[3], - int width, - int stride, - int x_screen, /* To align dither pattern */ - int y_screen); - -/* Performance function to blit a YUV bitmap directly to the LCD */ -void lcd_blit_yuv(unsigned char * const src[3], - int src_x, int src_y, int stride, - int x, int y, int width, int height) -{ - unsigned char const * yuv_src[3]; - off_t z; - - if (!display_on) - return; - - /* Sorry, but width and height must be >= 2 or else */ - width &= ~1; - height >>= 1; - - fb_data *dst = &lcd_driver_framebuffer[y][x]; - - z = stride*src_y; - yuv_src[0] = src[0] + z + src_x; - yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); - yuv_src[2] = src[2] + (yuv_src[1] - src[1]); - - if (lcd_yuv_options & LCD_YUV_DITHER) - { - do - { - lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x); - yuv_src[0] += stride << 1; /* Skip down two luma lines */ - yuv_src[1] += stride >> 1; /* Skip down one chroma line */ - yuv_src[2] += stride >> 1; - dst += 2*LCD_FBWIDTH; - y -= 2; - } - while (--height > 0); - } - else - { - do - { - lcd_write_yuv420_lines(dst, yuv_src, width, stride); - yuv_src[0] += stride << 1; /* Skip down two luma lines */ - yuv_src[1] += stride >> 1; /* Skip down one chroma line */ - yuv_src[2] += stride >> 1; - dst += 2*LCD_FBWIDTH; - } - while (--height > 0); - } -} 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 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Rob Purchase + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef LCD_TARGET_H +#define LCD_TARGET_H + +extern fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]; + +#define LCD_FRAMEBUF_ADDR(col, row) (&lcd_driver_framebuffer[row][col]) + +#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 @@ #include "ltv350qv.h" /* Power and display status */ -static bool display_on = false; /* Is the display turned on? */ +extern bool lcd_on; /* lcd-memframe.c */ static bool direct_fb_access = false; /* Does the DM320 has direct access to the FB? */ /* Copies a rectangle from one framebuffer to another. Can be used in @@ -189,7 +189,7 @@ static void lcd_display_on(bool reset) IO_VID_ENC_VMOD |= VENC_VMOD_VENC; } /* tell that we're on now */ - display_on = true; + lcd_on = true; } #ifdef HAVE_LCD_ENABLE @@ -224,14 +224,14 @@ static void lcd_display_off(void) enable_venc(false); - display_on = false; + lcd_on = false; } void lcd_enable(bool on) { /* Disabled until properly working */ return; - if (on == display_on) + if (on == lcd_on) return; if (on) @@ -247,13 +247,6 @@ return; } #endif -#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) -bool lcd_active(void) -{ - return display_on; -} -#endif - void lcd_set_direct_fb(bool yes) { unsigned int addr; @@ -323,7 +316,7 @@ void lcd_init_device(void) DM320_REG(0x0864) = 0; /* ???? */ } else - display_on = true; + lcd_on = true; /* Based on lcd-mr500.c from Catalin Patulea */ /* Clear the Frame */ @@ -369,7 +362,7 @@ void lcd_update_rect(int x, int y, int width, int height) { register fb_data *dst, *src; - if (!display_on || direct_fb_access) + if (!lcd_on || direct_fb_access) return; if (x + width > LCD_WIDTH) @@ -424,7 +417,7 @@ void lcd_update_rect(int x, int y, int width, int height) This must be called after all other LCD functions that change the display. */ void lcd_update(void) { - if (!display_on || direct_fb_access) + if (!lcd_on || direct_fb_access) return; #if CONFIG_ORIENTATION == SCREEN_PORTRAIT lcd_copy_buffer_rect((fb_data *)FRAME, &lcd_framebuffer[0][0], @@ -433,50 +426,3 @@ void lcd_update(void) lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); #endif } - -/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ -extern void lcd_write_yuv420_lines(fb_data *dst, -unsigned char chroma_buf[LCD_HEIGHT/2*3], -unsigned char const * const src[3], -int width, -int stride); -/* Performance function to blit a YUV bitmap directly to the LCD */ -/* For the Gigabeat - show it rotated */ -/* So the LCD_WIDTH is now the height */ -void lcd_blit_yuv(unsigned char * const src[3], - int src_x, int src_y, int stride, - int x, int y, int width, int height) -{ - /* Caches for chroma data so it only need be recalculated every other - line */ - unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */ - unsigned char const * yuv_src[3]; - off_t z; - - if (!display_on || direct_fb_access) - return; - - /* Sorry, but width and height must be >= 2 or else */ - width &= ~1; - height >>= 1; - - fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; - - z = stride*src_y; - yuv_src[0] = src[0] + z + src_x; - yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); - yuv_src[2] = src[2] + (yuv_src[1] - src[1]); - - do - { - lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, - stride); - - yuv_src[0] += stride << 1; /* Skip down two luma lines */ - yuv_src[1] += stride >> 1; /* Skip down one chroma line */ - yuv_src[2] += stride >> 1; - dst -= 2; - } - while (--height > 0); -} - 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 @@ * ****************************************************************************/ -#ifndef _LCD_TARGET_H_ -#define _LCD_TARGET_H_ - -extern void lcd_enable(bool state); +#ifndef LCD_TARGET_H +#define LCD_TARGET_H void lcd_set_direct_fb(bool yes); bool lcd_get_direct_fb(void); -#endif +/* Direct FB access disables regular updates */ +#define lcd_write_enabled() \ + ({ lcd_on && !lcd_get_direct_fb(); }) + +/* Very strange functions */ +#define LCD_OPTIMIZED_UPDATE +#define LCD_OPTIMIZED_UPDATE_RECT + +#define LCD_FRAMEBUF_ADDR(col, row) ((fb_data *)FRAME + (row)*LCD_WIDTH + (col)) + +#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 @@ #include "lcd-target.h" #include "avr-sansaconnect.h" -/* Copies a rectangle from one framebuffer to another. Can be used in - single transfer mode with width = num pixels, and height = 1 which - allows a full-width rectangle to be copied more efficiently. */ -extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, - int width, int height); - -static bool lcd_on = true; - -bool lcd_active(void) -{ - return lcd_on; -} +extern bool lcd_on; /* lcd-memframe.c */ #if defined(HAVE_LCD_SLEEP) void lcd_sleep(void) @@ -49,6 +38,7 @@ void lcd_sleep(void) if (lcd_on) { lcd_on = false; + avr_hid_lcm_sleep(); sleep(HZ/20); @@ -67,6 +57,7 @@ void lcd_awake(void) if (!lcd_on) { lcd_on = true; + /* enable video encoder clock */ bitset16(&IO_CLK_MOD1, CLK_MOD1_VENC); @@ -159,56 +150,7 @@ void lcd_init_device(void) /* Enable Video Encoder - RGB666, custom timing */ IO_VID_ENC_VMOD = 0x2011; avr_hid_lcm_wake(); -} - -/* Update a fraction of the display. */ -void lcd_update_rect(int x, int y, int width, int height) - __attribute__ ((section(".icode"))); -void lcd_update_rect(int x, int y, int width, int height) -{ - register fb_data *dst, *src; - - if (!lcd_on) - return; - - if ((width | height) < 0) - return; /* Nothing left to do */ - - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; /* Clip right */ - if (x < 0) - width += x, x = 0; /* Clip left */ - - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; /* Clip bottom */ - if (y < 0) - height += y, y = 0; /* Clip top */ - - dst = FRAME + LCD_WIDTH*y + x; - src = &lcd_framebuffer[y][x]; - - /* Copy part of the Rockbox framebuffer to the second framebuffer */ - if (width < LCD_WIDTH) - { - /* Not full width - do line-by-line */ - lcd_copy_buffer_rect(dst, src, width, height); - } - else - { - /* Full width - copy as one line */ - lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); - } -} - -/* Update the display. - This must be called after all other LCD functions that change the display. */ -void lcd_update(void) __attribute__ ((section(".icode"))); -void lcd_update(void) -{ - if (!lcd_on) - return; - - lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); + lcd_on = true; } void lcd_set_contrast(int val) { @@ -225,48 +167,3 @@ void lcd_set_flip(bool yesno) { (void) yesno; // TODO: } - -/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ -extern void lcd_write_yuv420_lines(fb_data *dst, - unsigned char chroma_buf[LCD_HEIGHT/2*3], - unsigned char const * const src[3], - int width, int stride); - -/* Performance function to blit a YUV bitmap directly to the LCD */ -void lcd_blit_yuv(unsigned char * const src[3], - int src_x, int src_y, int stride, - int x, int y, int width, int height) -{ - /* Caches for chroma data so it only need be recalculated every other - line */ - unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */ - unsigned char const * yuv_src[3]; - off_t z; - - if (!lcd_on) - return; - - /* Sorry, but width and height must be >= 2 or else */ - width &= ~1; - height >>= 1; - - fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; - - z = stride*src_y; - yuv_src[0] = src[0] + z + src_x; - yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); - yuv_src[2] = src[2] + (yuv_src[1] - src[1]); - - do - { - lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, - stride); - - yuv_src[0] += stride << 1; /* Skip down two luma lines */ - yuv_src[1] += stride >> 1; /* Skip down one chroma line */ - yuv_src[2] += stride >> 1; - dst -= 2; - } - while (--height > 0); -} - 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 @@ * ****************************************************************************/ -#ifndef _LCD_TARGET_H_ -#define _LCD_TARGET_H_ +#ifndef LCD_TARGET_H +#define LCD_TARGET_H + +#define LCD_FRAMEBUF_ADDR(col, row) ((fb_data *)FRAME + (row)*LCD_WIDTH + (col)) void lcd_awake(void); -#endif +#endif /* LCD_TARGET_H */ -- cgit v1.2.3