From 52ca187f68ff3d74f604b4e12048aacaed451a24 Mon Sep 17 00:00:00 2001 From: Bertrik Sikken Date: Sun, 25 Oct 2009 11:31:13 +0000 Subject: Meizu M6 SP: update lcd driver, it is now possible to display a rockbox logo (with some limitations, see comments in lcd-m6sp.c) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23345 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/meizu_m6sp.c | 6 +- firmware/export/config-meizu-m6sp.h | 6 +- firmware/target/arm/s5l8700/meizu-m6sp/lcd-m6sp.c | 157 +++++++++++++--------- 3 files changed, 98 insertions(+), 71 deletions(-) diff --git a/bootloader/meizu_m6sp.c b/bootloader/meizu_m6sp.c index 2240e95768..064d3fc8df 100644 --- a/bootloader/meizu_m6sp.c +++ b/bootloader/meizu_m6sp.c @@ -41,6 +41,7 @@ #include "rbunicode.h" #include "usb.h" #include "qt1106.h" +#include "bitmaps/rockboxlogo.h" #include @@ -107,7 +108,10 @@ void main(void) oldval = PCON1; PCON1 = ((oldval & ~(0xf << 16)) | (0 << 16)); - // Wait for play to be pressed + lcd_bitmap(rockboxlogo, 0, 0, BMPWIDTH_rockboxlogo, BMPHEIGHT_rockboxlogo); + lcd_init_device(); + + // Wait for play to be pressed while(!(PDAT1 & (1 << 4))); // Wait for play to be released while((PDAT1 & (1 << 4))); diff --git a/firmware/export/config-meizu-m6sp.h b/firmware/export/config-meizu-m6sp.h index b5aad58667..973d6fdcca 100644 --- a/firmware/export/config-meizu-m6sp.h +++ b/firmware/export/config-meizu-m6sp.h @@ -59,13 +59,13 @@ #define CONFIG_NAND NAND_SAMSUNG /* LCD dimensions */ -#define LCD_WIDTH 320 -#define LCD_HEIGHT 240 +#define LCD_WIDTH 240 +#define LCD_HEIGHT 320 #define LCD_DEPTH 16 /* pseudo 262.144 colors */ #define LCD_PIXELFORMAT RGB565 /* rgb565 */ /* Define this if your LCD can be enabled/disabled */ -//#define HAVE_LCD_ENABLE +#define HAVE_LCD_ENABLE /* Define this if your LCD can be put to sleep. HAVE_LCD_ENABLE should be defined as well. */ diff --git a/firmware/target/arm/s5l8700/meizu-m6sp/lcd-m6sp.c b/firmware/target/arm/s5l8700/meizu-m6sp/lcd-m6sp.c index b6330406f2..9a24480bfa 100644 --- a/firmware/target/arm/s5l8700/meizu-m6sp/lcd-m6sp.c +++ b/firmware/target/arm/s5l8700/meizu-m6sp/lcd-m6sp.c @@ -31,26 +31,32 @@ (yet unknown) type, the exact type is detected at run-time. Open issues: - * untested on actual hardware - * use 16-bit pixel format, currently pixels are converted to a 32-bit pixel - format in lcd_update_rect, that is not natively supported yet in Rockbox. + * LCD is currently in portrait mode instead of landscape mode + * This LCD driver accesses the Rockbox framebuffer directly, so any changes + to the framebuffer as shown directly even before lcd_update is called. + * Sometimes part of the top of the screen appears at the bottom + * The Meizu seems to hang after LCD initialisation + * The driver for the S6D0139 LCD has not been tested yet */ /* LCD SPI connections */ -#define LCD_SPI_SSn (1<<1) /* on PDAT7 */ -#define LCD_SPI_MISO (1<<2) /* on PDAT3 */ -#define LCD_SPI_MOSI (1<<6) /* on PDAT3 */ -#define LCD_SPI_SCLK (1<<7) /* on PDAT3 */ - -#define LCD_TYPE1_ID 0x139 /* id for LCD type S6D0139 */ - +#define LCD_SPI_SSn (1<<1) /* on PDAT7 */ +#define LCD_SPI_MISO (1<<2) /* on PDAT3 */ +#define LCD_SPI_MOSI (1<<6) /* on PDAT3 */ +#define LCD_SPI_SCLK (1<<7) /* on PDAT3 */ + +/* LCD SPI communication definitions */ +#define LCD_SPI_DEVICE_ID (0x1D<<2) +#define LCD_SPI_INDEX_WRITE (LCD_SPI_DEVICE_ID|0) +#define LCD_SPI_STATUS_READ (LCD_SPI_DEVICE_ID|1) +#define LCD_SPI_DATA_WRITE (LCD_SPI_DEVICE_ID|2) +#define LCD_SPI_DATA_READ (LCD_SPI_DEVICE_ID|3) + +#define LCD_TYPE1_ID 0x139 /* id for LCD type S6D0139 */ + static int lcd_type = 0; -/* local frame buffer, keeps pixels in 32-bit words in format 0x00RRGGBB */ -static uint32_t lcd_local_fb[LCD_HEIGHT][LCD_WIDTH]; - - /* simple and crude delay */ static void lcd_delay(int count) { @@ -111,7 +117,7 @@ static void lcd_spi_init(void) /* configure MISO (P3.2) input, MOSI (P3.6) output, SCLK (P3.7) output */ PCON3 = (PCON3 & ~0xFF000F00) | 0x11000000; - + /* set all outputs high */ PDAT7 |= LCD_SPI_SSn; PDAT3 |= (LCD_SPI_MOSI | LCD_SPI_SCLK); @@ -121,17 +127,17 @@ static void lcd_spi_init(void) static unsigned int lcd_read_reg(unsigned reg) { unsigned int data; - - lcd_spi_transfer(24, (0x74 << 16) | reg); //0111.0100 - data = lcd_spi_transfer(24, (0x77 << 16)); //0111.0111 + + lcd_spi_transfer(24, (LCD_SPI_INDEX_WRITE << 16) | reg); + data = lcd_spi_transfer(24, (LCD_SPI_DATA_READ << 16)); return data & 0xFFFF; } /* write LCD register over SPI */ static void lcd_write_reg(unsigned char reg, unsigned int data) -{ - lcd_spi_transfer(24, (0x74 << 16) | reg); //0111.0100 - lcd_spi_transfer(24, (0x76 << 16) | data); //0111.0110 +{ + lcd_spi_transfer(24, (LCD_SPI_INDEX_WRITE << 16) | reg); + lcd_spi_transfer(24, (LCD_SPI_DATA_WRITE << 16) | data); } /* enable/disable clock signals towards the lcd */ @@ -226,10 +232,10 @@ static void lcd_init2(void) lcd_write_reg(0x0C, 0x0000); lcd_write_reg(0x0D, 0x0007); lcd_write_reg(0x15, 0x0003); - lcd_write_reg(0x16, 0x0014); - lcd_write_reg(0x17, 0x0000); - lcd_write_reg(0x30, 0x0503); + lcd_write_reg(0x17, 0x0000); + + lcd_write_reg(0x30, 0x0503); /* gamma? */ lcd_write_reg(0x31, 0x0303); lcd_write_reg(0x32, 0x0305); lcd_write_reg(0x33, 0x0202); @@ -295,6 +301,8 @@ static void lcd_enable2(bool on) lcd_write_reg(0x13, 0x0022); lcd_write_reg(0x14, 0x0000); lcd_write_reg(0x10, 0x7404); + lcd_write_reg(0x11, 0x0738); + lcd_write_reg(0x10, 0x7404); lcd_delay(833350); lcd_write_reg(0x07, 0x0009); @@ -311,7 +319,7 @@ static void lcd_enable2(bool on) lcd_write_reg(0x07, 0x010B); } else { - lcd_write_reg(0x0B, 0x0000); + lcd_write_reg(0x0B, 0x0109); lcd_write_reg(0x07, 0x0009); lcd_delay(666680); @@ -326,7 +334,7 @@ static void lcd_enable2(bool on) /* turn both the lcd controller and the lcd itself on or off */ void lcd_enable(bool on) -{ +{ if (on) { /* enable controller clock */ PWRCON &= ~(1 << 18); @@ -354,16 +362,28 @@ void lcd_enable(bool on) /* initialise the lcd controller inside the s5l8700 */ static void lcd_controller_init(void) { - PWRCON &= ~(1 << 18); - - LCDCON1 = 0x991DC; - LCDCON2 = 0xE8; - LCDTCON1 = (lcd_type == 1) ? 0x70103 : 0x30303; - LCDTCON2 = (lcd_type == 1) ? 0x70103 : 0x30703; - LCDTCON3 = 0x9F8EF; + PWRCON &= ~(1 << 18); + + LCDCON1 = (0 << 28) | /* BURSTLEN */ + (0 << 19) | /* DIVEN */ + (12 << 13) | /* CLKVAL */ + (1 << 12) | /* CLKDIR, 1=divided clock */ + (0 << 11) | /* CLKSEL, 0=HCLK, 1=PLL */ + (5 << 6) | /* BPPMODEF, 5=rgb565, 7=raw24 */ + (5 << 2) | /* BPPMODEB, 5=rgb565, 7=raw24 */ + (0 << 0); /* ENVID */ + LCDCON2 = (2 << 9) | /* PALFRM, 2=rgb565 palette */ + (1 << 7) | /* IVCLK */ + (1 << 6) | /* IHSYNC */ + (1 << 5) | /* IVSYNC */ + (1 << 3); /* IVDEN */ + LCDTCON1 = (lcd_type == 1) ? 0x070103 : 0x030303; + LCDTCON2 = (lcd_type == 1) ? 0x070103 : 0x030703; + LCDTCON3 = ((LCD_HEIGHT - 1) << 11) | (LCD_WIDTH - 1); LCDOSD1 = 0; LCDOSD2 = 0; - LCDOSD3 = 0; + LCDOSD3 = 0; + LCDB1SADDR1 = 0; LCDB2SADDR1 = 0; LCDF1SADDR1 = 0; @@ -376,6 +396,7 @@ static void lcd_controller_init(void) LCDB2SADDR3 = 0; LCDF1SADDR3 = 0; LCDF2SADDR3 = 0; + LCDKEYCON = 0; LCDCOLVAL = 0; LCDBGCON = 0; @@ -387,21 +408,16 @@ static void lcd_controller_init(void) void lcd_init_device(void) { - unsigned int lcd_id; - + unsigned int lcd_id; + uint32_t fb, fb_end, window; + /* configure LCD SPI pins */ lcd_spi_init(); /* identify display through SPI */ lcd_id = lcd_read_reg(0); - lcd_type = (lcd_id == LCD_TYPE1_ID) ? 1 : 2; - - /* configure LCD pins */ - PCON_ASRAM = 1; + lcd_type = (lcd_id == LCD_TYPE1_ID) ? 1 : 2; - /* init LCD controller */ - lcd_controller_init(); - /* display specific init sequence */ if (lcd_type == 1) { lcd_init1(); @@ -409,35 +425,42 @@ void lcd_init_device(void) else { lcd_init2(); } + + /* init LCD controller */ + lcd_controller_init(); + + /* set framebuffer addresses */ + fb = (uint32_t) &lcd_framebuffer[0][0]; + fb_end = (uint32_t) &lcd_framebuffer[LCD_HEIGHT][0]; + window = 2 * LCD_WIDTH; + + LCDB1SADDR1 = fb; + LCDB2SADDR1 = fb; + LCDF1SADDR1 = fb; + LCDF2SADDR1 = fb; + + LCDB1SADDR2 = fb_end; + LCDB2SADDR2 = fb_end; + LCDF1SADDR2 = fb_end; LCDF2SADDR2 = fb_end; + + LCDB1SADDR3 = window; + LCDB2SADDR3 = window; + LCDF1SADDR3 = window; + LCDF2SADDR3 = window; - /* set active background buffer */ - LCDCON1 &= ~(1 << 21); /* clear BDBCON */ - - /* set background buffer address */ - LCDB1SADDR1 = (uint32_t) &lcd_local_fb[0][0]; - LCDB1SADDR2 = (uint32_t) &lcd_local_fb[LCD_HEIGHT][0]; - - lcd_enable(true); + lcd_enable(true); + + /* configure LCD pins */ + PCON_ASRAM = 1; } void lcd_update_rect(int x, int y, int width, int height) { - fb_data *src; - uint32_t *dst; - fb_data pixel; - int h, w; - - for (h = 0; h < height; h++) { - src = &lcd_framebuffer[y][x]; - dst = &lcd_local_fb[y][x]; - for (w = 0; w < width; w++) { - pixel = src[w]; - dst[w] = (RGB_UNPACK_RED(pixel) << 16) | - (RGB_UNPACK_GREEN(pixel) << 8) | - (RGB_UNPACK_BLUE(pixel) << 0); - } - y++; - } + /* not implemented yet, LCD controller accesses framebuffer directly */ + (void) x; + (void) y; + (void) width; + (void) height; } void lcd_update(void) -- cgit v1.2.3