forked from len0rd/rockbox
FS#7036: Power saving improvements for Sansa. Shutdown LCD controller when backlight is off and shutdown ATA controller when the disk isn't being accessed. Frequency scaling is not enabled yet as it was apparently causing some problems.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13250 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
27b4a64f9b
commit
7027c6a0f8
6 changed files with 90 additions and 31 deletions
|
@ -16,6 +16,9 @@
|
||||||
/* define this if you have a colour LCD */
|
/* define this if you have a colour LCD */
|
||||||
#define HAVE_LCD_COLOR
|
#define HAVE_LCD_COLOR
|
||||||
|
|
||||||
|
/* define this if you have LCD enable function */
|
||||||
|
#define HAVE_LCD_ENABLE
|
||||||
|
|
||||||
#define HAVE_BACKLIGHT_BRIGHTNESS
|
#define HAVE_BACKLIGHT_BRIGHTNESS
|
||||||
/* Main LCD backlight brightness range and defaults */
|
/* Main LCD backlight brightness range and defaults */
|
||||||
#define MIN_BRIGHTNESS_SETTING 1
|
#define MIN_BRIGHTNESS_SETTING 1
|
||||||
|
@ -125,7 +128,7 @@
|
||||||
#define CONFIG_LED LED_VIRTUAL
|
#define CONFIG_LED LED_VIRTUAL
|
||||||
|
|
||||||
/* Define this if you have adjustable CPU frequency */
|
/* Define this if you have adjustable CPU frequency */
|
||||||
/*#define HAVE_ADJUSTABLE_CPU_FREQ Let's say we don't for now*/
|
/*#define HAVE_ADJUSTABLE_CPU_FREQ*/
|
||||||
|
|
||||||
#define BOOTFILE_EXT "mi4"
|
#define BOOTFILE_EXT "mi4"
|
||||||
#define BOOTFILE "rockbox." BOOTFILE_EXT
|
#define BOOTFILE "rockbox." BOOTFILE_EXT
|
||||||
|
|
|
@ -123,11 +123,13 @@
|
||||||
#define DEV_SER1 0x80
|
#define DEV_SER1 0x80
|
||||||
#define DEV_I2S 0x800
|
#define DEV_I2S 0x800
|
||||||
#define DEV_I2C 0x1000
|
#define DEV_I2C 0x1000
|
||||||
|
#define DEV_ATA 0x4000
|
||||||
#define DEV_OPTO 0x10000
|
#define DEV_OPTO 0x10000
|
||||||
#define DEV_PIEZO 0x10000
|
#define DEV_PIEZO 0x10000
|
||||||
#define DEV_USB 0x400000
|
#define DEV_USB 0x400000
|
||||||
#define DEV_FIREWIRE 0x800000
|
#define DEV_FIREWIRE 0x800000
|
||||||
#define DEV_IDE0 0x2000000
|
#define DEV_IDE0 0x2000000
|
||||||
|
#define DEV_LCD 0x4000000
|
||||||
|
|
||||||
/* Processors Control */
|
/* Processors Control */
|
||||||
#define CPU_CTL (*(volatile unsigned long *)(0x60007000))
|
#define CPU_CTL (*(volatile unsigned long *)(0x60007000))
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
#include "pp5024.h"
|
||||||
|
|
||||||
#define NOINLINE_ATTR __attribute__((noinline)) /* don't inline the loops */
|
#define NOINLINE_ATTR __attribute__((noinline)) /* don't inline the loops */
|
||||||
|
|
||||||
|
@ -359,9 +360,9 @@ void sd_init_device(void)
|
||||||
GPIOD_ENABLE |= (0x1f);
|
GPIOD_ENABLE |= (0x1f);
|
||||||
GPIOD_OUTPUT_EN |= (0x1f);
|
GPIOD_OUTPUT_EN |= (0x1f);
|
||||||
GPIOD_OUTPUT_VAL |= (0x1f);
|
GPIOD_OUTPUT_VAL |= (0x1f);
|
||||||
DEV_EN |= (1 << 14); /* Enable controller */
|
DEV_EN |= DEV_ATA; /* Enable controller */
|
||||||
DEV_RS |= (1 << 14); /* Reset controller */
|
DEV_RS |= DEV_ATA; /* Reset controller */
|
||||||
DEV_RS &=~(1 << 14); /* Clear Reset */
|
DEV_RS &=~DEV_ATA; /* Clear Reset */
|
||||||
outl(0, 0x6000b000);
|
outl(0, 0x6000b000);
|
||||||
outl(0, 0x6000a000); /* Init DMA controller? */
|
outl(0, 0x6000a000); /* Init DMA controller? */
|
||||||
|
|
||||||
|
@ -478,6 +479,7 @@ int ata_read_sectors(IF_MV2(int drive,)
|
||||||
last_disk_activity = current_tick;
|
last_disk_activity = current_tick;
|
||||||
spinup_start = current_tick;
|
spinup_start = current_tick;
|
||||||
|
|
||||||
|
ata_enable(true);
|
||||||
ata_led(true);
|
ata_led(true);
|
||||||
|
|
||||||
timeout = current_tick + READ_TIMEOUT;
|
timeout = current_tick + READ_TIMEOUT;
|
||||||
|
@ -528,6 +530,7 @@ int ata_read_sectors(IF_MV2(int drive,)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ata_led(false);
|
ata_led(false);
|
||||||
|
ata_enable(false);
|
||||||
|
|
||||||
mutex_unlock(&sd_mtx);
|
mutex_unlock(&sd_mtx);
|
||||||
|
|
||||||
|
@ -551,6 +554,7 @@ int ata_write_sectors(IF_MV2(int drive,)
|
||||||
tSDCardInfo *card = &card_info[current_card];
|
tSDCardInfo *card = &card_info[current_card];
|
||||||
|
|
||||||
mutex_lock(&sd_mtx);
|
mutex_lock(&sd_mtx);
|
||||||
|
ata_enable(true);
|
||||||
ata_led(true);
|
ata_led(true);
|
||||||
if(current_card == 0)
|
if(current_card == 0)
|
||||||
{
|
{
|
||||||
|
@ -603,8 +607,10 @@ retry:
|
||||||
sd_read_response(&response, 1);
|
sd_read_response(&response, 1);
|
||||||
|
|
||||||
sd_wait_for_state(card, TRAN);
|
sd_wait_for_state(card, TRAN);
|
||||||
mutex_unlock(&sd_mtx);
|
|
||||||
ata_led(false);
|
ata_led(false);
|
||||||
|
ata_enable(false);
|
||||||
|
mutex_unlock(&sd_mtx);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,7 +673,14 @@ int ata_soft_reset(void)
|
||||||
|
|
||||||
void ata_enable(bool on)
|
void ata_enable(bool on)
|
||||||
{
|
{
|
||||||
(void)on;
|
if(on)
|
||||||
|
{
|
||||||
|
DEV_EN |= DEV_ATA; /* Enable controller */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEV_EN &= ~DEV_ATA; /* Disable controller */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short* ata_get_identify(void)
|
unsigned short* ata_get_identify(void)
|
||||||
|
|
|
@ -18,25 +18,37 @@
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "backlight-target.h"
|
#include "backlight-target.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
#include "lcd.h"
|
||||||
#include "backlight.h"
|
#include "backlight.h"
|
||||||
#include "i2c-pp.h"
|
#include "i2c-pp.h"
|
||||||
|
|
||||||
static unsigned short backlight_brightness;
|
static unsigned short backlight_brightness;
|
||||||
|
static bool backlight_is_on;
|
||||||
|
|
||||||
|
int __backlight_is_on(void)
|
||||||
|
{
|
||||||
|
return (int)backlight_is_on;
|
||||||
|
}
|
||||||
|
|
||||||
void __backlight_set_brightness(int brightness)
|
void __backlight_set_brightness(int brightness)
|
||||||
{
|
{
|
||||||
backlight_brightness = brightness;
|
backlight_brightness = brightness;
|
||||||
pp_i2c_send( 0x46, 0x23, backlight_brightness);
|
pp_i2c_send( 0x46, 0x23, backlight_brightness);
|
||||||
|
backlight_is_on = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __backlight_on(void)
|
void __backlight_on(void)
|
||||||
{
|
{
|
||||||
|
lcd_enable(true); /* power on lcd */
|
||||||
pp_i2c_send( 0x46, 0x23, backlight_brightness);
|
pp_i2c_send( 0x46, 0x23, backlight_brightness);
|
||||||
|
backlight_is_on = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __backlight_off(void)
|
void __backlight_off(void)
|
||||||
{
|
{
|
||||||
pp_i2c_send( 0x46, 0x23, 0x0);
|
pp_i2c_send( 0x46, 0x23, 0x0);
|
||||||
|
lcd_enable(false); /* power off lcd */
|
||||||
|
backlight_is_on = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
void __backlight_on(void);
|
void __backlight_on(void);
|
||||||
void __backlight_off(void);
|
void __backlight_off(void);
|
||||||
void __backlight_set_brightness(int brightness);
|
void __backlight_set_brightness(int brightness);
|
||||||
|
int __backlight_is_on(void);
|
||||||
|
|
||||||
void __button_backlight_on(void);
|
void __button_backlight_on(void);
|
||||||
void __button_backlight_off(void);
|
void __button_backlight_off(void);
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "backlight-target.h"
|
||||||
|
#include "pp5024.h"
|
||||||
|
|
||||||
#define LCD_DATA_IN_GPIO GPIOB_INPUT_VAL
|
#define LCD_DATA_IN_GPIO GPIOB_INPUT_VAL
|
||||||
#define LCD_DATA_IN_PIN 6
|
#define LCD_DATA_IN_PIN 6
|
||||||
|
@ -141,12 +143,12 @@ inline void lcd_init_device(void)
|
||||||
outl(((inl(0x70000010) & (0x03ffffff)) | (0x15 << 26)), 0x70000010);
|
outl(((inl(0x70000010) & (0x03ffffff)) | (0x15 << 26)), 0x70000010);
|
||||||
outl(((inl(0x70000014) & (0x0fffffff)) | (0x5 << 28)), 0x70000014);
|
outl(((inl(0x70000014) & (0x0fffffff)) | (0x5 << 28)), 0x70000014);
|
||||||
outl((inl(0x70000020) & ~(0x3 << 10)), 0x70000020);
|
outl((inl(0x70000020) & ~(0x3 << 10)), 0x70000020);
|
||||||
DEV_EN |= (1 << 26); /* Enable controller */
|
DEV_EN |= DEV_LCD; /* Enable controller */
|
||||||
outl(0x6, 0x600060d0);
|
outl(0x6, 0x600060d0);
|
||||||
DEV_RS |= (1 << 26); /* Reset controller */
|
DEV_RS |= DEV_LCD; /* Reset controller */
|
||||||
outl((inl(0x70000020) & ~(1 << 14)), 0x70000020);
|
outl((inl(0x70000020) & ~(1 << 14)), 0x70000020);
|
||||||
lcd_bus_idle();
|
lcd_bus_idle();
|
||||||
DEV_RS &=~(1 << 26); /* Clear reset */
|
DEV_RS &=~DEV_LCD; /* Clear reset */
|
||||||
udelay(1000);
|
udelay(1000);
|
||||||
|
|
||||||
LCD_REG_0 = (LCD_REG_0 & (0x00ffffff)) | (0x22 << 24);
|
LCD_REG_0 = (LCD_REG_0 & (0x00ffffff)) | (0x22 << 24);
|
||||||
|
@ -247,40 +249,66 @@ inline void lcd_init_device(void)
|
||||||
lcd_send_msg(0x70, 34);
|
lcd_send_msg(0x70, 34);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lcd_enable(bool on)
|
||||||
|
{
|
||||||
|
if(on)
|
||||||
|
{
|
||||||
|
DEV_EN |= DEV_LCD; /* Enable LCD controller */
|
||||||
|
LCD_REG_6 |= 1; /* Enable DMA */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(DEV_EN & DEV_LCD)
|
||||||
|
{
|
||||||
|
LCD_REG_6 &= ~1; /* Disable DMA */
|
||||||
|
udelay(20000); /* Wait for dma end (assuming 50Hz) */
|
||||||
|
DEV_EN &= ~DEV_LCD; /* Disable LCD controller */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void lcd_update_rect(int x, int y, int width, int height)
|
inline void lcd_update_rect(int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
(void)x;
|
(void)x;
|
||||||
(void)width;
|
(void)width;
|
||||||
/* Turn off DMA and wait for the transfer to complete */
|
|
||||||
/* TODO: Work out the proper delay */
|
|
||||||
LCD_REG_6 &= ~1;
|
|
||||||
udelay(1000);
|
|
||||||
|
|
||||||
/* Copy the Rockbox framebuffer to the second framebuffer */
|
if(__backlight_is_on())
|
||||||
/* TODO: Move the second framebuffer into uncached SDRAM */
|
{
|
||||||
memcpy(((char*)&lcd_driver_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH),
|
/* Turn off DMA and wait for the transfer to complete */
|
||||||
((char *)&lcd_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH),
|
/* TODO: Work out the proper delay */
|
||||||
((height * sizeof(fb_data) * LCD_WIDTH)));
|
LCD_REG_6 &= ~1;
|
||||||
flush_icache();
|
udelay(1000);
|
||||||
|
|
||||||
/* Restart DMA */
|
/* Copy the Rockbox framebuffer to the second framebuffer */
|
||||||
LCD_REG_6 |= 1;
|
/* TODO: Move the second framebuffer into uncached SDRAM */
|
||||||
|
memcpy(((char*)&lcd_driver_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH),
|
||||||
|
((char *)&lcd_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH),
|
||||||
|
((height * sizeof(fb_data) * LCD_WIDTH)));
|
||||||
|
flush_icache();
|
||||||
|
|
||||||
|
/* Restart DMA */
|
||||||
|
LCD_REG_6 |= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void lcd_update(void)
|
inline void lcd_update(void)
|
||||||
{
|
{
|
||||||
/* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer
|
if(__backlight_is_on())
|
||||||
* and lcd_framebuffer */
|
{
|
||||||
/* Turn off DMA and wait for the transfer to complete */
|
/* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer
|
||||||
LCD_REG_6 &= ~1;
|
* and lcd_framebuffer */
|
||||||
udelay(1000);
|
/* Turn off DMA and wait for the transfer to complete */
|
||||||
|
LCD_REG_6 &= ~1;
|
||||||
|
udelay(1000);
|
||||||
|
|
||||||
/* Copy the Rockbox framebuffer to the second framebuffer */
|
/* Copy the Rockbox framebuffer to the second framebuffer */
|
||||||
memcpy(lcd_driver_framebuffer, lcd_framebuffer, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT);
|
memcpy(lcd_driver_framebuffer, lcd_framebuffer,
|
||||||
flush_icache();
|
sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT);
|
||||||
|
flush_icache();
|
||||||
|
|
||||||
/* Restart DMA */
|
/* Restart DMA */
|
||||||
LCD_REG_6 |= 1;
|
LCD_REG_6 |= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue