summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Wardell <rockbox@barrywardell.net>2007-04-23 23:26:23 +0000
committerBarry Wardell <rockbox@barrywardell.net>2007-04-23 23:26:23 +0000
commit7027c6a0f8ed85c176e77ceb019a282b6b3d69ac (patch)
tree872ff2cca2dc1ed957ca5508e86575bae54a171d
parent27b4a64f9b215bde49e2a50aba51698fd56dbd85 (diff)
downloadrockbox-7027c6a0f8ed85c176e77ceb019a282b6b3d69ac.tar.gz
rockbox-7027c6a0f8ed85c176e77ceb019a282b6b3d69ac.zip
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
-rw-r--r--firmware/export/config-e200.h5
-rw-r--r--firmware/export/pp5020.h2
-rw-r--r--firmware/target/arm/sandisk/sansa-e200/ata-e200.c23
-rw-r--r--firmware/target/arm/sandisk/sansa-e200/backlight-e200.c12
-rw-r--r--firmware/target/arm/sandisk/sansa-e200/backlight-target.h1
-rw-r--r--firmware/target/arm/sandisk/sansa-e200/lcd-e200.c84
6 files changed, 93 insertions, 34 deletions
diff --git a/firmware/export/config-e200.h b/firmware/export/config-e200.h
index 87d7e78fbb..c61b1376d5 100644
--- a/firmware/export/config-e200.h
+++ b/firmware/export/config-e200.h
@@ -16,6 +16,9 @@
16/* define this if you have a colour LCD */ 16/* define this if you have a colour LCD */
17#define HAVE_LCD_COLOR 17#define HAVE_LCD_COLOR
18 18
19/* define this if you have LCD enable function */
20#define HAVE_LCD_ENABLE
21
19#define HAVE_BACKLIGHT_BRIGHTNESS 22#define HAVE_BACKLIGHT_BRIGHTNESS
20/* Main LCD backlight brightness range and defaults */ 23/* Main LCD backlight brightness range and defaults */
21#define MIN_BRIGHTNESS_SETTING 1 24#define MIN_BRIGHTNESS_SETTING 1
@@ -125,7 +128,7 @@
125#define CONFIG_LED LED_VIRTUAL 128#define CONFIG_LED LED_VIRTUAL
126 129
127/* Define this if you have adjustable CPU frequency */ 130/* Define this if you have adjustable CPU frequency */
128/*#define HAVE_ADJUSTABLE_CPU_FREQ Let's say we don't for now*/ 131/*#define HAVE_ADJUSTABLE_CPU_FREQ*/
129 132
130#define BOOTFILE_EXT "mi4" 133#define BOOTFILE_EXT "mi4"
131#define BOOTFILE "rockbox." BOOTFILE_EXT 134#define BOOTFILE "rockbox." BOOTFILE_EXT
diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h
index 8f70794c79..7475cc7b61 100644
--- a/firmware/export/pp5020.h
+++ b/firmware/export/pp5020.h
@@ -123,11 +123,13 @@
123#define DEV_SER1 0x80 123#define DEV_SER1 0x80
124#define DEV_I2S 0x800 124#define DEV_I2S 0x800
125#define DEV_I2C 0x1000 125#define DEV_I2C 0x1000
126#define DEV_ATA 0x4000
126#define DEV_OPTO 0x10000 127#define DEV_OPTO 0x10000
127#define DEV_PIEZO 0x10000 128#define DEV_PIEZO 0x10000
128#define DEV_USB 0x400000 129#define DEV_USB 0x400000
129#define DEV_FIREWIRE 0x800000 130#define DEV_FIREWIRE 0x800000
130#define DEV_IDE0 0x2000000 131#define DEV_IDE0 0x2000000
132#define DEV_LCD 0x4000000
131 133
132/* Processors Control */ 134/* Processors Control */
133#define CPU_CTL (*(volatile unsigned long *)(0x60007000)) 135#define CPU_CTL (*(volatile unsigned long *)(0x60007000))
diff --git a/firmware/target/arm/sandisk/sansa-e200/ata-e200.c b/firmware/target/arm/sandisk/sansa-e200/ata-e200.c
index 3d6cb23d9c..b66984bec4 100644
--- a/firmware/target/arm/sandisk/sansa-e200/ata-e200.c
+++ b/firmware/target/arm/sandisk/sansa-e200/ata-e200.c
@@ -22,6 +22,7 @@
22#include "system.h" 22#include "system.h"
23#include <string.h> 23#include <string.h>
24#include "thread.h" 24#include "thread.h"
25#include "pp5024.h"
25 26
26#define NOINLINE_ATTR __attribute__((noinline)) /* don't inline the loops */ 27#define NOINLINE_ATTR __attribute__((noinline)) /* don't inline the loops */
27 28
@@ -359,9 +360,9 @@ void sd_init_device(void)
359 GPIOD_ENABLE |= (0x1f); 360 GPIOD_ENABLE |= (0x1f);
360 GPIOD_OUTPUT_EN |= (0x1f); 361 GPIOD_OUTPUT_EN |= (0x1f);
361 GPIOD_OUTPUT_VAL |= (0x1f); 362 GPIOD_OUTPUT_VAL |= (0x1f);
362 DEV_EN |= (1 << 14); /* Enable controller */ 363 DEV_EN |= DEV_ATA; /* Enable controller */
363 DEV_RS |= (1 << 14); /* Reset controller */ 364 DEV_RS |= DEV_ATA; /* Reset controller */
364 DEV_RS &=~(1 << 14); /* Clear Reset */ 365 DEV_RS &=~DEV_ATA; /* Clear Reset */
365 outl(0, 0x6000b000); 366 outl(0, 0x6000b000);
366 outl(0, 0x6000a000); /* Init DMA controller? */ 367 outl(0, 0x6000a000); /* Init DMA controller? */
367 368
@@ -478,6 +479,7 @@ int ata_read_sectors(IF_MV2(int drive,)
478 last_disk_activity = current_tick; 479 last_disk_activity = current_tick;
479 spinup_start = current_tick; 480 spinup_start = current_tick;
480 481
482 ata_enable(true);
481 ata_led(true); 483 ata_led(true);
482 484
483 timeout = current_tick + READ_TIMEOUT; 485 timeout = current_tick + READ_TIMEOUT;
@@ -528,6 +530,7 @@ int ata_read_sectors(IF_MV2(int drive,)
528 break; 530 break;
529 } 531 }
530 ata_led(false); 532 ata_led(false);
533 ata_enable(false);
531 534
532 mutex_unlock(&sd_mtx); 535 mutex_unlock(&sd_mtx);
533 536
@@ -551,6 +554,7 @@ int ata_write_sectors(IF_MV2(int drive,)
551 tSDCardInfo *card = &card_info[current_card]; 554 tSDCardInfo *card = &card_info[current_card];
552 555
553 mutex_lock(&sd_mtx); 556 mutex_lock(&sd_mtx);
557 ata_enable(true);
554 ata_led(true); 558 ata_led(true);
555 if(current_card == 0) 559 if(current_card == 0)
556 { 560 {
@@ -603,8 +607,10 @@ retry:
603 sd_read_response(&response, 1); 607 sd_read_response(&response, 1);
604 608
605 sd_wait_for_state(card, TRAN); 609 sd_wait_for_state(card, TRAN);
606 mutex_unlock(&sd_mtx);
607 ata_led(false); 610 ata_led(false);
611 ata_enable(false);
612 mutex_unlock(&sd_mtx);
613
608 return ret; 614 return ret;
609} 615}
610 616
@@ -667,7 +673,14 @@ int ata_soft_reset(void)
667 673
668void ata_enable(bool on) 674void ata_enable(bool on)
669{ 675{
670 (void)on; 676 if(on)
677 {
678 DEV_EN |= DEV_ATA; /* Enable controller */
679 }
680 else
681 {
682 DEV_EN &= ~DEV_ATA; /* Disable controller */
683 }
671} 684}
672 685
673unsigned short* ata_get_identify(void) 686unsigned short* ata_get_identify(void)
diff --git a/firmware/target/arm/sandisk/sansa-e200/backlight-e200.c b/firmware/target/arm/sandisk/sansa-e200/backlight-e200.c
index 19ef7dd8ed..bb67b5b489 100644
--- a/firmware/target/arm/sandisk/sansa-e200/backlight-e200.c
+++ b/firmware/target/arm/sandisk/sansa-e200/backlight-e200.c
@@ -18,25 +18,37 @@
18 ****************************************************************************/ 18 ****************************************************************************/
19#include "backlight-target.h" 19#include "backlight-target.h"
20#include "system.h" 20#include "system.h"
21#include "lcd.h"
21#include "backlight.h" 22#include "backlight.h"
22#include "i2c-pp.h" 23#include "i2c-pp.h"
23 24
24static unsigned short backlight_brightness; 25static unsigned short backlight_brightness;
26static bool backlight_is_on;
27
28int __backlight_is_on(void)
29{
30 return (int)backlight_is_on;
31}
25 32
26void __backlight_set_brightness(int brightness) 33void __backlight_set_brightness(int brightness)
27{ 34{
28 backlight_brightness = brightness; 35 backlight_brightness = brightness;
29 pp_i2c_send( 0x46, 0x23, backlight_brightness); 36 pp_i2c_send( 0x46, 0x23, backlight_brightness);
37 backlight_is_on = true;
30} 38}
31 39
32void __backlight_on(void) 40void __backlight_on(void)
33{ 41{
42 lcd_enable(true); /* power on lcd */
34 pp_i2c_send( 0x46, 0x23, backlight_brightness); 43 pp_i2c_send( 0x46, 0x23, backlight_brightness);
44 backlight_is_on = true;
35} 45}
36 46
37void __backlight_off(void) 47void __backlight_off(void)
38{ 48{
39 pp_i2c_send( 0x46, 0x23, 0x0); 49 pp_i2c_send( 0x46, 0x23, 0x0);
50 lcd_enable(false); /* power off lcd */
51 backlight_is_on = false;
40} 52}
41 53
42 54
diff --git a/firmware/target/arm/sandisk/sansa-e200/backlight-target.h b/firmware/target/arm/sandisk/sansa-e200/backlight-target.h
index 2227278985..ac256036b9 100644
--- a/firmware/target/arm/sandisk/sansa-e200/backlight-target.h
+++ b/firmware/target/arm/sandisk/sansa-e200/backlight-target.h
@@ -23,6 +23,7 @@
23void __backlight_on(void); 23void __backlight_on(void);
24void __backlight_off(void); 24void __backlight_off(void);
25void __backlight_set_brightness(int brightness); 25void __backlight_set_brightness(int brightness);
26int __backlight_is_on(void);
26 27
27void __button_backlight_on(void); 28void __button_backlight_on(void);
28void __button_backlight_off(void); 29void __button_backlight_off(void);
diff --git a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c
index 9f6cf7fc11..07bc72c3c1 100644
--- a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c
+++ b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c
@@ -23,6 +23,8 @@
23#include "lcd.h" 23#include "lcd.h"
24#include "system.h" 24#include "system.h"
25#include <string.h> 25#include <string.h>
26#include "backlight-target.h"
27#include "pp5024.h"
26 28
27#define LCD_DATA_IN_GPIO GPIOB_INPUT_VAL 29#define LCD_DATA_IN_GPIO GPIOB_INPUT_VAL
28#define LCD_DATA_IN_PIN 6 30#define LCD_DATA_IN_PIN 6
@@ -141,12 +143,12 @@ inline void lcd_init_device(void)
141 outl(((inl(0x70000010) & (0x03ffffff)) | (0x15 << 26)), 0x70000010); 143 outl(((inl(0x70000010) & (0x03ffffff)) | (0x15 << 26)), 0x70000010);
142 outl(((inl(0x70000014) & (0x0fffffff)) | (0x5 << 28)), 0x70000014); 144 outl(((inl(0x70000014) & (0x0fffffff)) | (0x5 << 28)), 0x70000014);
143 outl((inl(0x70000020) & ~(0x3 << 10)), 0x70000020); 145 outl((inl(0x70000020) & ~(0x3 << 10)), 0x70000020);
144 DEV_EN |= (1 << 26); /* Enable controller */ 146 DEV_EN |= DEV_LCD; /* Enable controller */
145 outl(0x6, 0x600060d0); 147 outl(0x6, 0x600060d0);
146 DEV_RS |= (1 << 26); /* Reset controller */ 148 DEV_RS |= DEV_LCD; /* Reset controller */
147 outl((inl(0x70000020) & ~(1 << 14)), 0x70000020); 149 outl((inl(0x70000020) & ~(1 << 14)), 0x70000020);
148 lcd_bus_idle(); 150 lcd_bus_idle();
149 DEV_RS &=~(1 << 26); /* Clear reset */ 151 DEV_RS &=~DEV_LCD; /* Clear reset */
150 udelay(1000); 152 udelay(1000);
151 153
152 LCD_REG_0 = (LCD_REG_0 & (0x00ffffff)) | (0x22 << 24); 154 LCD_REG_0 = (LCD_REG_0 & (0x00ffffff)) | (0x22 << 24);
@@ -247,40 +249,66 @@ inline void lcd_init_device(void)
247 lcd_send_msg(0x70, 34); 249 lcd_send_msg(0x70, 34);
248} 250}
249 251
252void lcd_enable(bool on)
253{
254 if(on)
255 {
256 DEV_EN |= DEV_LCD; /* Enable LCD controller */
257 LCD_REG_6 |= 1; /* Enable DMA */
258 }
259 else
260 {
261 if(DEV_EN & DEV_LCD)
262 {
263 LCD_REG_6 &= ~1; /* Disable DMA */
264 udelay(20000); /* Wait for dma end (assuming 50Hz) */
265 DEV_EN &= ~DEV_LCD; /* Disable LCD controller */
266 }
267 }
268}
269
250inline void lcd_update_rect(int x, int y, int width, int height) 270inline void lcd_update_rect(int x, int y, int width, int height)
251{ 271{
252 (void)x; 272 (void)x;
253 (void)width; 273 (void)width;
254 /* Turn off DMA and wait for the transfer to complete */
255 /* TODO: Work out the proper delay */
256 LCD_REG_6 &= ~1;
257 udelay(1000);
258
259 /* Copy the Rockbox framebuffer to the second framebuffer */
260 /* TODO: Move the second framebuffer into uncached SDRAM */
261 memcpy(((char*)&lcd_driver_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH),
262 ((char *)&lcd_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH),
263 ((height * sizeof(fb_data) * LCD_WIDTH)));
264 flush_icache();
265 274
266 /* Restart DMA */ 275 if(__backlight_is_on())
267 LCD_REG_6 |= 1; 276 {
277 /* Turn off DMA and wait for the transfer to complete */
278 /* TODO: Work out the proper delay */
279 LCD_REG_6 &= ~1;
280 udelay(1000);
281
282 /* Copy the Rockbox framebuffer to the second framebuffer */
283 /* TODO: Move the second framebuffer into uncached SDRAM */
284 memcpy(((char*)&lcd_driver_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH),
285 ((char *)&lcd_framebuffer)+(y * sizeof(fb_data) * LCD_WIDTH),
286 ((height * sizeof(fb_data) * LCD_WIDTH)));
287 flush_icache();
288
289 /* Restart DMA */
290 LCD_REG_6 |= 1;
291 }
268} 292}
269 293
270inline void lcd_update(void) 294inline void lcd_update(void)
271{ 295{
272 /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer 296 if(__backlight_is_on())
273 * and lcd_framebuffer */ 297 {
274 /* Turn off DMA and wait for the transfer to complete */ 298 /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer
275 LCD_REG_6 &= ~1; 299 * and lcd_framebuffer */
276 udelay(1000); 300 /* Turn off DMA and wait for the transfer to complete */
277 301 LCD_REG_6 &= ~1;
278 /* Copy the Rockbox framebuffer to the second framebuffer */ 302 udelay(1000);
279 memcpy(lcd_driver_framebuffer, lcd_framebuffer, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT); 303
280 flush_icache(); 304 /* Copy the Rockbox framebuffer to the second framebuffer */
281 305 memcpy(lcd_driver_framebuffer, lcd_framebuffer,
282 /* Restart DMA */ 306 sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT);
283 LCD_REG_6 |= 1; 307 flush_icache();
308
309 /* Restart DMA */
310 LCD_REG_6 |= 1;
311 }
284} 312}
285 313
286 314