summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Kurbjun <kkurbjun@gmail.com>2008-05-14 00:26:28 +0000
committerKarl Kurbjun <kkurbjun@gmail.com>2008-05-14 00:26:28 +0000
commit6e322c878695e9b6dbf5620feda76315a523cc43 (patch)
treefa752c8f5419c4c27dabcc53dedba2b0ad4f9f97
parentf7e0e6bb1cfc079cfbf18ce3224442be26ba46f2 (diff)
downloadrockbox-6e322c878695e9b6dbf5620feda76315a523cc43.zip
rockbox-6e322c878695e9b6dbf5620feda76315a523cc43.tar.gz
rockbox-6e322c878695e9b6dbf5620feda76315a523cc43.tar.bz2
rockbox-6e322c878695e9b6dbf5620feda76315a523cc43.tar.xz
Reduce power consumed on the F/X by as much as 12% when the LCD is disabled. Timing is tighter on the SPI interface, if the screen does not come up let me know and we can space it out more - Works on the devices I tested. There will be a brief time (around 15ms) that the screen is all white after coming back on.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17498 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c249
1 files changed, 144 insertions, 105 deletions
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c
index 90ab145..5c666b4 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c
@@ -66,17 +66,55 @@ inline void delay_cycles(volatile int delay)
while(delay>0) delay--;
}
-void SPI_LCD_CS(bool select)
+void LCD_CTRL_setup(void)
{
- delay_cycles(0x4FFF);
+ /* ENVID = 0, BPPMODE = 16 bpp, PNRMODE = TFT, MMODE = Each Frame, CLKVAL = 8 */
+ LCDCON1 = 0x878;
- GPBCON&=~0x30000;
- GPBCON|=0x10000;
+ /* VCPW = 1, VFPD = 5, LINEVAL = 319, VBPD = 7 */
+ LCDCON2 = 0x74FC141;
+
+ /* HFPD = 9, HOZVAL = 239, HBPD = 7 */
+ LCDCON3 = 0x38EF09;
- if(select)
- GPBDAT|=0x100;
- else
- GPBDAT&=~0x100;
+ /* HSPW = 7 */
+ LCDCON4 = 7;
+
+ /* HWSWP = 1, INVVFRAM = 1, INVVLINE = 1, FRM565 = 1, All others = 0 */
+ LCDCON5 = 0xB01;
+
+ LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME));
+ LCDSADDR2 = LCDBASEL((unsigned)FRAME);
+ LCDSADDR3 = 0x000000F0;
+}
+
+void LCD_CTRL_clock(bool onoff)
+{
+ if(onoff)
+ {
+ GPCCON &= ~0xFFF000FC;
+ GPDCON &= ~0xFFF0FFF0;
+
+ GPCCON |= 0xAAA000A8;
+ GPCUP |= 0xFC0E;
+
+ GPDCON |= 0xAAA0AAA0;
+ GPDUP |= 0xFCFC;
+
+ s3c_regset(&CLKCON, 0x20); /* enable LCD clock */
+ LCDCON1 |=0x01;
+ }
+ else
+ {
+ GPCCON &= ~0xFFF000FC;
+ GPCUP &= ~0xFC0E;
+
+ GPDCON &= ~0xFFF0FFF0;
+ GPDUP &= ~0xFCFC;
+
+ LCDCON1 &= ~1; /* Must diable first or bus may freeze */
+ s3c_regclr(&CLKCON, 0x20); /* disable LCD clock */
+ }
}
void reset_LCD(bool reset)
@@ -89,7 +127,7 @@ void reset_LCD(bool reset)
GPBDAT&=~0x80;
}
-void SPI_Send_Bytes(const unsigned char *array, int count)
+void LCD_SPI_send(const unsigned char *array, int count)
{
while (count--)
{
@@ -98,97 +136,80 @@ void SPI_Send_Bytes(const unsigned char *array, int count)
}
}
-void Setup_LCD_SPI(void)
+void LCD_SPI_SS(bool select)
{
- s3c_regset(&CLKCON, 0x40000);
- SPI_LCD_CS(false);
- SPCON0=0x3E;
- SPPRE0=24;
-}
+ delay_cycles(0x4FFF);
-void Setup_LCD_CTRL(void)
-{
- /* ENVID = 0, BPPMODE = 16 bpp, PNRMODE = TFT, MMODE = Each Frame, CLKVAL = 8 */
- LCDCON1 = 0x878;
+ GPBCON&=~0x30000;
+ GPBCON|=0x10000;
- /* VCPW = 1, VFPD = 5, LINEVAL = 319, VBPD = 7 */
- LCDCON2 = 0x74FC141;
-
- /* HFPD = 9, HOZVAL = 239, HBPD = 7 */
- LCDCON3 = 0x38EF09;
+ if(select)
+ GPBDAT|=0x100;
+ else
+ GPBDAT&=~0x100;
+}
- /* HSPW = 7 */
- LCDCON4 = 7;
-
- /* HWSWP = 1, INVVFRAM = 1, INVVLINE = 1, FRM565 = 1, All others = 0 */
- LCDCON5 = 0xB01;
+void LCD_SPI_start(void)
+{
+ s3c_regset(&CLKCON, 0x40000); /* enable SPI clock */
+ LCD_SPI_SS(false);
+ SPCON0=0x3E;
+ SPPRE0=24;
- LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME));
- LCDSADDR2 = LCDBASEL((unsigned)FRAME);
- LCDSADDR3 = 0x000000F0;
+ reset_LCD(true);
+ LCD_SPI_SS(true);
}
-/* LCD init */
-void lcd_init_device(void)
+void LCD_SPI_stop(void)
{
-#ifdef BOOTLOADER
- int i;
- /* When the Rockbox bootloader starts, we are changing framebuffer address,
- but we don't want what's shown on the LCD to change until we do an
- lcd_update(), so copy the data from the old framebuffer to the new one */
- unsigned short *buf = (unsigned short*)FRAME;
-
- memcpy(FRAME, (short *)((LCDSADDR1)<<1), 320*240*2);
-
- /* The Rockbox bootloader is transitioning from RGB555I to RGB565 mode
- so convert the frambuffer data accordingly */
- for(i=0; i< 320*240; i++){
- *buf = ((*buf>>1) & 0x1F) | (*buf & 0xffc0);
- buf++;
- }
-#endif
-
- /* Set pins up */
- GPCCON |= 0xAAA000A8;
- GPCUP |= 0xFC0E;
+ LCD_SPI_SS(false);
- GPDCON |= 0xAAA0AAA0;
- GPDUP |= 0xFCFC;
+ SPCON0 &= ~0x10;
+ s3c_regclr(&CLKCON, 0x40000); /* disable SPI clock */
+}
- GPHUP &= 0x600;
+void LCD_SPI_powerdown(void)
+{
+ const unsigned char powerdncmd[] =
+ {
+ 0,0x04,1,0x00
+ };
- GPECON |= 0x0A800000;
- GPEUP |= 0x3800;
+ LCD_SPI_start();
- GPBUP |= 0x181;
+ LCD_SPI_send(powerdncmd, sizeof(powerdncmd));
-#if !defined(BOOTLOADER)
- lcd_poweroff = false;
-#endif
+ LCD_SPI_stop();
- s3c_regset(&CLKCON, 0x20); /* enable LCD clock */
+ reset_LCD(false); /* This makes a big difference on power */
+ LCD_CTRL_clock(false);
+}
- Setup_LCD_SPI();
+void LCD_SPI_powerup(void)
+{
+ const unsigned char powerupcmd[] =
+ {
+ 0,0x04,1,0x01
+ };
- Setup_LCD_CTRL();
+ LCD_CTRL_clock(true);
- delay_cycles(0xA000);
+ LCD_SPI_start();
- reset_LCD(true);
- LCDCON1|=0x01;
+ LCD_SPI_send(powerupcmd, sizeof(powerupcmd));
- delay_cycles(0x80000);
+ LCD_SPI_stop();
+}
-#if 0
- /* Setup the appropriate screen modes */
- TCONSEL= 0xCE6;
-#endif
-
- /* SPI data - Right now we are not sure what each of these SPI writes is actually
- * telling the lcd. Many thanks to Alex Gerchanovsky for discovering them.
+void LCD_SPI_init(void)
+{
+ /* SPI data - Right now we are not sure what each of these SPI writes is
+ * actually telling the lcd. Many thanks to Alex Gerchanovsky for
+ * discovering them.
*
- * This looks like a register, data combination, 0 denoting a register address,
- * 1 denoting data. Addr 0x04 is used more than once and may be an enable.
+ * This looks like a register, data combination, 0 denoting a register
+ * address, 1 denoting data. Addr 0x04 is used more than once is
+ * an enable.
*/
const unsigned char initbuf[] =
{
@@ -219,11 +240,51 @@ void lcd_init_device(void)
0,0x04,1,0x01,
};
- SPI_LCD_CS(true);
- SPI_Send_Bytes(initbuf, sizeof(initbuf));
- SPI_LCD_CS(false);
+ LCD_CTRL_clock(true);
- s3c_regclr(&CLKCON, 0x40000); /* disable SPI clock */
+ LCD_SPI_start();
+
+ LCD_SPI_send(initbuf, sizeof(initbuf));
+
+ LCD_SPI_stop();
+}
+
+/* LCD init */
+void lcd_init_device(void)
+{
+ /* Set pins up */
+
+ GPHUP &= 0x600;
+
+ GPECON |= 0x0A800000;
+ GPEUP |= 0x3800;
+
+ GPBUP |= 0x181;
+
+ s3c_regset(&CLKCON, 0x20); /* enable LCD clock */
+
+ LCD_CTRL_setup();
+ LCD_SPI_init();
+}
+
+void lcd_enable(bool state)
+{
+ if(state)
+ {
+ if(!lcd_on)
+ {
+ lcd_on = true;
+ lcd_update();
+ LCD_SPI_powerup();
+ }
+ }
+ else
+ {
+ if(lcd_on) {
+ lcd_on = false;
+ LCD_SPI_powerdown();
+ }
+ }
}
/* Update a fraction of the display. */
@@ -266,28 +327,6 @@ void lcd_update_rect(int x, int y, int width, int height)
}
}
-void lcd_enable(bool state)
-{
- if(!lcd_poweroff)
- return;
- if(state)
- {
- if(!lcd_on)
- {
- lcd_on = true;
- lcd_update();
- LCDCON1 |= 1;
- }
- }
- else
- {
- if(lcd_on) {
- lcd_on = false;
- LCDCON1 &= ~1;
- }
- }
-}
-
/* Update the display.
This must be called after all other LCD functions that change the display. */
void lcd_update(void)