summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorKarl Kurbjun <kkurbjun@gmail.com>2009-04-01 03:21:18 +0000
committerKarl Kurbjun <kkurbjun@gmail.com>2009-04-01 03:21:18 +0000
commit4fa96fbc914ae8fd69aedafd73f4f1798679d29f (patch)
treeea0deb3e1573e1dfd540441002e58b403670d178 /firmware/target/arm
parenta606121dd860245328198ac773d454980191abc3 (diff)
downloadrockbox-4fa96fbc914ae8fd69aedafd73f4f1798679d29f.tar.gz
rockbox-4fa96fbc914ae8fd69aedafd73f4f1798679d29f.zip
M:Robe 500i: More LCD initialization, and beginnings of support for QVGA as well as VGA on the LCD. MPEGPlayer now works with reasonable performance on smaller videos, but YUV blitting persists after MPEGPlayer is left, some cleanup/changes to the initialization code. This should be functionally equivalent for the ZVM, but the #ifdef's may need to be added back for app.lds. Get the bootloader building again.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20598 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/tms320dm320/app.lds79
-rw-r--r--firmware/target/arm/tms320dm320/boot.lds28
-rwxr-xr-xfirmware/target/arm/tms320dm320/crt0.S105
-rw-r--r--firmware/target/arm/tms320dm320/mrobe-500/backlight-mr500.c4
-rw-r--r--firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c145
-rw-r--r--firmware/target/arm/tms320dm320/mrobe-500/power-mr500.c2
6 files changed, 210 insertions, 153 deletions
diff --git a/firmware/target/arm/tms320dm320/app.lds b/firmware/target/arm/tms320dm320/app.lds
index 902e093633..bc00c3463b 100644
--- a/firmware/target/arm/tms320dm320/app.lds
+++ b/firmware/target/arm/tms320dm320/app.lds
@@ -15,7 +15,11 @@ STARTUP(target/arm/tms320dm320/crt0.o)
15#define STUBOFFSET 0 15#define STUBOFFSET 0
16#endif 16#endif
17 17
18#include "cpu.h" 18#define LCD_BUFFER_SIZE (LCD_WIDTH*LCD_HEIGHT*2)
19
20/* must be 16Kb (0x4000) aligned */
21#define TTB_SIZE (0x4000)
22
19#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE - LCD_BUFFER_SIZE - TTB_SIZE 23#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE - LCD_BUFFER_SIZE - TTB_SIZE
20 24
21#define DRAMORIG 0x00900000 + STUBOFFSET 25#define DRAMORIG 0x00900000 + STUBOFFSET
@@ -28,6 +32,10 @@ STARTUP(target/arm/tms320dm320/crt0.o)
28/* Where the codec buffer ends, and the plugin buffer starts */ 32/* Where the codec buffer ends, and the plugin buffer starts */
29#define ENDADDR (ENDAUDIOADDR + CODECSIZE) 33#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
30 34
35#define LCDBEGIN (ENDADDR + PLUGINSIZE)
36
37#define TTBBEGIN (LCDBEGIN + LCD_BUFFER_SIZE)
38
31MEMORY 39MEMORY
32{ 40{
33 DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE 41 DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
@@ -40,7 +48,6 @@ SECTIONS
40 { 48 {
41 loadaddress = .; 49 loadaddress = .;
42 _loadaddress = .; 50 _loadaddress = .;
43 . = ALIGN(0x200);
44 *(.init.text) 51 *(.init.text)
45 *(.text*) 52 *(.text*)
46 *(.glue_7) 53 *(.glue_7)
@@ -55,20 +62,22 @@ SECTIONS
55 *(.rodata.str1.1) 62 *(.rodata.str1.1)
56 *(.rodata.str1.4) 63 *(.rodata.str1.4)
57 . = ALIGN(0x4); 64 . = ALIGN(0x4);
58
59 /* Pseudo-allocate the copies of the data sections */
60 _datacopy = .;
61 } > DRAM 65 } > DRAM
62 66
63 /* TRICK ALERT! For RAM execution, we put the .data section at the 67 .data :
64 same load address as the copy. Thus, we don't waste extra RAM
65 when we don't actually need the copy. */
66 .data : AT ( _datacopy )
67 { 68 {
68 _datastart = .;
69 *(.data*) 69 *(.data*)
70 . = ALIGN(0x4); 70 . = ALIGN(0x4);
71 _dataend = .; 71 } > DRAM
72
73 .bss (NOLOAD) :
74 {
75 _edata = .;
76 *(.bss*)
77 *(.ibss*)
78 *(COMMON)
79 . = ALIGN(0x4);
80 _end = .;
72 } > DRAM 81 } > DRAM
73 82
74 /DISCARD/ : 83 /DISCARD/ :
@@ -81,30 +90,22 @@ SECTIONS
81 _vectorsstart = .; 90 _vectorsstart = .;
82 *(.vectors); 91 *(.vectors);
83 _vectorsend = .; 92 _vectorsend = .;
84#ifndef CREATIVE_ZVx
85 } > IRAM AT> DRAM 93 } > IRAM AT> DRAM
86 94
87 _vectorscopy = LOADADDR(.vectors); 95 _vectorscopy = LOADADDR(.vectors);
88#else
89 } > IRAM
90#endif
91 96
92 .iram : 97 .iram :
93 { 98 {
94 _iramstart = .; 99 _iramstart = .;
95 *(.icode) 100 *(.icode)
96 *(.irodata) 101 *(.irodata*)
97 *(.idata) 102 *(.idata)
98 . = ALIGN(0x4); 103 . = ALIGN(0x4);
99 _iramend = .; 104 _iramend = .;
100#ifndef CREATIVE_ZVx
101 } > IRAM AT> DRAM 105 } > IRAM AT> DRAM
102 106
103 _iramcopy = LOADADDR(.iram); 107 _iramcopy = LOADADDR(.iram);
104#else 108
105 } > IRAM
106#endif
107
108 .ibss (NOLOAD) : 109 .ibss (NOLOAD) :
109 { 110 {
110 _iedata = .; 111 _iedata = .;
@@ -113,49 +114,49 @@ SECTIONS
113 _iend = .; 114 _iend = .;
114 } > IRAM 115 } > IRAM
115 116
116 .stack : 117 .stack (NOLOAD) :
117 { 118 {
118 *(.stack) 119 *(.stack)
119 stackbegin = .; 120 stackbegin = .;
120 . += 0x2000; 121 . += 0x2000;
121 stackend = .; 122 stackend = .;
122 } > IRAM 123 } > IRAM
124
125 . = ADDR(.bss) + SIZEOF(.bss) + SIZEOF(.vectors) + SIZEOF(.iram);
123 126
124#ifndef CREATIVE_ZVx 127 .audiobuf (NOLOAD) :
125 .bss ADDR(.data) + SIZEOF(.data) + SIZEOF(.iram) + SIZEOF(.vectors):
126#else
127 .bss ADDR(.data) + SIZEOF(.data):
128#endif
129 {
130 _edata = .;
131 *(.bss*)
132 *(COMMON)
133 . = ALIGN(0x4);
134 _end = .;
135 } > DRAM
136
137 .audiobuf ALIGN(4) :
138 { 128 {
129 . = ALIGN(4);
139 _audiobuffer = .; 130 _audiobuffer = .;
140 audiobuffer = .; 131 audiobuffer = .;
141 } > DRAM 132 } > DRAM
142 133
143 .audiobufend ENDAUDIOADDR: 134 .audiobufend ENDAUDIOADDR (NOLOAD) :
144 { 135 {
145 audiobufend = .; 136 audiobufend = .;
146 _audiobufend = .; 137 _audiobufend = .;
147 } > DRAM 138 } > DRAM
148 139
149 .codec ENDAUDIOADDR: 140 .codec ENDAUDIOADDR (NOLOAD) :
150 { 141 {
151 codecbuf = .; 142 codecbuf = .;
152 _codecbuf = .; 143 _codecbuf = .;
153 } 144 }
154 145
155 .plugin ENDADDR: 146 .plugin ENDADDR (NOLOAD) :
156 { 147 {
157 _pluginbuf = .; 148 _pluginbuf = .;
158 pluginbuf = .; 149 pluginbuf = .;
159 } 150 }
151
152 .lcdbuffer LCDBEGIN (NOLOAD) :
153 {
154 _lcdbuf = .;
155 }
156
157 .ttbtable TTBBEGIN (NOLOAD) :
158 {
159 _ttbstart = .;
160 }
160} 161}
161 162
diff --git a/firmware/target/arm/tms320dm320/boot.lds b/firmware/target/arm/tms320dm320/boot.lds
index 97274a2c04..e391526dc5 100644
--- a/firmware/target/arm/tms320dm320/boot.lds
+++ b/firmware/target/arm/tms320dm320/boot.lds
@@ -1,11 +1,17 @@
1#include "config.h" 1#include "config.h"
2 2
3ENTRY(start) 3ENTRY(start)
4
4OUTPUT_FORMAT(elf32-littlearm) 5OUTPUT_FORMAT(elf32-littlearm)
5OUTPUT_ARCH(arm) 6OUTPUT_ARCH(arm)
6STARTUP(target/arm/tms320dm320/crt0.o) 7STARTUP(target/arm/tms320dm320/crt0.o)
7 8
8#define DRAMSIZE (MEMORYSIZE * 0x100000) 9#define LCD_BUFFER_SIZE (LCD_WIDTH*LCD_HEIGHT*2)
10
11/* must be 16Kb (0x4000) aligned */
12#define TTB_SIZE (0x4000)
13
14#define DRAMSIZE (MEMORYSIZE * 0x100000) - TTB_SIZE - LCD_BUFFER_SIZE
9 15
10#define DRAMORIG 0x01900000 /* actually it's 0x00900000 */ 16#define DRAMORIG 0x01900000 /* actually it's 0x00900000 */
11#define IRAMORIG 0x00000000 17#define IRAMORIG 0x00000000
@@ -13,6 +19,12 @@ STARTUP(target/arm/tms320dm320/crt0.o)
13#define FLASHORIG 0x00100000 19#define FLASHORIG 0x00100000
14#define FLASHSIZE 8M 20#define FLASHSIZE 8M
15 21
22/* Now we have the LCD buffer */
23#define LCDBEGIN (DRAMSIZE+0x00900000)
24
25/* Finally the TTB table */
26#define TTBBEGIN (LCDBEGIN + LCD_BUFFER_SIZE)
27
16MEMORY 28MEMORY
17{ 29{
18 DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE 30 DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
@@ -28,6 +40,7 @@ SECTIONS
28 loadaddress = .; 40 loadaddress = .;
29 _loadaddress = .; 41 _loadaddress = .;
30 *(.init.text) 42 *(.init.text)
43 *(.icode)
31 *(.text*) 44 *(.text*)
32 *(.glue_7) 45 *(.glue_7)
33 *(.glue_7t) 46 *(.glue_7t)
@@ -40,6 +53,7 @@ SECTIONS
40 *(.rodata*) 53 *(.rodata*)
41 *(.rodata.str1.1) 54 *(.rodata.str1.1)
42 *(.rodata.str1.4) 55 *(.rodata.str1.4)
56 *(.irodata)
43 . = ALIGN(0x4); 57 . = ALIGN(0x4);
44 58
45 /* Pseudo-allocate the copies of the data sections */ 59 /* Pseudo-allocate the copies of the data sections */
@@ -47,8 +61,6 @@ SECTIONS
47 } > DRAM 61 } > DRAM
48 62
49 .data : { 63 .data : {
50 *(.icode)
51 *(.irodata)
52 *(.idata) 64 *(.idata)
53 *(.data*) 65 *(.data*)
54 . = ALIGN(0x4); 66 . = ALIGN(0x4);
@@ -84,4 +96,14 @@ SECTIONS
84 _vectorsend = .; 96 _vectorsend = .;
85 } AT > DRAM 97 } AT > DRAM
86 _vectorscopy = LOADADDR(.vectors); 98 _vectorscopy = LOADADDR(.vectors);
99
100 .lcdbuffer LCDBEGIN (NOLOAD) :
101 {
102 _lcdbuf = .;
103 }
104
105 .ttbtable TTBBEGIN (NOLOAD) :
106 {
107 _ttbstart = .;
108 }
87} 109}
diff --git a/firmware/target/arm/tms320dm320/crt0.S b/firmware/target/arm/tms320dm320/crt0.S
index 9375de7d0d..a5a965b9c2 100755
--- a/firmware/target/arm/tms320dm320/crt0.S
+++ b/firmware/target/arm/tms320dm320/crt0.S
@@ -30,20 +30,6 @@
30 30
31 .global start 31 .global start
32start: 32start:
33 .equ INTC_IRQ0, 0x00030508
34 .equ INTC_IRQ1, 0x0003050A
35 .equ INTC_IRQ2, 0x0003050C
36 .equ INTC_FIQ0, 0x00030500
37 .equ INTC_FIQ1, 0x00030502
38 .equ INTC_FIQ2, 0x00030504
39 .equ INTC_EINT0, 0x00030528
40 .equ INTC_EINT1, 0x0003052A
41 .equ INTC_EINT2, 0x0003052C
42 .equ INTC_FISEL0, 0x00030520
43 .equ INTC_FISEL1, 0x00030522
44 .equ INTC_FISEL2, 0x00030524
45 .equ INTC_MASK, 0xFFFFFFFF
46
47 msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ 33 msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
48 34
49#ifndef CREATIVE_ZVx 35#ifndef CREATIVE_ZVx
@@ -68,37 +54,6 @@ start:
68 orr r0, r0, #0x00000002 54 orr r0, r0, #0x00000002
69 mcr p15, 0, r0, c1, c0, 0 55 mcr p15, 0, r0, c1, c0, 0
70 56
71#if 0
72 /* mask interrupts */
73 ldr r1, =INTC_MASK
74 ldr r2, =INTC_IRQ0
75 strh r1, [r2]
76 ldr r2, =INTC_IRQ1
77 strh r1, [r2]
78 ldr r2, =INTC_IRQ2
79 strh r1, [r2]
80 ldr r2, =INTC_FIQ0
81 strh r1, [r2]
82 ldr r2, =INTC_FIQ1
83 strh r1, [r2]
84 ldr r2, =INTC_FIQ2
85 strh r1, [r2]
86
87 mov r1, #0
88 ldr r2, =INTC_EINT0
89 strh r1, [r2]
90 ldr r2, =INTC_EINT1
91 strh r1, [r2]
92 ldr r2, =INTC_EINT2
93 strh r1, [r2]
94 ldr r2, =INTC_FISEL0
95 strh r1, [r2]
96 ldr r2, =INTC_FISEL1
97 strh r1, [r2]
98 ldr r2, =INTC_FISEL2
99 strh r1, [r2]
100#endif
101
102#if !defined(BOOTLOADER) && !defined(STUB) 57#if !defined(BOOTLOADER) && !defined(STUB)
103 /* Zero out IBSS */ 58 /* Zero out IBSS */
104 ldr r2, =_iedata 59 ldr r2, =_iedata
@@ -122,25 +77,25 @@ start:
122#endif 77#endif
123#endif /* !BOOTLOADER,!STUB */ 78#endif /* !BOOTLOADER,!STUB */
124 79
125 /* Initialise bss section to zero */
126 ldr r2, =_edata
127 ldr r3, =_end
128 mov r4, #0
1291:
130 cmp r3, r2
131 strhi r4, [r2], #4
132 bhi 1b
133 80
134 /* Load stack munge value */ 81 /* Initialise bss section to zero */
135 ldr r4, =0xdeadbeef 82 ldr r2, =_edata
83 ldr r3, =_end
84 mov r4, #0
85bsszero:
86 cmp r3, r2
87 strhi r4, [r2], #4
88 bhi bsszero
136 89
137 /* Set up some stack and munge it with 0xdeadbeef */ 90 /* Set up some stack and munge it with 0xdeadbeef */
138 ldr r2, =stackbegin 91 ldr sp, =stackend
139 ldr r3, =stackend 92 mov r3, sp
1401: 93 ldr r2, =stackbegin
141 cmp r3, r2 94 ldr r4, =0xdeadbeef
142 strhi r4, [r2], #4 95stackmunge:
143 bhi 1b 96 cmp r3, r2
97 strhi r4, [r2], #4
98 bhi stackmunge
144 99
145 /* Set up stack for IRQ mode */ 100 /* Set up stack for IRQ mode */
146 msr cpsr_c, #0xd2 /* IRQ disabled, FIQ enabled */ 101 msr cpsr_c, #0xd2 /* IRQ disabled, FIQ enabled */
@@ -185,26 +140,14 @@ start_loc:
185 140
186/* Exception handlers. Will be copied to address 0 after memory remapping */ 141/* Exception handlers. Will be copied to address 0 after memory remapping */
187 .section .vectors,"aw" 142 .section .vectors,"aw"
188 ldr pc, [pc, #24] 143 b start
189 ldr pc, [pc, #24] 144 b undef_instr_handler
190 ldr pc, [pc, #24] 145 b software_int_handler
191 ldr pc, [pc, #24] 146 b prefetch_abort_handler
192 ldr pc, [pc, #24] 147 b data_abort_handler
193 ldr pc, [pc, #24] 148 b reserved_handler
194 ldr pc, [pc, #24] 149 b irq_handler
195 ldr pc, [pc, #24] 150 b fiq_handler
196
197 /* Exception vectors */
198 .global vectors
199vectors:
200 .word start
201 .word undef_instr_handler
202 .word software_int_handler
203 .word prefetch_abort_handler
204 .word data_abort_handler
205 .word reserved_handler
206 .word irq_handler
207 .word fiq_handler
208 151
209 .text 152 .text
210 153
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/backlight-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/backlight-mr500.c
index 855f10ef35..9df857ec31 100644
--- a/firmware/target/arm/tms320dm320/mrobe-500/backlight-mr500.c
+++ b/firmware/target/arm/tms320dm320/mrobe-500/backlight-mr500.c
@@ -30,7 +30,7 @@
30 30
31void _backlight_on(void) 31void _backlight_on(void)
32{ 32{
33#ifdef HAVE_LCD_SLEEP 33#if defined(HAVE_LCD_SLEEP) && !defined(BOOTLOADER)
34 backlight_lcd_sleep_countdown(false); /* stop counter */ 34 backlight_lcd_sleep_countdown(false); /* stop counter */
35#endif 35#endif
36#ifdef HAVE_LCD_ENABLE 36#ifdef HAVE_LCD_ENABLE
@@ -42,7 +42,7 @@ void _backlight_on(void)
42void _backlight_off(void) 42void _backlight_off(void)
43{ 43{
44 _backlight_set_brightness(0); 44 _backlight_set_brightness(0);
45#ifdef HAVE_LCD_SLEEP 45#if defined(HAVE_LCD_SLEEP) && !defined(BOOTLOADER)
46 /* Disable lcd after fade completes (when lcd_sleep timeout expires) */ 46 /* Disable lcd after fade completes (when lcd_sleep timeout expires) */
47 backlight_lcd_sleep_countdown(true); /* start countdown */ 47 backlight_lcd_sleep_countdown(true); /* start countdown */
48#endif 48#endif
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
index 1126f35149..0357b469d9 100644
--- a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
+++ b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
@@ -43,7 +43,6 @@ static bool lcd_on = true;
43static bool lcd_powered = true; 43static bool lcd_powered = true;
44#endif 44#endif
45 45
46volatile bool lcd_poweroff = false;
47/* 46/*
48** These are imported from lcd-16bit.c 47** These are imported from lcd-16bit.c
49*/ 48*/
@@ -65,6 +64,14 @@ void lcd_sleep()
65 /* "not powered" implies "disabled" */ 64 /* "not powered" implies "disabled" */
66 if (lcd_on) 65 if (lcd_on)
67 lcd_enable(false); 66 lcd_enable(false);
67
68 /* Disabling these saves another ~15mA */
69 IO_OSD_OSDWINMD0&=~(0x01);
70 IO_VID_ENC_VMOD&=~(0x01);
71
72 sleep(HZ/5);
73
74 /* Disabling the LCD saves ~50mA */
68 IO_GIO_BITCLR2=1<<4; 75 IO_GIO_BITCLR2=1<<4;
69 lcd_powered=false; 76 lcd_powered=false;
70 } 77 }
@@ -83,6 +90,11 @@ void lcd_enable(bool state)
83 if (!lcd_powered) 90 if (!lcd_powered)
84 { 91 {
85 lcd_powered=true; 92 lcd_powered=true;
93
94 IO_OSD_OSDWINMD0|=0x01;
95 IO_VID_ENC_VMOD|=0x01;
96
97 sleep(2);
86 IO_GIO_BITSET2=1<<4; 98 IO_GIO_BITSET2=1<<4;
87 /* Wait long enough for a frame to be written - yes, it 99 /* Wait long enough for a frame to be written - yes, it
88 * takes awhile. */ 100 * takes awhile. */
@@ -110,6 +122,41 @@ void lcd_init_device(void)
110 /* Clear the Frame */ 122 /* Clear the Frame */
111 memset16(FRAME, 0x0000, LCD_WIDTH*LCD_HEIGHT); 123 memset16(FRAME, 0x0000, LCD_WIDTH*LCD_HEIGHT);
112 124
125 /* Setup the LCD controller */
126 IO_VID_ENC_VMOD=0x2015;
127 IO_VID_ENC_VDCTL=0x2000;
128 IO_VID_ENC_VDPRO=0x0000;
129 IO_VID_ENC_SYNCTL=0x100E;
130 IO_VID_ENC_HSPLS=1; /* HSYNC pulse width */
131 IO_VID_ENC_VSPLS=1; /* VSYNC pulse width */
132
133 /* These calculations support 640x480 and 320x240 */
134 IO_VID_ENC_HINT=NATIVE_MAX_WIDTH+NATIVE_MAX_WIDTH/3;
135 IO_VID_ENC_HSTART=NATIVE_MAX_WIDTH/6; /* Front porch */
136 IO_VID_ENC_HVALID=NATIVE_MAX_WIDTH; /* Data valid */
137 IO_VID_ENC_VINT=NATIVE_MAX_HEIGHT+7;
138 IO_VID_ENC_VSTART=3;
139 IO_VID_ENC_VVALID=NATIVE_MAX_HEIGHT;
140
141 IO_VID_ENC_HSDLY=0x0000;
142 IO_VID_ENC_VSDLY=0x0000;
143 IO_VID_ENC_YCCTL=0x0000;
144 IO_VID_ENC_RGBCTL=0x0000;
145 IO_VID_ENC_RGBCLP=0xFF00;
146 IO_VID_ENC_LNECTL=0x0000;
147 IO_VID_ENC_CULLLNE=0x0000;
148 IO_VID_ENC_LCDOUT=0x0000;
149 IO_VID_ENC_BRTS=0x0000;
150 IO_VID_ENC_BRTW=0x0000;
151 IO_VID_ENC_ACCTL=0x0000;
152 IO_VID_ENC_PWMP=0x0000;
153 IO_VID_ENC_PWMW=0x0000;
154
155 IO_VID_ENC_DCLKCTL=0x0800;
156 IO_VID_ENC_DCLKPTN0=0x0001;
157
158
159 /* Setup the display */
113 IO_OSD_MODE=0x00ff; 160 IO_OSD_MODE=0x00ff;
114 IO_OSD_VIDWINMD=0x0002; 161 IO_OSD_VIDWINMD=0x0002;
115 IO_OSD_OSDWINMD0=0x2001; 162 IO_OSD_OSDWINMD0=0x2001;
@@ -117,21 +164,34 @@ void lcd_init_device(void)
117 IO_OSD_ATRMD=0x0000; 164 IO_OSD_ATRMD=0x0000;
118 IO_OSD_RECTCUR=0x0000; 165 IO_OSD_RECTCUR=0x0000;
119 166
120 IO_OSD_OSDWIN0OFST=(480*2) / 32; 167 IO_OSD_OSDWIN0OFST=(NATIVE_MAX_WIDTH*2) / 32;
168
121 addr = ((int)FRAME-CONFIG_SDRAM_START) / 32; 169 addr = ((int)FRAME-CONFIG_SDRAM_START) / 32;
122 IO_OSD_OSDWINADH=addr >> 16; 170 IO_OSD_OSDWINADH=addr >> 16;
123 IO_OSD_OSDWIN0ADL=addr & 0xFFFF; 171 IO_OSD_OSDWIN0ADL=addr & 0xFFFF;
172
173 IO_OSD_VIDWINADH=addr >> 16;
174 IO_OSD_VIDWIN0ADL=addr & 0xFFFF;
124 175
125 IO_OSD_BASEPX=80; 176 IO_OSD_BASEPX=IO_VID_ENC_HSTART;
126 IO_OSD_BASEPY=2; 177 IO_OSD_BASEPY=IO_VID_ENC_VSTART;
127 178
128 IO_OSD_OSDWIN0XP=0; 179 IO_OSD_OSDWIN0XP=0;
129 IO_OSD_OSDWIN0YP=0; 180 IO_OSD_OSDWIN0YP=0;
130 IO_OSD_OSDWIN0XL=480; 181
131 IO_OSD_OSDWIN0YL=640; 182 IO_OSD_OSDWIN0XL=NATIVE_MAX_WIDTH;
183 IO_OSD_OSDWIN0YL=NATIVE_MAX_HEIGHT;
184
185 /* Set pin 36 and 35 (LCD POWER and LCD RESOLUTION) to an output */
186 IO_GIO_DIR2&=!(3<<3);
132 187
133 /* Set pin 36 to an output */ 188#if NATIVE_MAX_HEIGHT > 320
134 IO_GIO_DIR2&=!(1<<4); 189 /* Set LCD resolution to VGA */
190 IO_GIO_BITSET2=1<<3;
191#else
192 /* Set LCD resolution to QVGA */
193 IO_GIO_BITCLR2=1<<3;
194#endif
135} 195}
136 196
137/* Update a fraction of the display. */ 197/* Update a fraction of the display. */
@@ -204,50 +264,79 @@ void lcd_update(void)
204#endif 264#endif
205} 265}
206 266
207/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ 267void lcd_blit_yuv(unsigned char * const src[3],
208extern void lcd_write_yuv420_lines(fb_data *dst, 268 int src_x, int src_y, int stride,
209 unsigned char chroma_buf[LCD_HEIGHT/2*3], 269 int x, int y, int width,
210 unsigned char const * const src[3], 270 int height) __attribute__ ((section(".icode")));
211 int width, 271
212 int stride);
213/* Performance function to blit a YUV bitmap directly to the LCD */ 272/* Performance function to blit a YUV bitmap directly to the LCD */
214/* For the Gigabeat - show it rotated */ 273/* Show it rotated so the LCD_WIDTH is now the height */
215/* So the LCD_WIDTH is now the height */
216void lcd_blit_yuv(unsigned char * const src[3], 274void lcd_blit_yuv(unsigned char * const src[3],
217 int src_x, int src_y, int stride, 275 int src_x, int src_y, int stride,
218 int x, int y, int width, int height) 276 int x, int y, int width, int height)
219{ 277{
220 /* Caches for chroma data so it only need be recaculated every other 278 /* Caches for chroma data so it only need be recaculated every other
221 line */ 279 line */
222 unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */
223 unsigned char const * yuv_src[3]; 280 unsigned char const * yuv_src[3];
224 off_t z; 281 off_t z;
225 282
283 /* Turn off the RGB buffer and enable the YUV buffer */
284 IO_OSD_OSDWINMD0&=~(0x01);
285 IO_OSD_VIDWINMD|=0x01;
286
226 if (!lcd_on) 287 if (!lcd_on)
227 return; 288 return;
289
290 /* y has to be at multiple of 2 or else it will mess up the HW (interleaving) */
291 y &= ~1;
228 292
229 /* Sorry, but width and height must be >= 2 or else */ 293 /* Sorry, but width and height must be >= 2 or else */
230 width &= ~1; 294 width &= ~1;
231 height >>= 1; 295 height>>=1;
232 296
233 fb_data *dst = (fb_data*)FRAME + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; 297 fb_data *dst = (fb_data*)FRAME + LCD_WIDTH*LCD_HEIGHT - x * LCD_WIDTH + y;
234 298
235 z = stride*src_y; 299 z = stride*src_y;
236 yuv_src[0] = src[0] + z + src_x; 300 yuv_src[0] = src[0] + z + src_x;
237 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); 301 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
238 yuv_src[2] = src[2] + (yuv_src[1] - src[1]); 302 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
239 303
240 do
241 { 304 {
242 lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, 305 do
243 stride); 306 {
244 307 register fb_data *c_dst=dst;
245 yuv_src[0] += stride << 1; /* Skip down two luma lines */ 308 register int c_width=width;
246 yuv_src[1] += stride >> 1; /* Skip down one chroma line */ 309 unsigned char const * c_yuv_src[3];
247 yuv_src[2] += stride >> 1; 310 c_yuv_src[0] = yuv_src[0];
248 dst -= 2; 311 c_yuv_src[1] = yuv_src[1];
312 c_yuv_src[2] = yuv_src[2];
313
314 do
315 {
316 /* This needs to be done in a block of 4 pixels */
317 *c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1];
318 *(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2];
319 c_dst-=LCD_WIDTH;
320 c_yuv_src[0]++;
321 *c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1];
322 *(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2];
323 c_dst-=LCD_WIDTH;
324 c_yuv_src[0]++;
325
326 c_yuv_src[1]++;
327 c_yuv_src[2]++;
328
329 c_width -= 2;
330 }
331 while (c_width > 0);
332
333 yuv_src[0] += stride << 1; /* Skip down two luma lines */
334 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
335 yuv_src[2] += stride >> 1;
336 dst+=2;
337 }
338 while (--height > 0);
249 } 339 }
250 while (--height > 0);
251} 340}
252 341
253void lcd_set_contrast(int val) { 342void lcd_set_contrast(int val) {
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/power-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/power-mr500.c
index 48a989a736..9fd976ec10 100644
--- a/firmware/target/arm/tms320dm320/mrobe-500/power-mr500.c
+++ b/firmware/target/arm/tms320dm320/mrobe-500/power-mr500.c
@@ -25,6 +25,7 @@
25#include "kernel.h" 25#include "kernel.h"
26#include "system.h" 26#include "system.h"
27#include "power.h" 27#include "power.h"
28#include "lcd.h"
28#include "pcf50606.h" 29#include "pcf50606.h"
29#include "backlight.h" 30#include "backlight.h"
30#include "backlight-target.h" 31#include "backlight-target.h"
@@ -71,6 +72,7 @@ void power_off(void)
71{ 72{
72 /* turn off backlight and wait for 1 second */ 73 /* turn off backlight and wait for 1 second */
73 _backlight_off(); 74 _backlight_off();
75 lcd_sleep();
74 sleep(HZ); 76 sleep(HZ);
75 /* Hard shutdown */ 77 /* Hard shutdown */
76 IO_GIO_DIR1&=~(1<<10); 78 IO_GIO_DIR1&=~(1<<10);