diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2010-05-27 23:32:38 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2010-05-27 23:32:38 +0000 |
commit | 6921a2b6b988e40fed1c2c3c5182381c26ef3d75 (patch) | |
tree | dd3ca9554ecf0a24d704d84b976b745955545b3e /firmware/target/arm/as3525/sansa-fuzev2 | |
parent | 9d583f2b0b52919d961ed1853babebd6ec377c1d (diff) |
Merge common LCD code between fuzev1 & fuzev2
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26344 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/as3525/sansa-fuzev2')
-rw-r--r-- | firmware/target/arm/as3525/sansa-fuzev2/lcd-fuzev2.c | 394 |
1 files changed, 18 insertions, 376 deletions
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(); } |