summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
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/tms320dm320/mrobe-500/lcd-mr500.c
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/tms320dm320/mrobe-500/lcd-mr500.c')
-rw-r--r--firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c145
1 files changed, 117 insertions, 28 deletions
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) {