summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugin.c7
-rw-r--r--apps/plugin.h8
-rw-r--r--apps/plugins/doom/i_video.c95
-rw-r--r--apps/plugins/plugin.lds20
-rw-r--r--firmware/export/config-mrobe500.h37
-rw-r--r--firmware/export/lcd.h7
-rw-r--r--firmware/target/arm/tms320dm320/app.lds57
-rw-r--r--firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c241
8 files changed, 336 insertions, 136 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 17e9ac670b..087bf74a38 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -636,6 +636,13 @@ static const struct plugin_api rockbox_api = {
636#if defined(HAVE_LCD_MODES) 636#if defined(HAVE_LCD_MODES)
637 lcd_set_mode, 637 lcd_set_mode,
638#endif 638#endif
639
640#if defined(HAVE_LCD_MODES)
641#if HAVE_LCD_MODES & LCD_MODE_PAL256
642 lcd_blit_pal256,
643 lcd_pal256_update_pal,
644#endif
645#endif
639}; 646};
640 647
641int plugin_load(const char* plugin, const void* parameter) 648int plugin_load(const char* plugin, const void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index fdcf3c2afa..d38cc42ee7 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -794,6 +794,14 @@ struct plugin_api {
794#if defined(HAVE_LCD_MODES) 794#if defined(HAVE_LCD_MODES)
795 void (*lcd_set_mode)(int mode); 795 void (*lcd_set_mode)(int mode);
796#endif 796#endif
797
798#if defined(HAVE_LCD_MODES)
799#if HAVE_LCD_MODES & LCD_MODE_PAL256
800 void (*lcd_blit_pal256)(unsigned char *src, int src_x, int src_y, int x, int y,
801 int width, int height);
802 void (*lcd_pal256_update_pal)(fb_data *palette);
803#endif
804#endif
797}; 805};
798 806
799/* plugin header */ 807/* plugin header */
diff --git a/apps/plugins/doom/i_video.c b/apps/plugins/doom/i_video.c
index c148d17077..418fcd4404 100644
--- a/apps/plugins/doom/i_video.c
+++ b/apps/plugins/doom/i_video.c
@@ -140,6 +140,12 @@ static fb_data *paldata=NULL;
140// 140//
141void I_ShutdownGraphics(void) 141void I_ShutdownGraphics(void)
142{ 142{
143#if defined(HAVE_LCD_MODES)
144#if (HAVE_LCD_MODES & LCD_MODE_PAL256)
145 rb->lcd_set_mode(LCD_MODE_RGB565);
146#endif
147#endif
148
143#ifndef HAVE_LCD_COLOR 149#ifndef HAVE_LCD_COLOR
144 grey_release(); 150 grey_release();
145#endif 151#endif
@@ -597,13 +603,19 @@ static void I_UploadNewPalette(int pal)
597 } 603 }
598 604
599#ifdef RANGECHECK 605#ifdef RANGECHECK
600 if ((size_t)pal >= num_pals) 606 if ((size_t)pal >= num_pals)
601 I_Error("I_UploadNewPalette: Palette number out of range (%d>=%d)", 607 I_Error("I_UploadNewPalette: Palette number out of range (%d>=%d)",
602 pal, num_pals); 608 pal, num_pals);
603#endif 609#endif
604 memcpy(palette,paldata+256*pal,256*sizeof(fb_data));
605}
606 610
611 memcpy(palette,paldata+256*pal,256*sizeof(fb_data));
612
613#if defined(HAVE_LCD_MODES)
614#if (HAVE_LCD_MODES & LCD_MODE_PAL256)
615 rb->lcd_pal256_update_pal(paldata+256*pal);
616#endif
617#endif
618}
607 619
608// 620//
609// I_FinishUpdate 621// I_FinishUpdate
@@ -613,36 +625,37 @@ void I_FinishUpdate (void)
613{ 625{
614 int count; 626 int count;
615 byte *src = d_screens[0]; 627 byte *src = d_screens[0];
628
616#if (CONFIG_LCD == LCD_H300) && !defined(SIMULATOR) 629#if (CONFIG_LCD == LCD_H300) && !defined(SIMULATOR)
617 count = SCREENWIDTH*SCREENHEIGHT; 630 count = SCREENWIDTH*SCREENHEIGHT;
618 631
619 /* ASM screen update (drops ~300 tics) */ 632 /* ASM screen update (drops ~300 tics) */
620 asm volatile ( 633 asm volatile (
621 "move.w #33, (%[LCD]) \n" /* Setup the LCD controller */ 634 "move.w #33, (%[LCD]) \n" /* Setup the LCD controller */
622 "nop \n" 635 "nop \n"
623 "clr.w (%[LCD2]) \n" 636 "clr.w (%[LCD2]) \n"
624 "nop \n" 637 "nop \n"
625 "move.w #34, (%[LCD]) \n" /* End LCD controller setup */ 638 "move.w #34, (%[LCD]) \n" /* End LCD controller setup */
626 "clr.l %%d1 \n" 639 "clr.l %%d1 \n"
627 ".loop: \n" 640 ".loop: \n"
628 "move.l (%[scrp])+, %%d0 \n" 641 "move.l (%[scrp])+, %%d0 \n"
629 "swap.w %%d0 \n" 642 "swap.w %%d0 \n"
630 "move.w %%d0, %%d1 \n" 643 "move.w %%d0, %%d1 \n"
631 "lsr.l #8,%%d1 \n" 644 "lsr.l #8,%%d1 \n"
632 "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n" 645 "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
633 "move.b %%d0,%%d1 \n" 646 "move.b %%d0,%%d1 \n"
634 "swap.w %%d0 \n" 647 "swap.w %%d0 \n"
635 "nop \n" 648 "nop \n"
636 "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n" 649 "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
637 "move.w %%d0, %%d1 \n" 650 "move.w %%d0, %%d1 \n"
638 "lsr.l #8,%%d1 \n" 651 "lsr.l #8,%%d1 \n"
639 "nop \n" 652 "nop \n"
640 "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n" 653 "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
641 "move.b %%d0,%%d1 \n" 654 "move.b %%d0,%%d1 \n"
642 "nop \n" 655 "nop \n"
643 "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n" 656 "move.w (%[pal], %%d1.l:2), (%[LCD2]) \n"
644 "subq.l #4,%[cnt] \n" 657 "subq.l #4,%[cnt] \n"
645 "bne.b .loop \n" 658 "bne.b .loop \n"
646 : /* outputs */ 659 : /* outputs */
647 [scrp]"+a"(src), 660 [scrp]"+a"(src),
648 [cnt] "+d"(count) 661 [cnt] "+d"(count)
@@ -713,7 +726,14 @@ void I_FinishUpdate (void)
713 "d0", "d1", "d2", "d3" 726 "d0", "d1", "d2", "d3"
714 ); 727 );
715#else 728#else
716#ifdef HAVE_LCD_COLOR 729
730/* If the hardware has support for a paletted mode it takes precidence */
731#if defined(HAVE_LCD_MODES)
732#if (HAVE_LCD_MODES & LCD_MODE_PAL256)
733 (void) count;
734 rb->lcd_blit_pal256(src, 0, 0, 0, 0, LCD_WIDTH, LCD_HEIGHT);
735#endif
736#elif defined(HAVE_LCD_COLOR)
717#if(LCD_HEIGHT>LCD_WIDTH) 737#if(LCD_HEIGHT>LCD_WIDTH)
718 if(rotate_screen) 738 if(rotate_screen)
719 { 739 {
@@ -742,8 +762,9 @@ void I_FinishUpdate (void)
742 *dst++ = palette[*src++]; 762 *dst++ = palette[*src++];
743 while (--count); 763 while (--count);
744 } 764 }
745 rb->lcd_update(); 765 rb->lcd_update();
746#else /* !HAVE_LCD_COLOR */ 766#else /* !HAVE_LCD_COLOR */
767
747 unsigned char *dst; 768 unsigned char *dst;
748 int y; 769 int y;
749 770
@@ -758,8 +779,8 @@ void I_FinishUpdate (void)
758 779
759 grey_ub_gray_bitmap(greybuffer, 0, y, SCREENWIDTH, 1); 780 grey_ub_gray_bitmap(greybuffer, 0, y, SCREENWIDTH, 1);
760 } 781 }
761#endif /* !HAVE_LCD_COLOR */ 782#endif
762#endif 783#endif
763} 784}
764 785
765// 786//
@@ -786,6 +807,12 @@ void I_InitGraphics(void)
786 printf("Starting Graphics engine\n"); 807 printf("Starting Graphics engine\n");
787 808
788 noprintf=1; 809 noprintf=1;
810
811#if defined(HAVE_LCD_MODES)
812#if (HAVE_LCD_MODES & LCD_MODE_PAL256)
813 rb->lcd_set_mode(LCD_MODE_PAL256);
814#endif
815#endif
789 816
790 /* Note: The other screens are allocated as needed */ 817 /* Note: The other screens are allocated as needed */
791 818
diff --git a/apps/plugins/plugin.lds b/apps/plugins/plugin.lds
index 9c65f31779..d6f62341ce 100644
--- a/apps/plugins/plugin.lds
+++ b/apps/plugins/plugin.lds
@@ -35,18 +35,20 @@ OUTPUT_FORMAT(elf32-littlemips)
35#define NOCACHE_BASE 0x00000000 35#define NOCACHE_BASE 0x00000000
36#endif 36#endif
37 37
38#if CONFIG_CPU==DM320 || CONFIG_CPU==S3C2440 38#if CONFIG_CPU==DM320 || CONFIG_CPU==IMX31L
39#define LCD_BUFFER_SIZE (LCD_WIDTH*LCD_HEIGHT*2) 39/* Give this 1 meg to allow it to align to the MMU boundary */
40#define LCD_TTB_AREA 0x100000
41#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_TTB_AREA
40 42
43#elif CONFIG_CPU==S3C2440
44#define LCD_BUFFER_SIZE (LCD_WIDTH*LCD_HEIGHT*2)
41/* must be 16Kb (0x4000) aligned */ 45/* must be 16Kb (0x4000) aligned */
42#define TTB_SIZE (0x4000) 46#define TTB_SIZE (0x4000)
43#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_BUFFER_SIZE - TTB_SIZE 47#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_BUFFER_SIZE - TTB_SIZE
44#elif CONFIG_CPU==IMX31L 48
45#include "imx31l.h"
46/* Reserve 1mb for LCD buffer/TTB as in app.lds */
47#define DRAMSIZE (MEMORYSIZE * 0x100000 - 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET - CODEC_SIZE
48#elif CONFIG_CPU==AS3525 && MEMORYSIZE <= 2 49#elif CONFIG_CPU==AS3525 && MEMORYSIZE <= 2
49#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET 50#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET
51
50#else 52#else
51#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET - CODEC_SIZE 53#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGIN_BUFFER_SIZE - STUBOFFSET - CODEC_SIZE
52#endif 54#endif
@@ -77,11 +79,7 @@ OUTPUT_FORMAT(elf32-littlemips)
77#define DRAMORIG 0xc00000 + STUBOFFSET 79#define DRAMORIG 0xc00000 + STUBOFFSET
78#define IRAMORIG 0x407000 80#define IRAMORIG 0x407000
79#define IRAMSIZE 0x9000 81#define IRAMSIZE 0x9000
80#elif CONFIG_CPU == S3C2440 82#elif CONFIG_CPU == IMX31L || CONFIG_CPU == S3C2440
81#define DRAMORIG 0x0 + STUBOFFSET
82#define IRAM DRAM
83#define IRAMSIZE 0
84#elif CONFIG_CPU == IMX31L
85#define DRAMORIG 0x0 + STUBOFFSET 83#define DRAMORIG 0x0 + STUBOFFSET
86#define IRAM DRAM 84#define IRAM DRAM
87#define IRAMSIZE 0 85#define IRAMSIZE 0
diff --git a/firmware/export/config-mrobe500.h b/firmware/export/config-mrobe500.h
index fafea48a94..90bbefe329 100644
--- a/firmware/export/config-mrobe500.h
+++ b/firmware/export/config-mrobe500.h
@@ -59,24 +59,21 @@
59/* LCD dimensions */ 59/* LCD dimensions */
60#define CONFIG_LCD LCD_MROBE500 60#define CONFIG_LCD LCD_MROBE500
61 61
62/* choose the lcd orientation. both work */ 62#if 0
63/* #define CONFIG_ORIENTATION SCREEN_PORTRAIT */ 63#define LCD_NATIVE_WIDTH 480
64#define CONFIG_ORIENTATION SCREEN_PORTRAIT 64#define LCD_NATIVE_HEIGHT 640
65
66#if 1
67#define NATIVE_MAX_WIDTH 480
68#define NATIVE_MAX_HEIGHT 640
69#else 65#else
70#define NATIVE_MAX_WIDTH 240 66#define LCD_NATIVE_WIDTH 240
71#define NATIVE_MAX_HEIGHT 320 67#define LCD_NATIVE_HEIGHT 320
72#endif 68#endif
73 69
74#if CONFIG_ORIENTATION == SCREEN_PORTRAIT 70/* choose the lcd orientation. CONFIG_ORIENTATION defined in config.h */
75#define LCD_WIDTH NATIVE_MAX_WIDTH 71#if 0
76#define LCD_HEIGHT NATIVE_MAX_HEIGHT 72#define LCD_WIDTH LCD_NATIVE_WIDTH
73#define LCD_HEIGHT LCD_NATIVE_HEIGHT
77#else 74#else
78#define LCD_WIDTH NATIVE_MAX_HEIGHT 75#define LCD_WIDTH LCD_NATIVE_HEIGHT
79#define LCD_HEIGHT NATIVE_MAX_WIDTH 76#define LCD_HEIGHT LCD_NATIVE_WIDTH
80#endif 77#endif
81 78
82#define LCD_DEPTH 16 /* 65k colours */ 79#define LCD_DEPTH 16 /* 65k colours */
@@ -142,16 +139,20 @@
142 139
143#define HW_SAMPR_CAPS SAMPR_CAP_44 140#define HW_SAMPR_CAPS SAMPR_CAP_44
144 141
145#define BATTERY_CAPACITY_DEFAULT 1100 /* default battery capacity */ 142#define BATTERY_CAPACITY_DEFAULT 1500 /* default battery capacity */
146#define BATTERY_CAPACITY_MIN 500 /* min. capacity selectable */ 143#define BATTERY_CAPACITY_MIN 1000 /* min. capacity selectable */
147#define BATTERY_CAPACITY_MAX 2500 /* max. capacity selectable */ 144#define BATTERY_CAPACITY_MAX 2000 /* max. capacity selectable */
148#define BATTERY_CAPACITY_INC 100 /* capacity increment */ 145#define BATTERY_CAPACITY_INC 100 /* capacity increment */
149#define BATTERY_TYPES_COUNT 1 /* only one type */ 146#define BATTERY_TYPES_COUNT 1 /* only one type */
150 147
148/* define current usage levels */
149#define CURRENT_NORMAL 120 /* Measured */
150#define CURRENT_BACKLIGHT 80 /* Over 200 mA total measured when on */
151#define CURRENT_RECORD 0 /* no recording */
152
151/* Hardware controlled charging with monitoring */ 153/* Hardware controlled charging with monitoring */
152#define CONFIG_CHARGING CHARGING_MONITOR 154#define CONFIG_CHARGING CHARGING_MONITOR
153 155
154
155/* Define this if you have a Texas Instruments TSC2100 touch screen */ 156/* Define this if you have a Texas Instruments TSC2100 touch screen */
156#define HAVE_TSC2100 157#define HAVE_TSC2100
157 158
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 4f35927353..e52356b8bf 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -97,8 +97,15 @@ void lcd_set_mode(int mode);
97#define LCD_MODE_RGB565 0x00000001 97#define LCD_MODE_RGB565 0x00000001
98#define LCD_MODE_YUV 0x00000002 98#define LCD_MODE_YUV 0x00000002
99#define LCD_MODE_PAL256 0x00000004 99#define LCD_MODE_PAL256 0x00000004
100
101#if HAVE_LCD_MODES & LCD_MODE_PAL256
102 void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
103 int width, int height);
104 void lcd_pal256_update_pal(fb_data *palette);
105#endif
100#endif 106#endif
101 107
108
102/* common functions */ 109/* common functions */
103extern void lcd_write_command(int byte); 110extern void lcd_write_command(int byte);
104extern void lcd_write_command_e(int cmd, int data); 111extern void lcd_write_command_e(int cmd, int data);
diff --git a/firmware/target/arm/tms320dm320/app.lds b/firmware/target/arm/tms320dm320/app.lds
index 47ff239a1a..4e175101a9 100644
--- a/firmware/target/arm/tms320dm320/app.lds
+++ b/firmware/target/arm/tms320dm320/app.lds
@@ -6,35 +6,30 @@ OUTPUT_FORMAT(elf32-littlearm)
6OUTPUT_ARCH(arm) 6OUTPUT_ARCH(arm)
7STARTUP(target/arm/tms320dm320/crt0.o) 7STARTUP(target/arm/tms320dm320/crt0.o)
8 8
9#define PLUGINSIZE PLUGIN_BUFFER_SIZE
10#define CODECSIZE CODEC_SIZE
11
12#ifdef DEBUG 9#ifdef DEBUG
13#define STUBOFFSET 0x10000 10#define STUBOFFSET 0x10000
14#else 11#else
15#define STUBOFFSET 0 12#define STUBOFFSET 0
16#endif 13#endif
17 14
18#define LCD_BUFFER_SIZE (LCD_WIDTH*LCD_HEIGHT*2) 15#define LCD_FUDGE LCD_NATIVE_WIDTH%32
19
20/* must be 16Kb (0x4000) aligned */
21#define TTB_SIZE (0x4000)
22 16
23#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET - PLUGINSIZE - CODECSIZE - LCD_BUFFER_SIZE - TTB_SIZE 17#define LCD_BUFFER_SIZE ((LCD_NATIVE_WIDTH+LCD_FUDGE)*LCD_NATIVE_HEIGHT*2)
24 18
25#define DRAMORIG 0x00900000 + STUBOFFSET 19/* must be 16Kb (0x4000) aligned */
26#define IRAMORIG 0x00000000 20#define TTB_SIZE 0x4000
27#define IRAMSIZE 0x4000
28 21
29/* End of the audio buffer, where the codec buffer starts */ 22/* Give this 1 meg to allow it to align to the MMU boundary */
30#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE) 23#define LCD_TTB_AREA 0x100000
31 24
32/* Where the codec buffer ends, and the plugin buffer starts */ 25#define DRAMSIZE (MEMORYSIZE * 0x100000) - STUBOFFSET
33#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
34 26
35#define LCDBEGIN (ENDADDR + PLUGINSIZE) 27#define DRAMORIG 0x00900000 + STUBOFFSET
28#define IRAMORIG 0x00000000
29#define IRAMSIZE 0x4000
36 30
37#define TTBBEGIN (LCDBEGIN + LCD_BUFFER_SIZE) 31/* End of the audio buffer, where the codec buffer starts */
32#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_TTB_AREA)
38 33
39MEMORY 34MEMORY
40{ 35{
@@ -144,22 +139,32 @@ SECTIONS
144 { 139 {
145 codecbuf = .; 140 codecbuf = .;
146 _codecbuf = .; 141 _codecbuf = .;
147 } 142 . += CODEC_SIZE;
143 } > DRAM
148 144
149 .plugin ENDADDR (NOLOAD) : 145 .plugin (NOLOAD) :
150 { 146 {
151 _pluginbuf = .; 147 _pluginbuf = .;
152 pluginbuf = .; 148 pluginbuf = .;
153 } 149 . += PLUGIN_BUFFER_SIZE;
150 } > DRAM
154 151
155 .lcdbuffer LCDBEGIN (NOLOAD) : 152 .ttbtable (NOLOAD) :
156 { 153 {
157 _lcdbuf = .; 154 . = ALIGN (0x4000);
158 } 155 _ttbstart = .;
156 . += TTB_SIZE;
157 } > DRAM
158
159 /* The LCD buffer should be at the end of memory to protect against
160 * overflowing something else when the YUV blitter is fudging the screen
161 * size.
162 */
159 163
160 .ttbtable TTBBEGIN (NOLOAD) : 164 .lcdbuffer (NOLOAD) :
161 { 165 {
162 _ttbstart = .; 166 _lcdbuf = .;
163 } 167 . += LCD_BUFFER_SIZE;
168 } > DRAM
164} 169}
165 170
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
index 3fa8a7e6c1..1334eeaf8d 100644
--- a/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
+++ b/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
@@ -112,6 +112,11 @@ void lcd_enable(bool state)
112} 112}
113#endif 113#endif
114 114
115/* Note this is expecting a screen size of 480x640 or 240x320, other screen
116 * sizes need to be considered for fudge factors
117 */
118#define LCD_FUDGE LCD_NATIVE_WIDTH%32
119
115/* LCD init - based on code from ingenient-bsp/bootloader/board/dm320/splash.c 120/* LCD init - based on code from ingenient-bsp/bootloader/board/dm320/splash.c
116 * and code by Catalin Patulea from the M:Robe 500i linux port 121 * and code by Catalin Patulea from the M:Robe 500i linux port
117 */ 122 */
@@ -122,21 +127,26 @@ void lcd_init_device(void)
122 /* Clear the Frame */ 127 /* Clear the Frame */
123 memset16(FRAME, 0x0000, LCD_WIDTH*LCD_HEIGHT); 128 memset16(FRAME, 0x0000, LCD_WIDTH*LCD_HEIGHT);
124 129
130 lcd_sleep();
131
132 IO_OSD_OSDWINMD0&=~(0x0001);
133 IO_OSD_VIDWINMD&=~(0x0001);
134
125 /* Setup the LCD controller */ 135 /* Setup the LCD controller */
126 IO_VID_ENC_VMOD=0x2015; 136 IO_VID_ENC_VMOD=0x2014;
127 IO_VID_ENC_VDCTL=0x2000; 137 IO_VID_ENC_VDCTL=0x2000;
128 IO_VID_ENC_VDPRO=0x0000; 138 IO_VID_ENC_VDPRO=0x0000;
129 IO_VID_ENC_SYNCTL=0x100E; 139 IO_VID_ENC_SYNCTL=0x100E;
130 IO_VID_ENC_HSPLS=1; /* HSYNC pulse width */ 140 IO_VID_ENC_HSPLS=1; /* HSYNC pulse width */
131 IO_VID_ENC_VSPLS=1; /* VSYNC pulse width */ 141 IO_VID_ENC_VSPLS=1; /* VSYNC pulse width */
132 142
133 /* These calculations support 640x480 and 320x240 */ 143 /* These calculations support 640x480 and 320x240 (based on OF) */
134 IO_VID_ENC_HINT=NATIVE_MAX_WIDTH+NATIVE_MAX_WIDTH/3; 144 IO_VID_ENC_HINT=LCD_NATIVE_WIDTH+LCD_NATIVE_WIDTH/3;
135 IO_VID_ENC_HSTART=NATIVE_MAX_WIDTH/6; /* Front porch */ 145 IO_VID_ENC_HSTART=LCD_NATIVE_WIDTH/6; /* Front porch */
136 IO_VID_ENC_HVALID=NATIVE_MAX_WIDTH; /* Data valid */ 146 IO_VID_ENC_HVALID=LCD_NATIVE_WIDTH; /* Data valid */
137 IO_VID_ENC_VINT=NATIVE_MAX_HEIGHT+7; 147 IO_VID_ENC_VINT=LCD_NATIVE_HEIGHT+7;
138 IO_VID_ENC_VSTART=3; 148 IO_VID_ENC_VSTART=3;
139 IO_VID_ENC_VVALID=NATIVE_MAX_HEIGHT; 149 IO_VID_ENC_VVALID=LCD_NATIVE_HEIGHT;
140 150
141 IO_VID_ENC_HSDLY=0x0000; 151 IO_VID_ENC_HSDLY=0x0000;
142 IO_VID_ENC_VSDLY=0x0000; 152 IO_VID_ENC_VSDLY=0x0000;
@@ -152,46 +162,88 @@ void lcd_init_device(void)
152 IO_VID_ENC_PWMP=0x0000; 162 IO_VID_ENC_PWMP=0x0000;
153 IO_VID_ENC_PWMW=0x0000; 163 IO_VID_ENC_PWMW=0x0000;
154 164
155 IO_VID_ENC_DCLKCTL=0x0800;
156 IO_VID_ENC_DCLKPTN0=0x0001; 165 IO_VID_ENC_DCLKPTN0=0x0001;
157 166
158
159 /* Setup the display */ 167 /* Setup the display */
160 IO_OSD_MODE=0x00ff; 168 IO_OSD_MODE=0x00ff;
161 IO_OSD_VIDWINMD=0x0002; 169
162 IO_OSD_OSDWINMD0=0x2001;
163 IO_OSD_OSDWINMD1=0x0002;
164 IO_OSD_ATRMD=0x0000; 170 IO_OSD_ATRMD=0x0000;
165 IO_OSD_RECTCUR=0x0000; 171 IO_OSD_RECTCUR=0x0000;
166 172
167 IO_OSD_OSDWIN0OFST=(NATIVE_MAX_WIDTH*2) / 32; 173 IO_OSD_BASEPX=IO_VID_ENC_HSTART;
174 IO_OSD_BASEPY=IO_VID_ENC_VSTART;
168 175
169 addr = ((int)FRAME-CONFIG_SDRAM_START) / 32; 176 addr = ((int)FRAME-CONFIG_SDRAM_START) / 32;
170 IO_OSD_OSDWINADH=addr >> 16; 177
171 IO_OSD_OSDWIN0ADL=addr & 0xFFFF; 178 /* Setup the OSD windows */
172 179
173 IO_OSD_VIDWINADH=addr >> 16; 180 /* Used for 565 RGB */
174 IO_OSD_VIDWIN0ADL=addr & 0xFFFF; 181 IO_OSD_OSDWINMD0=0x30C0;
175 182
176 IO_OSD_BASEPX=IO_VID_ENC_HSTART; 183 IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 16;
177 IO_OSD_BASEPY=IO_VID_ENC_VSTART; 184
185 IO_OSD_OSDWINADH=addr >> 16;
186 IO_OSD_OSDWIN0ADL=addr & 0xFFFF;
178 187
179 IO_OSD_OSDWIN0XP=0; 188 IO_OSD_OSDWIN0XP=0;
180 IO_OSD_OSDWIN0YP=0; 189 IO_OSD_OSDWIN0YP=0;
181 190
182 IO_OSD_OSDWIN0XL=NATIVE_MAX_WIDTH; 191 /* read from OF */
183 IO_OSD_OSDWIN0YL=NATIVE_MAX_HEIGHT; 192 IO_OSD_OSDWIN0XL=LCD_NATIVE_WIDTH;
193 IO_OSD_OSDWIN0YL=LCD_NATIVE_HEIGHT;
194
195 /* Unused */
196 IO_OSD_OSDWINMD1=0x10C0;
197
198#if LCD_NATIVE_WIDTH%32!=0
199 IO_OSD_OSDWIN1OFST=LCD_NATIVE_WIDTH / 32+1;
200#else
201 IO_OSD_OSDWIN1OFST=LCD_NATIVE_WIDTH / 32;
202#endif
203
204 IO_OSD_OSDWIN1ADL=addr & 0xFFFF;
205
206 IO_OSD_OSDWIN1XP=0;
207 IO_OSD_OSDWIN1YP=0;
208
209 IO_OSD_OSDWIN1XL=LCD_NATIVE_WIDTH;
210 IO_OSD_OSDWIN1YL=LCD_NATIVE_HEIGHT;
211
212 IO_OSD_VIDWINMD=0x0002;
213
214 /* This is a bit messy, the LCD transfers appear to happen in chunks of 32
215 * pixels. (based on OF)
216 */
217#if LCD_NATIVE_WIDTH%32!=0
218 IO_OSD_VIDWIN0OFST=LCD_NATIVE_WIDTH / 32+1;
219#else
220 IO_OSD_VIDWIN0OFST=LCD_NATIVE_WIDTH / 32;
221#endif
222
223 IO_OSD_VIDWINADH=addr >> 16;
224 IO_OSD_VIDWIN0ADL=addr & 0xFFFF;
225
226 IO_OSD_VIDWIN0XP=0;
227 IO_OSD_VIDWIN0YP=0;
228
229 IO_OSD_VIDWIN0XL=LCD_NATIVE_WIDTH;
230 IO_OSD_VIDWIN0YL=LCD_NATIVE_HEIGHT;
184 231
185 /* Set pin 36 and 35 (LCD POWER and LCD RESOLUTION) to an output */ 232 /* Set pin 36 and 35 (LCD POWER and LCD RESOLUTION) to an output */
186 IO_GIO_DIR2&=!(3<<3); 233 IO_GIO_DIR2&=!(3<<3);
187 234
188#if NATIVE_MAX_HEIGHT > 320 235#if LCD_NATIVE_HEIGHT > 320
189 /* Set LCD resolution to VGA */ 236 /* Set LCD resolution to VGA */
190 IO_GIO_BITSET2=1<<3; 237 IO_GIO_BITSET2=1<<3;
191#else 238#else
192 /* Set LCD resolution to QVGA */ 239 /* Set LCD resolution to QVGA */
193 IO_GIO_BITCLR2=1<<3; 240 IO_GIO_BITCLR2=1<<3;
194#endif 241#endif
242
243 IO_OSD_OSDWINMD0|=0x01;
244 IO_VID_ENC_VMOD|=0x01;
245
246 lcd_enable(true);
195} 247}
196 248
197/* Update a fraction of the display. */ 249/* Update a fraction of the display. */
@@ -216,9 +268,10 @@ void lcd_update_rect(int x, int y, int width, int height)
216 if (height <= 0) 268 if (height <= 0)
217 return; /* nothing left to do */ 269 return; /* nothing left to do */
218 270
271 src = &lcd_framebuffer[y][x];
272
219#if CONFIG_ORIENTATION == SCREEN_PORTRAIT 273#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
220 dst = (fb_data *)FRAME + LCD_WIDTH*y + x; 274 dst = (fb_data *)FRAME + LCD_WIDTH*y + x;
221 src = &lcd_framebuffer[y][x];
222 275
223 /* Copy part of the Rockbox framebuffer to the second framebuffer */ 276 /* Copy part of the Rockbox framebuffer to the second framebuffer */
224 if (width < LCD_WIDTH) 277 if (width < LCD_WIDTH)
@@ -232,21 +285,23 @@ void lcd_update_rect(int x, int y, int width, int height)
232 lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1); 285 lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1);
233 } 286 }
234#else 287#else
235 src = &lcd_framebuffer[y][x]; 288 dst=FRAME + (LCD_NATIVE_WIDTH*(LCD_NATIVE_HEIGHT-1))
236 289 - LCD_NATIVE_WIDTH*x + y ;
237 register int xc, yc;
238 register fb_data *start=FRAME + LCD_HEIGHT*(LCD_WIDTH-x-1) + y + 1;
239 290
240 for(yc=0;yc<height;yc++) 291 do
241 { 292 {
242 dst=start+yc; 293 register int c_width=width;
243 for(xc=0; xc<width; xc++) 294 register fb_data *c_dst=dst;
295 do
244 { 296 {
245 *dst=*src++; 297 *c_dst=*src++;
246 dst-=LCD_HEIGHT; 298 c_dst-=LCD_NATIVE_WIDTH;
247 } 299 }
248 src+=x; 300 while(--c_width);
301 src+=LCD_WIDTH-width-x;
302 dst++;
249 } 303 }
304 while(--height);
250#endif 305#endif
251} 306}
252 307
@@ -271,20 +326,94 @@ void lcd_set_mode(int mode)
271 if(mode==LCD_MODE_YUV) 326 if(mode==LCD_MODE_YUV)
272 { 327 {
273 /* Turn off the RGB buffer and enable the YUV buffer */ 328 /* Turn off the RGB buffer and enable the YUV buffer */
274 IO_OSD_OSDWINMD0&=~(0x01); 329 IO_OSD_OSDWINMD0 &=~(0x01);
275 IO_OSD_VIDWINMD|=0x01; 330 IO_OSD_VIDWINMD |=0x01;
276 memset16(FRAME, 0x0080, LCD_WIDTH*LCD_HEIGHT); 331 memset16(FRAME, 0x0080, LCD_NATIVE_HEIGHT*(LCD_NATIVE_WIDTH+LCD_FUDGE));
277 } 332 }
278 else if(mode==LCD_MODE_RGB565) 333 else if(mode==LCD_MODE_RGB565)
279 { 334 {
280 /* Turn on the RGB window and the YUV window off (This should probably be 335 /* Turn on the RGB window, set it to 16 bit and turn YUV window off */
281 * made into a function). 336 IO_OSD_VIDWINMD &=~(0x01);
282 */ 337 IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 16;
283 IO_OSD_OSDWINMD0|=0x01; 338 IO_OSD_OSDWINMD0 |=(1<<13)|0x01;
284 IO_OSD_VIDWINMD&=~(0x01); 339 lcd_clear_display();
285 } 340 }
286 else if(mode==LCD_MODE_PAL256) 341 else if(mode==LCD_MODE_PAL256)
287 { 342 {
343#if LCD_NATIVE_WIDTH%32!=0
344 IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 32+1;
345#else
346 IO_OSD_OSDWIN0OFST=LCD_NATIVE_WIDTH / 32;
347#endif
348
349 IO_OSD_VIDWINMD &=~(0x01);
350 IO_OSD_OSDWINMD0 &=~(1<<13);
351 IO_OSD_OSDWINMD0 |=0x01;
352 }
353}
354#endif
355
356#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
357void lcd_blit_pal256(unsigned char *src, int src_x, int src_y, int x, int y,
358 int width, int height)
359{
360#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
361 char *dst=(char *)FRAME+x+y*(LCD_NATIVE_WIDTH+LCD_FUDGE);
362
363 src=src+src_x+src_y*LCD_NATIVE_WIDTH;
364 do
365 {
366 memcpy ( dst, src, width);
367
368 /* The LCD uses the top 1/4 of the screen when in palette mode */
369 dst=dst+width+(LCD_NATIVE_WIDTH-x-width)+LCD_FUDGE;
370 src+=width;
371 }
372 while(--height);
373#else
374 char *dst=(char *)FRAME
375 + (LCD_NATIVE_WIDTH+LCD_FUDGE)*(LCD_NATIVE_HEIGHT-1)
376 - (LCD_NATIVE_WIDTH+LCD_FUDGE)*x + y;
377
378 src=src+src_x+src_y*LCD_WIDTH;
379 do
380 {
381 register char *c_dst=dst;
382 register int c_width=width;
383 do
384 {
385 *c_dst=*src++;
386 /* The LCD uses the top 1/4 of the screen when in palette mode */
387 c_dst=c_dst-(LCD_NATIVE_WIDTH+LCD_FUDGE);
388 } while (--c_width);
389 dst++;
390 src=src+(LCD_WIDTH-width-x);
391 }
392 while(--height);
393#endif
394}
395
396void lcd_pal256_update_pal(fb_data *palette)
397{
398 unsigned char i;
399 for(i=0; i< 255; i++)
400 {
401 int y, cb, cr;
402 unsigned char r=RGB_UNPACK_RED_LCD(palette[i])<<3;
403 unsigned char g=RGB_UNPACK_GREEN_LCD(palette[i])<<2;
404 unsigned char b=RGB_UNPACK_BLUE_LCD(palette[i])<<3;
405
406 y = ((77 * r + 150 * g + 29 * b) >> 8); cb = ((-43 * r - 85 * g + 128 * b) >> 8) + 128;
407 cr = ((128 * r - 107 * g - 21 * b) >> 8) + 128;
408
409 while(IO_OSD_MISCCTL&0x08)
410 {};
411
412 /* Write in y and cb */
413 IO_OSD_CLUTRAMYCB= ((unsigned char)y << 8) | (unsigned char)cb;
414
415 /* Write in the index and cr */
416 IO_OSD_CLUTRAMCR=((unsigned char)cr << 8) | i;
288 } 417 }
289} 418}
290#endif 419#endif
@@ -308,14 +437,32 @@ void lcd_blit_yuv(unsigned char * const src[3],
308 if (!lcd_on) 437 if (!lcd_on)
309 return; 438 return;
310 439
311 /* y has to be at multiple of 2 or else it will mess up the HW (interleaving) */ 440 /* y has to be at multiple of 2 or else it will mess up the HW
441 * (interleaving)
442 */
312 y &= ~1; 443 y &= ~1;
313 444
445 if(y<0 || y>LCD_NATIVE_HEIGHT || x<0 || x>LCD_NATIVE_WIDTH
446 || height<0 || width <0)
447 {
448 return;
449 }
450
451 if(y+height>LCD_NATIVE_WIDTH)
452 {
453 height=LCD_NATIVE_WIDTH-y;
454 }
455 if(x+width>LCD_NATIVE_HEIGHT)
456 {
457 width=LCD_NATIVE_HEIGHT-x;
458 }
459
314 /* Sorry, but width and height must be >= 2 or else */ 460 /* Sorry, but width and height must be >= 2 or else */
315 width &= ~1; 461 width &= ~1;
316 height>>=1; 462 height>>=1;
317 463
318 fb_data *dst = (fb_data*)FRAME + LCD_WIDTH*LCD_HEIGHT - x * LCD_WIDTH + y; 464 fb_data * dst = FRAME + ((LCD_NATIVE_WIDTH+LCD_FUDGE)*(LCD_NATIVE_HEIGHT-1))
465 - (LCD_NATIVE_WIDTH+LCD_FUDGE)*x + y ;
319 466
320 z = stride*src_y; 467 z = stride*src_y;
321 yuv_src[0] = src[0] + z + src_x; 468 yuv_src[0] = src[0] + z + src_x;
@@ -337,11 +484,11 @@ void lcd_blit_yuv(unsigned char * const src[3],
337 /* This needs to be done in a block of 4 pixels */ 484 /* This needs to be done in a block of 4 pixels */
338 *c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1]; 485 *c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1];
339 *(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2]; 486 *(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2];
340 c_dst-=LCD_WIDTH; 487 c_dst-=(LCD_NATIVE_WIDTH+LCD_FUDGE);
341 c_yuv_src[0]++; 488 c_yuv_src[0]++;
342 *c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1]; 489 *c_dst=*c_yuv_src[0]<<8 | *c_yuv_src[1];
343 *(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2]; 490 *(c_dst+1)=*(c_yuv_src[0]+stride)<<8 | *c_yuv_src[2];
344 c_dst-=LCD_WIDTH; 491 c_dst-=(LCD_NATIVE_WIDTH+LCD_FUDGE);
345 c_yuv_src[0]++; 492 c_yuv_src[0]++;
346 493
347 c_yuv_src[1]++; 494 c_yuv_src[1]++;