Index: firmware/export/config/ipodnano2g.h =================================================================== --- firmware/export/config/ipodnano2g.h (revision 28328) +++ firmware/export/config/ipodnano2g.h (working copy) @@ -41,9 +41,6 @@ /* define this to enable JPEG decoding */ #define HAVE_JPEG -/* define this if the LCD can shut down */ -#define HAVE_LCD_SHUTDOWN - /* define this if you can invert the colours on your LCD */ //#define HAVE_LCD_INVERT @@ -88,12 +85,16 @@ #define LCD_DEPTH 16 /* pseudo 262.144 colors */ #define LCD_PIXELFORMAT RGB565 /* rgb565 */ +/* Define this if the LCD can shut down */ +#define HAVE_LCD_SHUTDOWN + /* 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. */ -//#define HAVE_LCD_SLEEP +#define HAVE_LCD_SLEEP +#define HAVE_LCD_SLEEP_SETTING #define CONFIG_KEYPAD IPOD_4G_PAD Index: firmware/target/arm/s5l8700/boot.lds =================================================================== --- firmware/target/arm/s5l8700/boot.lds (revision 28328) +++ firmware/target/arm/s5l8700/boot.lds (working copy) @@ -9,8 +9,13 @@ OUTPUT_ARCH(arm) STARTUP(target/arm/s5l8700/crt0.o) +#ifdef IPOD_NANO2G +#define DRAMORIG 0x08000000 + ((MEMORYSIZE - 1) * 0x100000) +#define DRAMSIZE 0x00100000 +#else #define DRAMORIG 0x08000000 #define DRAMSIZE (MEMORYSIZE * 0x100000) +#endif #define IRAMORIG 0x22000000 #if CONFIG_CPU==S5L8701 @@ -39,19 +44,25 @@ #if defined(IPOD_NANO2G) || defined(MEIZU_M6SL) #define LOAD_AREA IRAM #else +#define NEEDS_INTVECT_COPYING #define LOAD_AREA FLASH #endif SECTIONS { +#ifdef NEEDS_INTVECT_COPYING .intvect : { _intvectstart = . ; *(.intvect) _intvectend = _newstart ; } >IRAM AT> LOAD_AREA _intvectcopy = LOADADDR(.intvect) ; +#endif .text : { +#ifndef NEEDS_INTVECT_COPYING + *(.intvect) +#endif *(.init.text) *(.text*) *(.glue_7*) @@ -90,12 +101,8 @@ _fiqstackend = .; } > IRAM - . = DRAMORIG; -#ifdef IPOD_NANO2G - /* The bss section is too large for IRAM - we just move it 12MB into the - DRAM */ - . += (12*1024*1024); -#endif + /* The bss section is too large for IRAM on the Nano 2G, thanks to the FTL. + We just move it 31MB into the DRAM */ .bss (NOLOAD) : { _edata = .; *(.bss*); @@ -104,5 +111,9 @@ *(COMMON); . = ALIGN(0x4); _end = .; +#ifdef IPOD_NANO2G } > DRAM +#else + } > IRAM +#endif } Index: firmware/target/arm/s5l8700/crt0.S =================================================================== --- firmware/target/arm/s5l8700/crt0.S (revision 28328) +++ firmware/target/arm/s5l8700/crt0.S (working copy) @@ -49,11 +49,7 @@ .global _newstart /* Exception vectors */ start: -#if CONFIG_CPU==S5L8701 && defined(BOOTLOADER) - b newstart2 -#else b _newstart -#endif ldr pc, =undef_instr_handler ldr pc, =software_int_handler ldr pc, =prefetch_abort_handler @@ -66,9 +62,11 @@ #endif .ltorg _newstart: +#if CONFIG_CPU!=S5L8701 || !defined(BOOTLOADER) ldr pc, =newstart2 // we do not want to execute from 0x0 as iram will be mapped there .section .init.text,"ax",%progbits newstart2: +#endif msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ #ifdef ROCKBOX_BIG_ENDIAN @@ -77,7 +75,7 @@ orr r0, r0, r1 mcr 15, 0, r0, c1, c0, 0 // set bigendian #endif - + ldr r1, =0x3c800000 // disable watchdog mov r0, #0xa5 str r0, [r1] Index: firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c =================================================================== --- firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c (revision 28328) +++ firmware/target/arm/s5l8700/ipodnano2g/lcd-nano2g.c (working copy) @@ -57,14 +57,341 @@ #define R_ROW_ADDR_SET 0x2b #define R_MEMORY_WRITE 0x2c - /** globals **/ int lcd_type; /* also needed in debug-s5l8700.c */ static int xoffset; /* needed for flip */ +static bool lcd_ispowered; -/** hardware access functions */ +#if !defined(BOOTLOADER) +#define SLEEP 0 +#define CMD8 1 +#define CMD16 2 +#define DATA8 3 +#define DATA16 4 + +unsigned short lcd_init_sequence_0[] = { + CMD16, 0x00a4, + DATA16, 0x0001, + SLEEP, 0x0000, + CMD16, 0x0001, + DATA16, 0x0100, + CMD16, 0x0002, + DATA16, 0x0300, + CMD16, 0x0003, + DATA16, 0x1230, + CMD16, 0x0008, + DATA16, 0x0404, + CMD16, 0x0008, + DATA16, 0x0404, + CMD16, 0x000e, + DATA16, 0x0010, + CMD16, 0x0070, + DATA16, 0x1000, + CMD16, 0x0071, + DATA16, 0x0001, + CMD16, 0x0030, + DATA16, 0x0002, + CMD16, 0x0031, + DATA16, 0x0400, + CMD16, 0x0032, + DATA16, 0x0007, + CMD16, 0x0033, + DATA16, 0x0500, + CMD16, 0x0034, + DATA16, 0x0007, + CMD16, 0x0035, + DATA16, 0x0703, + CMD16, 0x0036, + DATA16, 0x0507, + CMD16, 0x0037, + DATA16, 0x0005, + CMD16, 0x0038, + DATA16, 0x0407, + CMD16, 0x0039, + DATA16, 0x000e, + CMD16, 0x0040, + DATA16, 0x0202, + CMD16, 0x0041, + DATA16, 0x0003, + CMD16, 0x0042, + DATA16, 0x0000, + CMD16, 0x0043, + DATA16, 0x0200, + CMD16, 0x0044, + DATA16, 0x0707, + CMD16, 0x0045, + DATA16, 0x0407, + CMD16, 0x0046, + DATA16, 0x0505, + CMD16, 0x0047, + DATA16, 0x0002, + CMD16, 0x0048, + DATA16, 0x0004, + CMD16, 0x0049, + DATA16, 0x0004, + CMD16, 0x0060, + DATA16, 0x0202, + CMD16, 0x0061, + DATA16, 0x0003, + CMD16, 0x0062, + DATA16, 0x0000, + CMD16, 0x0063, + DATA16, 0x0200, + CMD16, 0x0064, + DATA16, 0x0707, + CMD16, 0x0065, + DATA16, 0x0407, + CMD16, 0x0066, + DATA16, 0x0505, + CMD16, 0x0068, + DATA16, 0x0004, + CMD16, 0x0069, + DATA16, 0x0004, + CMD16, 0x0007, + DATA16, 0x0001, + CMD16, 0x0018, + DATA16, 0x0001, + CMD16, 0x0010, + DATA16, 0x1690, + CMD16, 0x0011, + DATA16, 0x0100, + CMD16, 0x0012, + DATA16, 0x0117, + CMD16, 0x0013, + DATA16, 0x0f80, + CMD16, 0x0012, + DATA16, 0x0137, + CMD16, 0x0020, + DATA16, 0x0000, + CMD16, 0x0021, + DATA16, 0x0000, + CMD16, 0x0050, + DATA16, 0x0000, + CMD16, 0x0051, + DATA16, 0x00af, + CMD16, 0x0052, + DATA16, 0x0000, + CMD16, 0x0053, + DATA16, 0x0083, + CMD16, 0x0090, + DATA16, 0x0003, + CMD16, 0x0091, + DATA16, 0x0000, + CMD16, 0x0092, + DATA16, 0x0101, + CMD16, 0x0098, + DATA16, 0x0400, + CMD16, 0x0099, + DATA16, 0x1302, + CMD16, 0x009a, + DATA16, 0x0202, + CMD16, 0x009b, + DATA16, 0x0200, + SLEEP, 0x0000, + CMD16, 0x0007, + DATA16, 0x0021, + CMD16, 0x0012, + DATA16, 0x0137, + SLEEP, 0x0000, + CMD16, 0x0007, + DATA16, 0x0021, + CMD16, 0x0012, + DATA16, 0x1137, + SLEEP, 0x0000, + CMD16, 0x0007, + DATA16, 0x0233, +}; +unsigned short lcd_init_sequence_1[] = { + CMD8, 0x01, + DATA8, 0x00, + SLEEP, 0, + CMD8, 0xB1, + DATA8, 0x16, + DATA8, 0x03, + CMD8, 0xB2, + DATA8, 0x17, + DATA8, 0x03, + CMD8, 0xB4, + DATA8, 0x00, + CMD8, 0xB6, + DATA8, 0x01, + CMD8, 0xB7, + DATA8, 0x00, + DATA8, 0x00, + DATA8, 0x02, + DATA8, 0x00, + DATA8, 0x06, + DATA8, 0x26, + DATA8, 0x2D, + DATA8, 0x27, + DATA8, 0x55, + DATA8, 0x27, + CMD8, 0xB8, + DATA8, 0x10, + CMD8, 0xB9, + DATA8, 0x52, + DATA8, 0x12, + DATA8, 0x03, + CMD8, 0xC0, + DATA8, 0x0A, + DATA8, 0x10, + DATA8, 0x10, + CMD8, 0xC2, + DATA8, 0x14, + DATA8, 0x23, + CMD8, 0xC3, + DATA8, 0x12, + DATA8, 0x23, + CMD8, 0xC6, + DATA8, 0x48, + CMD8, 0xE0, + DATA8, 0x20, + DATA8, 0x71, + DATA8, 0x17, + DATA8, 0x09, + DATA8, 0x70, + DATA8, 0x0C, + DATA8, 0x13, + DATA8, 0x25, + CMD8, 0xE1, + DATA8, 0x37, + DATA8, 0x00, + DATA8, 0x63, + DATA8, 0x11, + DATA8, 0xD9, + DATA8, 0x00, + DATA8, 0x12, + DATA8, 0x01, + CMD8, 0xE2, + DATA8, 0x42, + DATA8, 0x42, + DATA8, 0x60, + DATA8, 0x08, + DATA8, 0xB4, + DATA8, 0x07, + DATA8, 0x0E, + DATA8, 0x90, + CMD8, 0xE3, + DATA8, 0x47, + DATA8, 0x60, + DATA8, 0x66, + DATA8, 0x09, + DATA8, 0x6A, + DATA8, 0x02, + DATA8, 0x0E, + DATA8, 0x09, + CMD8, 0xE4, + DATA8, 0x11, + DATA8, 0x40, + DATA8, 0x03, + DATA8, 0x0A, + DATA8, 0xC1, + DATA8, 0x0D, + DATA8, 0x17, + DATA8, 0x30, + CMD8, 0xE5, + DATA8, 0x00, + DATA8, 0x30, + DATA8, 0x77, + DATA8, 0x1C, + DATA8, 0xFB, + DATA8, 0x00, + DATA8, 0x13, + DATA8, 0x07, + CMD8, 0xE6, + DATA8, 0x01, + CMD8, 0x35, + DATA8, 0x00, + CMD8, 0x36, + DATA8, 0x00, + CMD8, 0xF2, + DATA8, 0x40, + CMD8, 0xF3, + DATA8, 0x50, + CMD8, 0xFB, + DATA8, 0x01, + CMD8, 0x11, + DATA8, 0x00, + SLEEP, 0, + CMD8, 0x3A, + DATA8, 0x65, + CMD8, 0x29, + DATA8, 0x00, +}; + +unsigned short lcd_init_sequence_2[] = { + CMD8, 0x01, + SLEEP, 0, + CMD8, 0x11, + SLEEP, 0, + CMD8, 0x3a, + DATA8, 0x65, + CMD8, 0xab, + CMD8, 0x35, + DATA8, 0x00, + CMD8, 0xf2, + DATA8, 0x01, + CMD8, 0xe0, + DATA8, 0x71, + DATA8, 0x76, + DATA8, 0x25, + DATA8, 0x01, + DATA8, 0xa5, + DATA8, 0x09, + DATA8, 0x15, + DATA8, 0x11, + CMD8, 0xe1, + DATA8, 0x40, + DATA8, 0x21, + DATA8, 0x64, + DATA8, 0x13, + DATA8, 0xf3, + DATA8, 0x0b, + DATA8, 0x00, + DATA8, 0x00, + CMD8, 0xe2, + DATA8, 0x71, + DATA8, 0x65, + DATA8, 0x24, + DATA8, 0x08, + DATA8, 0x97, + DATA8, 0x01, + DATA8, 0x15, + DATA8, 0x11, + CMD8, 0xe3, + DATA8, 0x51, + DATA8, 0x01, + DATA8, 0x62, + DATA8, 0x13, + DATA8, 0xf3, + DATA8, 0x0b, + DATA8, 0x00, + DATA8, 0x00, + CMD8, 0xe4, + DATA8, 0x71, + DATA8, 0x57, + DATA8, 0x31, + DATA8, 0x01, + DATA8, 0x82, + DATA8, 0x04, + DATA8, 0x1f, + DATA8, 0x11, + CMD8, 0xe5, + DATA8, 0x64, + DATA8, 0x41, + DATA8, 0x64, + DATA8, 0x19, + DATA8, 0xb3, + DATA8, 0x09, + DATA8, 0x00, + DATA8, 0x00, + CMD8, 0x29, +}; + +#endif + static inline void s5l_lcd_write_cmd_data(int cmd, int data) { while (LCD_STATUS & 0x10); @@ -84,9 +411,23 @@ LCD_WCMD = cmd; } -static inline void s5l_lcd_write_data(int data) +static inline void s5l_lcd_write_wcmd(unsigned short cmd) { while (LCD_STATUS & 0x10); + LCD_WCMD = cmd >> 8; + while (LCD_STATUS & 0x10); + LCD_WCMD = cmd & 0xff; +} + +static inline void s5l_lcd_write_data(unsigned short data) +{ + while (LCD_STATUS & 0x10); + LCD_WDATA = data & 0xff; +} + +static inline void s5l_lcd_write_wdata(unsigned short data) +{ + while (LCD_STATUS & 0x10); LCD_WDATA = data >> 8; while (LCD_STATUS & 0x10); LCD_WDATA = data & 0xff; @@ -125,6 +466,85 @@ } } +bool lcd_active(void) +{ + return lcd_ispowered; +} + +void lcd_wakeup(void) +{ +#if !defined(BOOTLOADER) + unsigned short *lcd_init_sequence; + unsigned int lcd_init_sequence_length; + int type = lcd_type; + + PCON13 &= ~0xf; /* Set pin 0 to input */ + PCON14 &= ~0xf0; /* Set pin 1 to input */ + + if((((PDAT13 & 1) == 1) && ((PDAT14 & 2) == 2))|| + (((PDAT13 & 1) == 0) && ((PDAT14 & 2) == 0))) + { + type = 2; /* there is a third lcd type which behaves like a LDS176 but needs to be initialized differently */ + } + + pmu_write(0x2b, 1); + + if(type == 0) + { + lcd_init_sequence = lcd_init_sequence_0; + lcd_init_sequence_length = (sizeof(lcd_init_sequence_0) - 1)/sizeof(unsigned short); + } + else if(type == 1) + { + lcd_init_sequence = lcd_init_sequence_1; + lcd_init_sequence_length = (sizeof(lcd_init_sequence_1) - 1)/sizeof(unsigned short); + } + else + { + lcd_init_sequence = lcd_init_sequence_2; + lcd_init_sequence_length = (sizeof(lcd_init_sequence_2) - 1)/sizeof(unsigned short); + } + + /* reset the lcd chip */ + + LCD_RST_TIME = 0x7FFF; + LCD_DRV_RST = 0; + sleep(0); + LCD_DRV_RST = 1; + sleep(0); + + for(unsigned int i=0;i #include "config.h" +#include "kernel.h" #include "backlight.h" #include "backlight-target.h" #include "pmu-target.h" +#ifdef HAVE_LCD_SLEEP +void lcd_awake(void); +void lcd_update(void); +#endif void _backlight_set_brightness(int brightness) { @@ -33,6 +38,12 @@ void _backlight_on(void) { + if(pmu_read(0x29) == 1) return; +#ifdef HAVE_LCD_SLEEP + lcd_awake(); + lcd_update(); + sleep(HZ/10); +#endif pmu_write(0x29, 1); }