summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Moń <desowin@gmail.com>2021-07-05 15:15:30 +0200
committerTomasz Moń <desowin@gmail.com>2021-07-05 15:19:52 +0200
commit2acf8db3e14e8c81f27cb0cea5b366678693c7b3 (patch)
tree95a60cd59f8debdfa7c5388a7ec4cdfbb4057176
parent89d3ca77b6ffd0ad499d91e8c66100f6d852e358 (diff)
downloadrockbox-2acf8db3e14e8c81f27cb0cea5b366678693c7b3.tar.gz
rockbox-2acf8db3e14e8c81f27cb0cea5b366678693c7b3.zip
Sansa Connect: Power off LCD to save power
Prevent startup screen flash by properly using AVR LCM functions. Power off LCD when not needed to improve battery runtime. Change-Id: I76e3c5c0208774f189fbc6f7d7b3c9e22c062285
-rw-r--r--bootloader/sansaconnect.c6
-rw-r--r--firmware/export/config/sansaconnect.h3
-rw-r--r--firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c5
-rw-r--r--firmware/target/arm/tms320dm320/sansa-connect/backlight-sansaconnect.c3
-rw-r--r--firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c117
5 files changed, 89 insertions, 45 deletions
diff --git a/bootloader/sansaconnect.c b/bootloader/sansaconnect.c
index a60fa71800..f154593818 100644
--- a/bootloader/sansaconnect.c
+++ b/bootloader/sansaconnect.c
@@ -239,9 +239,7 @@ void main(void)
239 font_init(); 239 font_init();
240 button_init(); 240 button_init();
241 241
242#ifdef HAVE_LCD_ENABLE
243 lcd_enable(true); 242 lcd_enable(true);
244#endif
245 lcd_setfont(FONT_SYSFIXED); 243 lcd_setfont(FONT_SYSFIXED);
246 reset_screen(); 244 reset_screen();
247 show_logo(); 245 show_logo();
@@ -288,10 +286,12 @@ void main(void)
288 286
289 if (ret > 0) 287 if (ret > 0)
290 { 288 {
289 lcd_enable(false);
291 system_prepare_fw_start(); 290 system_prepare_fw_start();
292 291
293 kernel_entry = (void*)0x01008000; 292 kernel_entry = (void*)0x01008000;
294 ret = kernel_entry(); 293 ret = kernel_entry();
294 lcd_enable(true);
295 printf("FAILED to boot OF"); 295 printf("FAILED to boot OF");
296 } 296 }
297 } 297 }
@@ -309,10 +309,12 @@ void main(void)
309 } 309 }
310 else 310 else
311 { 311 {
312 lcd_enable(false);
312 system_prepare_fw_start(); 313 system_prepare_fw_start();
313 314
314 kernel_entry = (void*) loadbuffer; 315 kernel_entry = (void*) loadbuffer;
315 ret = kernel_entry(); 316 ret = kernel_entry();
317 lcd_enable(true);
316 printf("FAILED!"); 318 printf("FAILED!");
317 } 319 }
318 320
diff --git a/firmware/export/config/sansaconnect.h b/firmware/export/config/sansaconnect.h
index 874b198316..5668d579fc 100644
--- a/firmware/export/config/sansaconnect.h
+++ b/firmware/export/config/sansaconnect.h
@@ -81,9 +81,8 @@
81#define LCD_PIXELFORMAT RGB565 /* rgb565 */ 81#define LCD_PIXELFORMAT RGB565 /* rgb565 */
82 82
83#define HAVE_LCD_ENABLE 83#define HAVE_LCD_ENABLE
84#ifndef BOOTLOADER
85#define HAVE_LCD_SLEEP 84#define HAVE_LCD_SLEEP
86#endif 85#define HAVE_LCD_SHUTDOWN
87 86
88#define LCD_SLEEP_TIMEOUT (2*HZ) 87#define LCD_SLEEP_TIMEOUT (2*HZ)
89 88
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c
index a8e0d5eb5e..8ebba3a8d5 100644
--- a/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c
+++ b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c
@@ -857,8 +857,3 @@ bool button_hold(void)
857{ 857{
858 return hold_switch; 858 return hold_switch;
859} 859}
860
861void lcd_enable(bool on)
862{
863 (void)on;
864}
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/backlight-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/backlight-sansaconnect.c
index c65d806635..37cb672738 100644
--- a/firmware/target/arm/tms320dm320/sansa-connect/backlight-sansaconnect.c
+++ b/firmware/target/arm/tms320dm320/sansa-connect/backlight-sansaconnect.c
@@ -52,13 +52,12 @@ static void _backlight_write_brightness(int brightness)
52 52
53void backlight_hw_on(void) 53void backlight_hw_on(void)
54{ 54{
55#ifdef HAVE_LCD_SLEEP
56 if (!lcd_active()) 55 if (!lcd_active())
57 { 56 {
58 lcd_awake(); 57 lcd_awake();
59 lcd_update(); 58 lcd_update();
60 } 59 }
61#endif 60
62 /* set GIO34 as PWM1 */ 61 /* set GIO34 as PWM1 */
63 IO_GIO_FSEL3 = (IO_GIO_FSEL3 & 0xFFF3) | (1 << 2); 62 IO_GIO_FSEL3 = (IO_GIO_FSEL3 & 0xFFF3) | (1 << 2);
64 63
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c
index 07be11e849..9d58fccdb3 100644
--- a/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c
+++ b/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c
@@ -29,60 +29,109 @@
29#include "lcd.h" 29#include "lcd.h"
30#include "lcd-target.h" 30#include "lcd-target.h"
31#include "avr-sansaconnect.h" 31#include "avr-sansaconnect.h"
32#include "backlight-target.h"
32 33
33extern bool lcd_on; /* lcd-memframe.c */ 34/* See lcd-memframe.c */
35extern void lcd_set_active(bool active);
36
37static bool lcd_powered;
34 38
35#if defined(HAVE_LCD_SLEEP)
36void lcd_sleep(void) 39void lcd_sleep(void)
37{ 40{
38 if (lcd_on) 41 if (lcd_powered)
39 { 42 {
40 lcd_on = false; 43 lcd_set_active(false);
41 44
42 avr_hid_lcm_sleep(); 45 avr_hid_lcm_power_off();
43 sleep(HZ/20); 46 mdelay(100);
44 47
48 /* Disable OSD window */
49 bitclr16(&IO_OSD_OSDWINMD0, 0x01);
45 /* disable video encoder */ 50 /* disable video encoder */
46 bitclr16(&IO_VID_ENC_VMOD, 0x01); 51 bitclr16(&IO_VID_ENC_VMOD, VENC_VMOD_VENC);
52 mdelay(66);
47 53
48 sleep(HZ/20); 54 /* disable video encoder and OSD clocks */
55 bitclr16(&IO_CLK_MOD1, CLK_MOD1_VENC | CLK_MOD1_OSD);
49 56
50 /* disable video encoder clock */ 57 lcd_powered = false;
51 bitclr16(&IO_CLK_MOD1, CLK_MOD1_VENC);
52 } 58 }
53} 59}
54 60
55void lcd_awake(void) 61void lcd_awake(void)
56{ 62{
57 if (!lcd_on) 63 if (!lcd_powered)
58 { 64 {
59 lcd_on = true; 65 /* Enable Video Encoder and OSD clocks */
66 bitset16(&IO_CLK_MOD1, CLK_MOD1_VENC | CLK_MOD1_OSD);
67 /* Enable OSD window */
68 bitset16(&IO_OSD_OSDWINMD0, 0x01);
69 /* Enable video encoder */
70 bitset16(&IO_VID_ENC_VMOD, VENC_VMOD_VENC);
71
72 avr_hid_lcm_power_on();
73 lcd_set_active(true);
74 avr_hid_lcm_wake();
60 75
61 /* enable video encoder clock */ 76 lcd_powered = true;
62 bitset16(&IO_CLK_MOD1, CLK_MOD1_VENC); 77 send_event(LCD_EVENT_ACTIVATION, NULL);
78 }
79}
63 80
64 /* enable video encoder */ 81void lcd_shutdown(void)
65 bitset16(&IO_VID_ENC_VMOD, 0x01); 82{
83 backlight_hw_off();
84 lcd_sleep();
85}
86
87void lcd_enable(bool enable)
88{
89 if (lcd_active() == enable)
90 return;
91
92 lcd_set_active(enable);
93
94 if (enable)
95 {
96 /* Enable Video Encoder and OSD clocks */
97 bitset16(&IO_CLK_MOD1, CLK_MOD1_VENC | CLK_MOD1_OSD);
98 /* Enable OSD window */
99 bitset16(&IO_OSD_OSDWINMD0, 0x01);
100 /* Enable video encoder */
101 bitset16(&IO_VID_ENC_VMOD, VENC_VMOD_VENC);
66 102
67 avr_hid_lcm_wake(); 103 avr_hid_lcm_wake();
104 mdelay(30);
68 105
69 send_event(LCD_EVENT_ACTIVATION, NULL); 106 send_event(LCD_EVENT_ACTIVATION, NULL);
107 }
108 else
109 {
110 mdelay(30);
111 avr_hid_lcm_sleep();
112 mdelay(10);
70 113
71 lcd_update(); 114 /* Disable OSD window */
115 bitclr16(&IO_OSD_OSDWINMD0, 0x01);
116 /* disable video encoder */
117 bitclr16(&IO_VID_ENC_VMOD, VENC_VMOD_VENC);
118 mdelay(66);
119
120 /* disable video encoder and OSD clocks */
121 bitclr16(&IO_CLK_MOD1, CLK_MOD1_VENC | CLK_MOD1_OSD);
72 } 122 }
73} 123}
74#endif
75 124
76void lcd_init_device(void) 125void lcd_init_device(void)
77{ 126{
78 unsigned int addr; 127 unsigned int addr;
79 128
80 /* Disable Video Encoder clock */ 129 /* Disable Video Encoder clock */
81 bitclr16(&IO_CLK_MOD1, CLK_MOD1_VENC); 130 bitclr16(&IO_CLK_MOD1, CLK_MOD1_VENC);
82 131
83 /* configure GIO39, GIO34 as outputs */ 132 /* configure GIO39, GIO34 as outputs */
84 IO_GIO_DIR2 &= ~((1 << 7) /* GIO39 */ | (1 << 2) /* GIO34 */); 133 IO_GIO_DIR2 &= ~((1 << 7) /* GIO39 */ | (1 << 2) /* GIO34 */);
85 134
86 IO_GIO_FSEL3 = (IO_GIO_FSEL3 & ~(0x300F)) | 135 IO_GIO_FSEL3 = (IO_GIO_FSEL3 & ~(0x300F)) |
87 (0x1000) /* GIO39 - FIELD_VENC */ | 136 (0x1000) /* GIO39 - FIELD_VENC */ |
88 (0x4); /* GIO34 - PWM1 (brightness control) */ 137 (0x4); /* GIO34 - PWM1 (brightness control) */
@@ -121,10 +170,9 @@ void lcd_init_device(void)
121 IO_VID_ENC_VMOD = 0x2015; /* OF sets 0x2011 */ 170 IO_VID_ENC_VMOD = 0x2015; /* OF sets 0x2011 */
122 171
123 /* Copy Rockbox frame buffer to the second framebuffer */ 172 /* Copy Rockbox frame buffer to the second framebuffer */
173 lcd_set_active(true);
124 lcd_update(); 174 lcd_update();
125 175
126 avr_hid_lcm_power_on();
127
128 /* set framebuffer address - OF sets RAM start address to 0x1000000 */ 176 /* set framebuffer address - OF sets RAM start address to 0x1000000 */
129 addr = ((int)FRAME-CONFIG_SDRAM_START)/32; 177 addr = ((int)FRAME-CONFIG_SDRAM_START)/32;
130 178
@@ -149,8 +197,9 @@ void lcd_init_device(void)
149 197
150 /* Enable Video Encoder - RGB666, custom timing */ 198 /* Enable Video Encoder - RGB666, custom timing */
151 IO_VID_ENC_VMOD = 0x2015; 199 IO_VID_ENC_VMOD = 0x2015;
200
201 lcd_powered = true;
152 avr_hid_lcm_wake(); 202 avr_hid_lcm_wake();
153 lcd_on = true;
154} 203}
155 204
156#ifdef LCD_USE_DMA 205#ifdef LCD_USE_DMA
@@ -167,14 +216,14 @@ static void dma_lcd_copy_buffer_rect(int x, int y, int width, int height)
167 /* Set source and destination addresses */ 216 /* Set source and destination addresses */
168 dst = (char*)(FRAME + LCD_WIDTH*y + x); 217 dst = (char*)(FRAME + LCD_WIDTH*y + x);
169 src = (char*)(FBADDR(x,y)); 218 src = (char*)(FBADDR(x,y));
170 219
171 /* Flush cache to memory */ 220 /* Flush cache to memory */
172 commit_dcache(); 221 commit_dcache();
173 222
174 /* Addresses are relative to start of SDRAM */ 223 /* Addresses are relative to start of SDRAM */
175 src -= CONFIG_SDRAM_START; 224 src -= CONFIG_SDRAM_START;
176 dst -= CONFIG_SDRAM_START; 225 dst -= CONFIG_SDRAM_START;
177 226
178 /* Enable Image Buffer clock */ 227 /* Enable Image Buffer clock */
179 bitset16(&IO_CLK_MOD1, CLK_MOD1_IMGBUF); 228 bitset16(&IO_CLK_MOD1, CLK_MOD1_IMGBUF);
180 229
@@ -191,7 +240,7 @@ static void dma_lcd_copy_buffer_rect(int x, int y, int width, int height)
191 240
192 /* Set the start address of buffer */ 241 /* Set the start address of buffer */
193 COP_BUF_ADDR = 0x0000; 242 COP_BUF_ADDR = 0x0000;
194 243
195 /* Setup SDRAM stride */ 244 /* Setup SDRAM stride */
196 COP_SDEM_LOFST = LCD_WIDTH; 245 COP_SDEM_LOFST = LCD_WIDTH;
197 246
@@ -200,28 +249,28 @@ static void dma_lcd_copy_buffer_rect(int x, int y, int width, int height)
200 249
201 addr = (int)src; 250 addr = (int)src;
202 addr >>= 1; /* Addresses are in 16-bit words */ 251 addr >>= 1; /* Addresses are in 16-bit words */
203 252
204 /* Setup the registers to initiate the read from SDRAM */ 253 /* Setup the registers to initiate the read from SDRAM */
205 COP_SDEM_ADDRH = addr >> 16; 254 COP_SDEM_ADDRH = addr >> 16;
206 COP_SDEM_ADDRL = addr & 0xFFFF; 255 COP_SDEM_ADDRL = addr & 0xFFFF;
207 256
208 /* Set direction and start */ 257 /* Set direction and start */
209 COP_DMA_CTRL = 0x0001; 258 COP_DMA_CTRL = 0x0001;
210 COP_DMA_CTRL |= 0x0002; 259 COP_DMA_CTRL |= 0x0002;
211 260
212 /* Wait for read to finish */ 261 /* Wait for read to finish */
213 while (COP_DMA_CTRL & 0x02) {}; 262 while (COP_DMA_CTRL & 0x02) {};
214 263
215 addr = (int)dst; 264 addr = (int)dst;
216 addr >>= 1; 265 addr >>= 1;
217 266
218 COP_SDEM_ADDRH = addr >> 16; 267 COP_SDEM_ADDRH = addr >> 16;
219 COP_SDEM_ADDRL = addr & 0xFFFF; 268 COP_SDEM_ADDRL = addr & 0xFFFF;
220 269
221 /* Set direction and start transfer */ 270 /* Set direction and start transfer */
222 COP_DMA_CTRL = 0x0000; 271 COP_DMA_CTRL = 0x0000;
223 COP_DMA_CTRL |= 0x0002; 272 COP_DMA_CTRL |= 0x0002;
224 273
225 /* Wait for the transfer to complete */ 274 /* Wait for the transfer to complete */
226 while (COP_DMA_CTRL & 0x02) {}; 275 while (COP_DMA_CTRL & 0x02) {};
227 276
@@ -246,7 +295,7 @@ void lcd_update_rect(int x, int y, int width, int height)
246 __attribute__ ((section(".icode"))); 295 __attribute__ ((section(".icode")));
247void lcd_update_rect(int x, int y, int width, int height) 296void lcd_update_rect(int x, int y, int width, int height)
248{ 297{
249 if (!lcd_on) 298 if (!lcd_active())
250 return; 299 return;
251 300
252 if ((width | height) < 0) 301 if ((width | height) < 0)
@@ -270,7 +319,7 @@ void lcd_update_rect(int x, int y, int width, int height)
270void lcd_update(void) __attribute__ ((section(".icode"))); 319void lcd_update(void) __attribute__ ((section(".icode")));
271void lcd_update(void) 320void lcd_update(void)
272{ 321{
273 if (!lcd_on) 322 if (!lcd_active())
274 return; 323 return;
275 324
276 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); 325 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);