From 6921a2b6b988e40fed1c2c3c5182381c26ef3d75 Mon Sep 17 00:00:00 2001 From: Rafaël Carré Date: Thu, 27 May 2010 23:32:38 +0000 Subject: Merge common LCD code between fuzev1 & fuzev2 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26344 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 4 +- firmware/target/arm/as3525/lcd-fuze.c | 338 +++++++++++++++ firmware/target/arm/as3525/lcd-fuze.h | 56 +++ firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c | 452 --------------------- firmware/target/arm/as3525/sansa-fuze/lcd-fuzev1.c | 88 ++++ .../target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c | 394 +----------------- 6 files changed, 503 insertions(+), 829 deletions(-) create mode 100644 firmware/target/arm/as3525/lcd-fuze.c create mode 100644 firmware/target/arm/as3525/lcd-fuze.h delete mode 100644 firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c create mode 100644 firmware/target/arm/as3525/sansa-fuze/lcd-fuzev1.c diff --git a/firmware/SOURCES b/firmware/SOURCES index 6a66efcdb6..3012314ac2 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1322,7 +1322,8 @@ target/arm/as3525/sansa-m200v4/powermgmt-m200v4.c #ifdef SANSA_FUZE #ifndef SIMULATOR target/arm/as3525/button-e200v2-fuze.c -target/arm/as3525/sansa-fuze/lcd-fuze.c +target/arm/as3525/lcd-fuze.c +target/arm/as3525/sansa-fuze/lcd-fuzev1.c target/arm/as3525/backlight-e200v2-fuze.c target/arm/as3525/dbop-as3525.c #ifndef BOOTLOADER @@ -1335,6 +1336,7 @@ target/arm/as3525/lcd-as-e200v2-fuze-fuzev2.S #ifdef SANSA_FUZEV2 #ifndef SIMULATOR +target/arm/as3525/lcd-fuze.c target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c target/arm/as3525/sansa-fuzev2/backlight-fuzev2.c target/arm/as3525/sansa-fuzev2/button-fuzev2.c diff --git a/firmware/target/arm/as3525/lcd-fuze.c b/firmware/target/arm/as3525/lcd-fuze.c new file mode 100644 index 0000000000..ef4791e6eb --- /dev/null +++ b/firmware/target/arm/as3525/lcd-fuze.c @@ -0,0 +1,338 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Dave Chapman + * + * LCD driver for the Sansa Fuze - controller unknown + * + * 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. + * + ****************************************************************************/ +#include "config.h" + +#include "cpu.h" +#include "lcd.h" +#include "system.h" +#include "file.h" +#include "clock-target.h" +#include "dbop-as3525.h" +#include "lcd-fuze.h" + +/* The controller is unknown, but some registers appear to be the same as the + HD66789R */ +static bool display_on = false; /* is the display turned on? */ + +/* Flip Flag */ +static unsigned short r_entry_mode = R_ENTRY_MODE_HORZ_NORMAL; + +/* Reverse Flag */ +static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL; + +static const int xoffset = 20; + +/*** hardware configuration ***/ + +void lcd_set_contrast(int val) +{ + (void)val; +} + +void lcd_set_invert_display(bool yesno) +{ + r_disp_control_rev = yesno ? R_DISP_CONTROL_REV : + R_DISP_CONTROL_NORMAL; + + if (display_on) + { + lcd_write_reg(R_DISP_CONTROL1, 0x0013 | r_disp_control_rev); + } + +} + +#ifdef HAVE_LCD_FLIP +static bool display_flipped = false; + +/* turn the display upside down */ +void lcd_set_flip(bool yesno) +{ + display_flipped = yesno; + + r_entry_mode = yesno ? R_ENTRY_MODE_HORZ_FLIPPED : + R_ENTRY_MODE_HORZ_NORMAL; +} +#endif + +void fuze_display_on(void) +{ + /* Initialise in the same way as the original firmare */ + + lcd_write_reg(R_DISP_CONTROL1, 0); + lcd_write_reg(R_POWER_CONTROL4, 0); + + lcd_write_reg(R_POWER_CONTROL2, 0x3704); + lcd_write_reg(0x14, 0x1a1b); + lcd_write_reg(R_POWER_CONTROL1, 0x3860); + lcd_write_reg(R_POWER_CONTROL4, 0x40); + + lcd_write_reg(R_POWER_CONTROL4, 0x60); + + lcd_write_reg(R_POWER_CONTROL4, 0x70); + lcd_write_reg(R_DRV_OUTPUT_CONTROL, 277); + lcd_write_reg(R_DRV_WAVEFORM_CONTROL, (7<<8)); + lcd_write_reg(R_ENTRY_MODE, r_entry_mode); + lcd_write_reg(R_DISP_CONTROL2, 0x01); + lcd_write_reg(R_FRAME_CYCLE_CONTROL, (1<<10)); + lcd_write_reg(R_EXT_DISP_IF_CONTROL, 0); + + lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x40); + lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0687); + lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0306); + lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x104); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0585); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 255+66); + lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0687+128); + lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 259); + lcd_write_reg(R_GAMMA_AMP_ADJ_RES_POS, 0); + lcd_write_reg(R_GAMMA_AMP_AVG_ADJ_RES_NEG, 0); + + lcd_write_reg(R_1ST_SCR_DRV_POS, (LCD_WIDTH - 1)); + lcd_write_reg(R_2ND_SCR_DRV_POS, 0); + lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (LCD_WIDTH - 1)); + lcd_write_reg(R_VERT_RAM_ADDR_POS, 0); + lcd_write_reg(0x46, (((LCD_WIDTH - 1) + xoffset) << 8) | xoffset); + lcd_write_reg(0x47, (LCD_HEIGHT - 1)); + lcd_write_reg(0x48, 0x0); + + lcd_write_reg(R_DISP_CONTROL1, 0x11); + lcd_write_reg(R_DISP_CONTROL1, 0x13 | r_disp_control_rev); + + display_on = true; /* must be done before calling lcd_update() */ + lcd_update(); +} + +#if defined(HAVE_LCD_ENABLE) +void lcd_enable(bool on) +{ + if (display_on == on) + return; + + if(on) + { + lcd_write_reg(R_START_OSC, 1); + lcd_write_reg(R_POWER_CONTROL1, 0); + lcd_write_reg(R_POWER_CONTROL2, 0x3704); + lcd_write_reg(0x14, 0x1a1b); + lcd_write_reg(R_POWER_CONTROL1, 0x3860); + lcd_write_reg(R_POWER_CONTROL4, 0x40); + lcd_write_reg(R_POWER_CONTROL4, 0x60); + lcd_write_reg(R_POWER_CONTROL4, 112); + lcd_write_reg(R_DISP_CONTROL1, 0x11); + lcd_write_reg(R_DISP_CONTROL1, 0x13 | r_disp_control_rev); + display_on = true; + lcd_update(); /* Resync display */ + send_event(LCD_EVENT_ACTIVATION, NULL); + sleep(0); + + } + else + { + lcd_write_reg(R_DISP_CONTROL1, 0x22); + lcd_write_reg(R_DISP_CONTROL1, 0); + lcd_write_reg(R_POWER_CONTROL1, 1); + display_on = false; + } +} +#endif + +#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) +bool lcd_active(void) +{ + return display_on; +} +#endif + +/*** update functions ***/ + +/* FIXME : find the datasheet for this RENESAS controller so we identify the + * registers used in windowing code (not present in HD66789R) */ + +/* Set horizontal window addresses */ +static void lcd_window_x(int xmin, int xmax) +{ + xmin += xoffset; + xmax += xoffset; + lcd_write_reg(R_HORIZ_RAM_ADDR_POS + 2, (xmax << 8) | xmin); + lcd_write_reg(R_RAM_ADDR_SET - 1, xmin); +} + +/* Set vertical window addresses */ +static void lcd_window_y(int ymin, int ymax) +{ + lcd_write_reg(R_VERT_RAM_ADDR_POS + 2, ymax); + lcd_write_reg(R_VERT_RAM_ADDR_POS + 3, ymin); + lcd_write_reg(R_RAM_ADDR_SET, ymin); +} + +static unsigned lcd_yuv_options = 0; + +void lcd_yuv_set_options(unsigned options) +{ + lcd_yuv_options = options; +} + + +#ifndef BOOTLOADER +/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ +extern void lcd_write_yuv420_lines(unsigned char const * const src[3], + int width, + int stride); +extern void lcd_write_yuv420_lines_odither(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 + * src_x, src_y, width and height should be even + * x, y, width and height have to be within LCD bounds + */ +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; + + /* Sorry, but width and height must be >= 2 or else */ + width &= ~1; + height >>= 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]); + +#ifdef HAVE_LCD_FLIP + lcd_write_reg(R_ENTRY_MODE, + display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL + ); +#else + lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VIDEO_NORMAL); +#endif + + lcd_window_x(x, x + width - 1); + + if (lcd_yuv_options & LCD_YUV_DITHER) + { + do + { + lcd_window_y(y, y + 1); + + lcd_write_cmd(R_WRITE_DATA_2_GRAM); + + lcd_write_yuv420_lines_odither(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; + y += 2; + } + while (--height > 0); + } + else + { + do + { + lcd_window_y(y, y + 1); + + lcd_write_cmd(R_WRITE_DATA_2_GRAM); + + lcd_write_yuv420_lines(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; + y += 2; + } + while (--height > 0); + } +} + +#endif + + +/* Update the display. + This must be called after all other LCD functions that change the display. */ +void lcd_update(void) +{ + if (!display_on) + return; + + lcd_write_reg(R_ENTRY_MODE, r_entry_mode); + + lcd_window_x(0, LCD_WIDTH - 1); + lcd_window_y(0, LCD_HEIGHT - 1); + + lcd_write_cmd(R_WRITE_DATA_2_GRAM); + + dbop_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); +} + +/* Update a fraction of the display. */ +void lcd_update_rect(int x, int y, int width, int height) +{ + const fb_data *ptr; + + if (!display_on) + return; + + /* nothing to draw? */ + if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || + (y >= LCD_HEIGHT) || (x + width <= 0) || (y + height <= 0)) + return; + + if (x < 0) + { /* clip left */ + width += x; + x = 0; + } + if (y < 0) + { /* clip top */ + height += y; + y = 0; + } + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; /* clip right */ + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; /* clip bottom */ + + lcd_write_reg(R_ENTRY_MODE, r_entry_mode); + + /* we need to make x and width even to enable 32bit transfers */ + width = (width + (x & 1) + 1) & ~1; + x &= ~1; + + lcd_window_x(x, x + width - 1); + lcd_window_y(y, y + height -1); + + lcd_write_cmd(R_WRITE_DATA_2_GRAM); + + ptr = &lcd_framebuffer[y][x]; + + do + { + dbop_write_data(ptr, width); + ptr += LCD_WIDTH; + } + while (--height > 0); +} diff --git a/firmware/target/arm/as3525/lcd-fuze.h b/firmware/target/arm/as3525/lcd-fuze.h new file mode 100644 index 0000000000..00bb960ef1 --- /dev/null +++ b/firmware/target/arm/as3525/lcd-fuze.h @@ -0,0 +1,56 @@ +/* register defines */ +#define R_START_OSC 0x00 +#define R_DRV_OUTPUT_CONTROL 0x01 +#define R_DRV_WAVEFORM_CONTROL 0x02 +#define R_ENTRY_MODE 0x03 +#define R_COMPARE_REG1 0x04 +#define R_COMPARE_REG2 0x05 + +#define R_DISP_CONTROL1 0x07 +#define R_DISP_CONTROL2 0x08 +#define R_DISP_CONTROL3 0x09 + +#define R_FRAME_CYCLE_CONTROL 0x0b +#define R_EXT_DISP_IF_CONTROL 0x0c + +#define R_POWER_CONTROL1 0x10 +#define R_POWER_CONTROL2 0x11 +#define R_POWER_CONTROL3 0x12 +#define R_POWER_CONTROL4 0x13 + +#define R_RAM_ADDR_SET 0x21 +#define R_WRITE_DATA_2_GRAM 0x22 + +#define R_GAMMA_FINE_ADJ_POS1 0x30 +#define R_GAMMA_FINE_ADJ_POS2 0x31 +#define R_GAMMA_FINE_ADJ_POS3 0x32 +#define R_GAMMA_GRAD_ADJ_POS 0x33 + +#define R_GAMMA_FINE_ADJ_NEG1 0x34 +#define R_GAMMA_FINE_ADJ_NEG2 0x35 +#define R_GAMMA_FINE_ADJ_NEG3 0x36 +#define R_GAMMA_GRAD_ADJ_NEG 0x37 + +#define R_GAMMA_AMP_ADJ_RES_POS 0x38 +#define R_GAMMA_AMP_AVG_ADJ_RES_NEG 0x39 + +#define R_GATE_SCAN_POS 0x40 +#define R_VERT_SCROLL_CONTROL 0x41 +#define R_1ST_SCR_DRV_POS 0x42 +#define R_2ND_SCR_DRV_POS 0x43 +#define R_HORIZ_RAM_ADDR_POS 0x44 +#define R_VERT_RAM_ADDR_POS 0x45 + +/* Flip Flag */ +#define R_ENTRY_MODE_HORZ_NORMAL 0x1030 +#define R_ENTRY_MODE_HORZ_FLIPPED 0x1000 +#define R_ENTRY_MODE_VIDEO_NORMAL 0x1038 +#define R_ENTRY_MODE_VIDEO_FLIPPED 0x1018 + +/* Reverse Flag */ +#define R_DISP_CONTROL_NORMAL 0x0004 +#define R_DISP_CONTROL_REV 0x0000 + +void lcd_write_cmd(int16_t cmd); +void lcd_write_reg(int reg, int value); +void fuze_display_on(void); diff --git a/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c b/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c deleted file mode 100644 index 54d4d73183..0000000000 --- a/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c +++ /dev/null @@ -1,452 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2008 by Dave Chapman - * - * LCD driver for the Sansa Fuze - controller unknown - * - * 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. - * - ****************************************************************************/ -#include "config.h" - -#include "cpu.h" -#include "lcd.h" -#include "file.h" -#include "debug.h" -#include "system.h" -#include "clock-target.h" -#include "dbop-as3525.h" - -/* The controller is unknown, but some registers appear to be the same as the - HD66789R */ -static bool display_on = false; /* is the display turned on? */ - -/* register defines */ -#define R_START_OSC 0x00 -#define R_DRV_OUTPUT_CONTROL 0x01 -#define R_DRV_WAVEFORM_CONTROL 0x02 -#define R_ENTRY_MODE 0x03 -#define R_COMPARE_REG1 0x04 -#define R_COMPARE_REG2 0x05 - -#define R_DISP_CONTROL1 0x07 -#define R_DISP_CONTROL2 0x08 -#define R_DISP_CONTROL3 0x09 - -#define R_FRAME_CYCLE_CONTROL 0x0b -#define R_EXT_DISP_IF_CONTROL 0x0c - -#define R_POWER_CONTROL1 0x10 -#define R_POWER_CONTROL2 0x11 -#define R_POWER_CONTROL3 0x12 -#define R_POWER_CONTROL4 0x13 - -#define R_RAM_ADDR_SET 0x21 -#define R_WRITE_DATA_2_GRAM 0x22 - -#define R_GAMMA_FINE_ADJ_POS1 0x30 -#define R_GAMMA_FINE_ADJ_POS2 0x31 -#define R_GAMMA_FINE_ADJ_POS3 0x32 -#define R_GAMMA_GRAD_ADJ_POS 0x33 - -#define R_GAMMA_FINE_ADJ_NEG1 0x34 -#define R_GAMMA_FINE_ADJ_NEG2 0x35 -#define R_GAMMA_FINE_ADJ_NEG3 0x36 -#define R_GAMMA_GRAD_ADJ_NEG 0x37 - -#define R_GAMMA_AMP_ADJ_RES_POS 0x38 -#define R_GAMMA_AMP_AVG_ADJ_RES_NEG 0x39 - -#define R_GATE_SCAN_POS 0x40 -#define R_VERT_SCROLL_CONTROL 0x41 -#define R_1ST_SCR_DRV_POS 0x42 -#define R_2ND_SCR_DRV_POS 0x43 -#define R_HORIZ_RAM_ADDR_POS 0x44 -#define R_VERT_RAM_ADDR_POS 0x45 - -/* Flip Flag */ -#define R_ENTRY_MODE_HORZ_NORMAL 0x7030 -#define R_ENTRY_MODE_HORZ_FLIPPED 0x7000 -static unsigned short r_entry_mode = R_ENTRY_MODE_HORZ_NORMAL; -#define R_ENTRY_MODE_VERT 0x7038 -#define R_ENTRY_MODE_SOLID_VERT 0x1038 -/* FIXME */ -#define R_ENTRY_MODE_VIDEO_NORMAL 0x7038 -#define R_ENTRY_MODE_VIDEO_FLIPPED 0x7018 - -/* Reverse Flag */ -#define R_DISP_CONTROL_NORMAL 0x0004 -#define R_DISP_CONTROL_REV 0x0000 -static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL; - -static const int xoffset = 20; - -static inline void lcd_delay(int x) -{ - do { - asm volatile ("nop\n"); - } while (x--); -} - -static void as3525_dbop_init(void) -{ - CGU_DBOP = (1<<3) | AS3525_DBOP_DIV; - - DBOP_TIMPOL_01 = 0xe167e167; - DBOP_TIMPOL_23 = 0xe167006e; - - /* short count: 16 | output data width: 16 | readstrobe line */ - DBOP_CTRL = (1<<18|1<<12|1<<3); - - GPIOB_AFSEL = 0xfc; - GPIOC_AFSEL = 0xff; - - DBOP_TIMPOL_23 = 0x6000e; - - /* short count: 16|enable write|output data width: 16|read strobe line */ - DBOP_CTRL = (1<<18|1<<16|1<<12|1<<3); - DBOP_TIMPOL_01 = 0x6e167; - DBOP_TIMPOL_23 = 0xa167e06f; - - /* TODO: The OF calls some other functions here, but maybe not important */ -} - -static void lcd_write_cmd(short cmd) -{ - /* Write register */ - DBOP_TIMPOL_23 = 0xa167006e; - dbop_write_data(&cmd, 1); - - lcd_delay(4); - - DBOP_TIMPOL_23 = 0xa167e06f; -} - -static void lcd_write_reg(int reg, int value) -{ - int16_t data = value; - - lcd_write_cmd(reg); - dbop_write_data(&data, 1); -} - -/*** hardware configuration ***/ - -void lcd_set_contrast(int val) -{ - (void)val; -} - -void lcd_set_invert_display(bool yesno) -{ - r_disp_control_rev = yesno ? R_DISP_CONTROL_REV : - R_DISP_CONTROL_NORMAL; - - if (display_on) - { - lcd_write_reg(R_DISP_CONTROL1, 0x0013 | r_disp_control_rev); - } - -} - -#ifdef HAVE_LCD_FLIP -static bool display_flipped = false; - -/* turn the display upside down */ -void lcd_set_flip(bool yesno) -{ - display_flipped = yesno; - - r_entry_mode = yesno ? R_ENTRY_MODE_HORZ_FLIPPED : - R_ENTRY_MODE_HORZ_NORMAL; -} -#endif - -static void _display_on(void) -{ - /* Initialise in the same way as the original firmare */ - - lcd_write_reg(R_DISP_CONTROL1, 0); - lcd_write_reg(R_POWER_CONTROL4, 0); - - lcd_write_reg(R_POWER_CONTROL2, 0x3704); - lcd_write_reg(0x14, 0x1a1b); - lcd_write_reg(R_POWER_CONTROL1, 0x3860); - lcd_write_reg(R_POWER_CONTROL4, 0x40); - - lcd_write_reg(R_POWER_CONTROL4, 0x60); - - lcd_write_reg(R_POWER_CONTROL4, 0x70); - lcd_write_reg(R_DRV_OUTPUT_CONTROL, 277); - lcd_write_reg(R_DRV_WAVEFORM_CONTROL, (7<<8)); - lcd_write_reg(R_ENTRY_MODE, r_entry_mode); - lcd_write_reg(R_DISP_CONTROL2, 0x01); - lcd_write_reg(R_FRAME_CYCLE_CONTROL, (1<<10)); - lcd_write_reg(R_EXT_DISP_IF_CONTROL, 0); - - lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x40); - lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0687); - lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0306); - lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x104); - lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0585); - lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 255+66); - lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0687+128); - lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 259); - lcd_write_reg(R_GAMMA_AMP_ADJ_RES_POS, 0); - lcd_write_reg(R_GAMMA_AMP_AVG_ADJ_RES_NEG, 0); - - lcd_write_reg(R_1ST_SCR_DRV_POS, (LCD_WIDTH - 1)); - lcd_write_reg(R_2ND_SCR_DRV_POS, 0); - lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (LCD_WIDTH - 1)); - lcd_write_reg(R_VERT_RAM_ADDR_POS, 0); - lcd_write_reg(0x46, (((LCD_WIDTH - 1) + xoffset) << 8) | xoffset); - lcd_write_reg(0x47, (LCD_HEIGHT - 1)); - lcd_write_reg(0x48, 0x0); - - lcd_write_reg(R_DISP_CONTROL1, 0x11); - lcd_write_reg(R_DISP_CONTROL1, 0x13 | r_disp_control_rev); - - display_on = true; /* must be done before calling lcd_update() */ - lcd_update(); -} - -void lcd_init_device(void) -{ - as3525_dbop_init(); - - GPIOA_DIR |= (1<<5|1<<4|1<<3); - GPIOA_PIN(5) = 0; - GPIOA_PIN(3) = (1<<3); - GPIOA_PIN(4) = 0; - GPIOA_PIN(5) = (1<<5); - - _display_on(); -} - -#if defined(HAVE_LCD_ENABLE) -void lcd_enable(bool on) -{ - if (display_on == on) - return; - - if(on) - { - lcd_write_reg(R_START_OSC, 1); - lcd_write_reg(R_POWER_CONTROL1, 0); - lcd_write_reg(R_POWER_CONTROL2, 0x3704); - lcd_write_reg(0x14, 0x1a1b); - lcd_write_reg(R_POWER_CONTROL1, 0x3860); - lcd_write_reg(R_POWER_CONTROL4, 0x40); - lcd_write_reg(R_POWER_CONTROL4, 0x60); - lcd_write_reg(R_POWER_CONTROL4, 112); - lcd_write_reg(R_DISP_CONTROL1, 0x11); - lcd_write_reg(R_DISP_CONTROL1, 0x13 | r_disp_control_rev); - display_on = true; - lcd_update(); /* Resync display */ - send_event(LCD_EVENT_ACTIVATION, NULL); - sleep(0); - - } - else - { - lcd_write_reg(R_DISP_CONTROL1, 0x22); - lcd_write_reg(R_DISP_CONTROL1, 0); - lcd_write_reg(R_POWER_CONTROL1, 1); - display_on = false; - } -} -#endif - -#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) -bool lcd_active(void) -{ - return display_on; -} -#endif - -/*** update functions ***/ - -/* FIXME : find the datasheet for this RENESAS controller so we identify the - * registers used in windowing code (not present in HD66789R) */ - -/* Set horizontal window addresses */ -static void lcd_window_x(int xmin, int xmax) -{ - xmin += xoffset; - xmax += xoffset; - lcd_write_reg(R_HORIZ_RAM_ADDR_POS + 2, (xmax << 8) | xmin); - lcd_write_reg(R_RAM_ADDR_SET - 1, xmin); -} - -/* Set vertical window addresses */ -static void lcd_window_y(int ymin, int ymax) -{ - lcd_write_reg(R_VERT_RAM_ADDR_POS + 2, ymax); - lcd_write_reg(R_VERT_RAM_ADDR_POS + 3, ymin); - lcd_write_reg(R_RAM_ADDR_SET, ymin); -} - -static unsigned lcd_yuv_options = 0; - -void lcd_yuv_set_options(unsigned options) -{ - lcd_yuv_options = options; -} - - -#ifndef BOOTLOADER -/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ -extern void lcd_write_yuv420_lines(unsigned char const * const src[3], - int width, - int stride); -extern void lcd_write_yuv420_lines_odither(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 - * src_x, src_y, width and height should be even - * x, y, width and height have to be within LCD bounds - */ -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; - - /* Sorry, but width and height must be >= 2 or else */ - width &= ~1; - height >>= 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]); - -#ifdef HAVE_LCD_FLIP - lcd_write_reg(R_ENTRY_MODE, - display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL - ); -#else - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VIDEO_NORMAL); -#endif - - lcd_window_x(x, x + width - 1); - - if (lcd_yuv_options & LCD_YUV_DITHER) - { - do - { - lcd_window_y(y, y + 1); - - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - - lcd_write_yuv420_lines_odither(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; - y += 2; - } - while (--height > 0); - } - else - { - do - { - lcd_window_y(y, y + 1); - - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - - lcd_write_yuv420_lines(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; - y += 2; - } - while (--height > 0); - } -} - -#endif - - -/* Update the display. - This must be called after all other LCD functions that change the display. */ -void lcd_update(void) -{ - if (!display_on) - return; - - lcd_write_reg(R_ENTRY_MODE, r_entry_mode); - - lcd_window_x(0, LCD_WIDTH - 1); - lcd_window_y(0, LCD_HEIGHT - 1); - - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - - dbop_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); -} - -/* Update a fraction of the display. */ -void lcd_update_rect(int x, int y, int width, int height) -{ - const fb_data *ptr; - - if (!display_on) - return; - - /* nothing to draw? */ - if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || - (y >= LCD_HEIGHT) || (x + width <= 0) || (y + height <= 0)) - return; - - if (x < 0) - { /* clip left */ - width += x; - x = 0; - } - if (y < 0) - { /* clip top */ - height += y; - y = 0; - } - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; /* clip right */ - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; /* clip bottom */ - - lcd_write_reg(R_ENTRY_MODE, r_entry_mode); - - /* we need to make x and width even to enable 32bit transfers */ - width = (width + (x & 1) + 1) & ~1; - x &= ~1; - - lcd_window_x(x, x + width - 1); - lcd_window_y(y, y + height -1); - - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - - ptr = &lcd_framebuffer[y][x]; - - do - { - dbop_write_data(ptr, width); - ptr += LCD_WIDTH; - } - while (--height > 0); -} diff --git a/firmware/target/arm/as3525/sansa-fuze/lcd-fuzev1.c b/firmware/target/arm/as3525/sansa-fuze/lcd-fuzev1.c new file mode 100644 index 0000000000..0c56ee3070 --- /dev/null +++ b/firmware/target/arm/as3525/sansa-fuze/lcd-fuzev1.c @@ -0,0 +1,88 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Dave Chapman + * + * LCD driver for the Sansa Fuze - controller unknown + * + * 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. + * + ****************************************************************************/ +#include "config.h" + +#include "cpu.h" +#include "lcd.h" +#include "system.h" +#include "clock-target.h" +#include "dbop-as3525.h" +#include "lcd-fuze.h" + +void lcd_write_cmd(int16_t cmd) +{ + /* Write register */ + DBOP_TIMPOL_23 = 0xa167006e; + dbop_write_data(&cmd, 1); + + int delay = 4; + do { + nop; + } while(delay--); + + DBOP_TIMPOL_23 = 0xa167e06f; +} + +void lcd_write_reg(int reg, int value) +{ + int16_t data = value; + + lcd_write_cmd(reg); + dbop_write_data(&data, 1); +} + + +static void as3525_dbop_init(void) +{ + CGU_DBOP = (1<<3) | AS3525_DBOP_DIV; + + DBOP_TIMPOL_01 = 0xe167e167; + DBOP_TIMPOL_23 = 0xe167006e; + + /* short count: 16 | output data width: 16 | readstrobe line */ + DBOP_CTRL = (1<<18|1<<12|1<<3); + + GPIOB_AFSEL = 0xfc; + GPIOC_AFSEL = 0xff; + + DBOP_TIMPOL_23 = 0x6000e; + + /* short count: 16|enable write|output data width: 16|read strobe line */ + DBOP_CTRL = (1<<18|1<<16|1<<12|1<<3); + DBOP_TIMPOL_01 = 0x6e167; + DBOP_TIMPOL_23 = 0xa167e06f; +} + + +void lcd_init_device(void) +{ + as3525_dbop_init(); + + GPIOA_DIR |= (1<<5|1<<4|1<<3); + GPIOA_PIN(5) = 0; + GPIOA_PIN(3) = (1<<3); + GPIOA_PIN(4) = 0; + GPIOA_PIN(5) = (1<<5); + + fuze_display_on(); +} diff --git a/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c b/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c index 9797815d23..fd6bcb45fc 100644 --- a/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c +++ b/firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c @@ -25,82 +25,33 @@ #include "cpu.h" #include "lcd.h" -#include "file.h" -#include "debug.h" #include "system.h" #include "clock-target.h" #include "dbop-as3525.h" +#include "lcd-fuze.h" -/* The controller is unknown, but some registers appear to be the same as the - HD66789R */ -static bool display_on = false; /* is the display turned on? */ - -/* register defines */ -#define R_START_OSC 0x00 -#define R_DRV_OUTPUT_CONTROL 0x01 -#define R_DRV_WAVEFORM_CONTROL 0x02 -#define R_ENTRY_MODE 0x03 -#define R_COMPARE_REG1 0x04 -#define R_COMPARE_REG2 0x05 - -#define R_DISP_CONTROL1 0x07 -#define R_DISP_CONTROL2 0x08 -#define R_DISP_CONTROL3 0x09 - -#define R_FRAME_CYCLE_CONTROL 0x0b -#define R_EXT_DISP_IF_CONTROL 0x0c - -#define R_POWER_CONTROL1 0x10 -#define R_POWER_CONTROL2 0x11 -#define R_POWER_CONTROL3 0x12 -#define R_POWER_CONTROL4 0x13 - -#define R_RAM_ADDR_SET 0x21 -#define R_WRITE_DATA_2_GRAM 0x22 - -#define R_GAMMA_FINE_ADJ_POS1 0x30 -#define R_GAMMA_FINE_ADJ_POS2 0x31 -#define R_GAMMA_FINE_ADJ_POS3 0x32 -#define R_GAMMA_GRAD_ADJ_POS 0x33 - -#define R_GAMMA_FINE_ADJ_NEG1 0x34 -#define R_GAMMA_FINE_ADJ_NEG2 0x35 -#define R_GAMMA_FINE_ADJ_NEG3 0x36 -#define R_GAMMA_GRAD_ADJ_NEG 0x37 - -#define R_GAMMA_AMP_ADJ_RES_POS 0x38 -#define R_GAMMA_AMP_AVG_ADJ_RES_NEG 0x39 - -#define R_GATE_SCAN_POS 0x40 -#define R_VERT_SCROLL_CONTROL 0x41 -#define R_1ST_SCR_DRV_POS 0x42 -#define R_2ND_SCR_DRV_POS 0x43 -#define R_HORIZ_RAM_ADDR_POS 0x44 -#define R_VERT_RAM_ADDR_POS 0x45 - -/* Flip Flag */ -#define R_ENTRY_MODE_HORZ_NORMAL 0x7030 -#define R_ENTRY_MODE_HORZ_FLIPPED 0x7000 -static unsigned short r_entry_mode = R_ENTRY_MODE_HORZ_NORMAL; -#define R_ENTRY_MODE_VERT 0x7038 -#define R_ENTRY_MODE_SOLID_VERT 0x1038 -#define R_ENTRY_MODE_VIDEO_NORMAL 0x7038 -#define R_ENTRY_MODE_VIDEO_FLIPPED 0x7018 +void lcd_write_cmd(int16_t cmd) +{ + unsigned short data = swap16(cmd); + DBOP_TIMPOL_23 = 0xA12F0036; + dbop_write_data(&data, 1); -/* Reverse Flag */ -#define R_DISP_CONTROL_NORMAL 0x0004 -#define R_DISP_CONTROL_REV 0x0000 -static unsigned short r_disp_control_rev = R_DISP_CONTROL_NORMAL; + int delay = 32; + do { + nop; + } while(delay--); -static const int xoffset = 20; + DBOP_TIMPOL_23 = 0xA12FE037; +} -static inline void lcd_delay(int x) +void lcd_write_reg(int reg, int value) { - do { - asm volatile ("nop\n"); - } while (x--); + int16_t data = swap16(value); + lcd_write_cmd(reg); + dbop_write_data(&data, 1); } + static void as3525_dbop_init(void) { CCU_IO |= 1<<12; @@ -115,102 +66,6 @@ static void as3525_dbop_init(void) } -static void lcd_write_cmd(unsigned short cmd) -{ - unsigned short data = swap16(cmd); - DBOP_TIMPOL_23 = 0xA12F0036; - dbop_write_data(&data, 1); - lcd_delay(32); - DBOP_TIMPOL_23 = 0xA12FE037; -} - -static void lcd_write_reg(int reg, int value) -{ - int16_t data = swap16(value); - lcd_write_cmd(reg); - dbop_write_data(&data, 1); -} - -/*** hardware configuration ***/ - -void lcd_set_contrast(int val) -{ - (void)val; -} - -void lcd_set_invert_display(bool yesno) -{ - r_disp_control_rev = yesno ? R_DISP_CONTROL_REV : - R_DISP_CONTROL_NORMAL; - - if (display_on) - { - lcd_write_reg(R_DISP_CONTROL1, 0x0013 | r_disp_control_rev); - } - -} - -#ifdef HAVE_LCD_FLIP -static bool display_flipped = false; - -/* turn the display upside down */ -void lcd_set_flip(bool yesno) -{ - display_flipped = yesno; - - r_entry_mode = yesno ? R_ENTRY_MODE_HORZ_FLIPPED : - R_ENTRY_MODE_HORZ_NORMAL; -} -#endif - -static void _display_on(void) -{ - /* Initialise in the same way as the original firmare */ - - lcd_write_reg(R_DISP_CONTROL1, 0); - lcd_write_reg(R_POWER_CONTROL4, 0); - - lcd_write_reg(R_POWER_CONTROL2, 0x3704); - lcd_write_reg(0x14, 0x1a1b); - lcd_write_reg(R_POWER_CONTROL1, 0x3860); - lcd_write_reg(R_POWER_CONTROL4, 0x40); - - lcd_write_reg(R_POWER_CONTROL4, 0x60); - - lcd_write_reg(R_POWER_CONTROL4, 0x70); - lcd_write_reg(R_DRV_OUTPUT_CONTROL, 277); - lcd_write_reg(R_DRV_WAVEFORM_CONTROL, (7<<8)); - lcd_write_reg(R_ENTRY_MODE, r_entry_mode); - lcd_write_reg(R_DISP_CONTROL2, 0x01); - lcd_write_reg(R_FRAME_CYCLE_CONTROL, (1<<10)); - lcd_write_reg(R_EXT_DISP_IF_CONTROL, 0); - - lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x40); - lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0687); - lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0306); - lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x104); - lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0585); - lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 255+66); - lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0687+128); - lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 259); - lcd_write_reg(R_GAMMA_AMP_ADJ_RES_POS, 0); - lcd_write_reg(R_GAMMA_AMP_AVG_ADJ_RES_NEG, 0); - - lcd_write_reg(R_1ST_SCR_DRV_POS, (LCD_WIDTH - 1)); - lcd_write_reg(R_2ND_SCR_DRV_POS, 0); - lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (LCD_WIDTH - 1)); - lcd_write_reg(R_VERT_RAM_ADDR_POS, 0); - lcd_write_reg(0x46, (((LCD_WIDTH - 1) + xoffset) << 8) | xoffset); - lcd_write_reg(0x47, (LCD_HEIGHT - 1)); - lcd_write_reg(0x48, 0x0); - - lcd_write_reg(R_DISP_CONTROL1, 0x11); - lcd_write_reg(R_DISP_CONTROL1, 0x13 | r_disp_control_rev); - - display_on = true; /* must be done before calling lcd_update() */ - lcd_update(); -} - void lcd_init_device(void) { as3525_dbop_init(); @@ -229,218 +84,5 @@ void lcd_init_device(void) GPIOA_PIN(4) = 1<<4; GPIOA_PIN(5) = 1<<5; - _display_on(); -} - -#if defined(HAVE_LCD_ENABLE) -void lcd_enable(bool on) -{ - if (display_on == on) - return; - - if(on) - { - lcd_write_reg(R_START_OSC, 1); - lcd_write_reg(R_POWER_CONTROL1, 0); - lcd_write_reg(R_POWER_CONTROL2, 0x3704); - lcd_write_reg(0x14, 0x1a1b); - lcd_write_reg(R_POWER_CONTROL1, 0x3860); - lcd_write_reg(R_POWER_CONTROL4, 0x40); - lcd_write_reg(R_POWER_CONTROL4, 0x60); - lcd_write_reg(R_POWER_CONTROL4, 112); - lcd_write_reg(R_DISP_CONTROL1, 0x11); - lcd_write_reg(R_DISP_CONTROL1, 0x13 | r_disp_control_rev); - display_on = true; - lcd_update(); /* Resync display */ - send_event(LCD_EVENT_ACTIVATION, NULL); - sleep(0); - - } - else - { - lcd_write_reg(R_DISP_CONTROL1, 0x22); - lcd_write_reg(R_DISP_CONTROL1, 0); - lcd_write_reg(R_POWER_CONTROL1, 1); - display_on = false; - } -} -#endif - -#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) -bool lcd_active(void) -{ - return display_on; -} -#endif - -/*** update functions ***/ - -/* FIXME : find the datasheet for this RENESAS controller so we identify the - * registers used in windowing code (not present in HD66789R) */ - -/* Set horizontal window addresses */ -static void lcd_window_x(int xmin, int xmax) -{ - xmin += xoffset; - xmax += xoffset; - lcd_write_reg(R_HORIZ_RAM_ADDR_POS + 2, (xmax << 8) | xmin); - lcd_write_reg(R_RAM_ADDR_SET - 1, xmin); -} - -/* Set vertical window addresses */ -static void lcd_window_y(int ymin, int ymax) -{ - lcd_write_reg(R_VERT_RAM_ADDR_POS + 2, ymax); - lcd_write_reg(R_VERT_RAM_ADDR_POS + 3, ymin); - lcd_write_reg(R_RAM_ADDR_SET, ymin); -} - -static unsigned lcd_yuv_options = 0; - -void lcd_yuv_set_options(unsigned options) -{ - lcd_yuv_options = options; -} - - -#ifndef BOOTLOADER -/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ -extern void lcd_write_yuv420_lines(unsigned char const * const src[3], - int width, - int stride); -extern void lcd_write_yuv420_lines_odither(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 - * src_x, src_y, width and height should be even - * x, y, width and height have to be within LCD bounds - */ -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; - - /* Sorry, but width and height must be >= 2 or else */ - width &= ~1; - height >>= 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]); - -#ifdef HAVE_LCD_FLIP - lcd_write_reg(R_ENTRY_MODE, - display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL - ); -#else - lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VIDEO_NORMAL); -#endif - - lcd_window_x(x, x + width - 1); - - if (lcd_yuv_options & LCD_YUV_DITHER) - { - do - { - lcd_window_y(y, y + 1); - - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - lcd_write_yuv420_lines_odither(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; - y += 2; - } - while (--height > 0); - } - else - { - do - { - lcd_window_y(y, y + 1); - - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - lcd_write_yuv420_lines(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; - y += 2; - } - while (--height > 0); - } -} - -#endif - - -/* Update the display. - This must be called after all other LCD functions that change the display. */ -void lcd_update(void) -{ - if (!display_on) - return; - - lcd_write_reg(R_ENTRY_MODE, r_entry_mode); - - lcd_window_x(0, LCD_WIDTH - 1); - lcd_window_y(0, LCD_HEIGHT - 1); - - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - - lcd_update_rect(0,0, LCD_WIDTH, LCD_HEIGHT); -} - -/* Update a fraction of the display. */ -void lcd_update_rect(int x, int y, int width, int height) -{ - const fb_data *ptr; - - if (!display_on) - return; - - /* nothing to draw? */ - if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || - (y >= LCD_HEIGHT) || (x + width <= 0) || (y + height <= 0)) - return; - - if (x < 0) - { /* clip left */ - width += x; - x = 0; - } - if (y < 0) - { /* clip top */ - height += y; - y = 0; - } - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; /* clip right */ - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; /* clip bottom */ - - lcd_write_reg(R_ENTRY_MODE, r_entry_mode); - - /* we need to make x and width even to enable 32bit transfers */ - width = (width + (x & 1) + 1) & ~1; - x &= ~1; - - lcd_window_x(x, x + width - 1); - lcd_window_y(y, y + height -1); - - lcd_write_cmd(R_WRITE_DATA_2_GRAM); - - ptr = &lcd_framebuffer[y][x]; - - do - { - dbop_write_data(ptr, width); - ptr += LCD_WIDTH; - } - while (--height > 0); + fuze_display_on(); } -- cgit v1.2.3