summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c
diff options
context:
space:
mode:
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) {