summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c')
-rw-r--r--firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c147
1 files changed, 6 insertions, 141 deletions
diff --git a/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c b/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c
index ab50769983..b4c37b716c 100644
--- a/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c
+++ b/firmware/target/arm/tcc780x/cowond2/lcd-cowond2.c
@@ -24,9 +24,12 @@
24#include "hwcompat.h" 24#include "hwcompat.h"
25#include "kernel.h" 25#include "kernel.h"
26#include "lcd.h" 26#include "lcd.h"
27#include "lcd-target.h"
27#include "system.h" 28#include "system.h"
28#include "cpu.h" 29#include "cpu.h"
29 30
31extern bool lcd_on; /* lcd-memframe.c */
32
30/* GPIO A pins for LCD panel SDI interface */ 33/* GPIO A pins for LCD panel SDI interface */
31 34
32#define LTV250QV_CS (1<<24) 35#define LTV250QV_CS (1<<24)
@@ -51,11 +54,6 @@
51#define LCDC_I1OFF (*(volatile unsigned long *)0xF00000A8) 54#define LCDC_I1OFF (*(volatile unsigned long *)0xF00000A8)
52#define LCDC_I1SCALE (*(volatile unsigned long *)0xF00000AC) 55#define LCDC_I1SCALE (*(volatile unsigned long *)0xF00000AC)
53 56
54/* Power and display status */
55static bool display_on = false; /* Is the display turned on? */
56
57static unsigned lcd_yuv_options = 0;
58
59/* Framebuffer copy as seen by the hardware */ 57/* Framebuffer copy as seen by the hardware */
60fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]; 58fb_data lcd_driver_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH];
61 59
@@ -180,13 +178,13 @@ static void lcd_display_on(void)
180 udelay(10000); 178 udelay(10000);
181 179
182 /* tell that we're on now */ 180 /* tell that we're on now */
183 display_on = true; 181 lcd_on = true;
184} 182}
185 183
186static void lcd_display_off(void) 184static void lcd_display_off(void)
187{ 185{
188 /* block drawing operations and changing of first */ 186 /* block drawing operations and changing of first */
189 display_on = false; 187 lcd_on = false;
190 188
191 /* LQV shutdown sequence */ 189 /* LQV shutdown sequence */
192 lcd_write_reg(9, 0x55); 190 lcd_write_reg(9, 0x55);
@@ -204,7 +202,7 @@ static void lcd_display_off(void)
204 202
205void lcd_enable(bool on) 203void lcd_enable(bool on)
206{ 204{
207 if (on == display_on) 205 if (on == lcd_on)
208 return; 206 return;
209 207
210 if (on) 208 if (on)
@@ -221,11 +219,6 @@ void lcd_enable(bool on)
221 } 219 }
222} 220}
223 221
224bool lcd_active(void)
225{
226 return display_on;
227}
228
229/* TODO: implement lcd_sleep() and separate out the power on/off functions */ 222/* TODO: implement lcd_sleep() and separate out the power on/off functions */
230 223
231void lcd_init_device(void) 224void lcd_init_device(void)
@@ -278,67 +271,6 @@ void lcd_init_device(void)
278 271
279 272
280/*** Update functions ***/ 273/*** Update functions ***/
281
282
283/* Copies a rectangle from one framebuffer to another. Can be used in
284 single transfer mode with width = num pixels, and height = 1 which
285 allows a full-width rectangle to be copied more efficiently. */
286extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src,
287 int width, int height);
288
289/* Update the display.
290 This must be called after all other LCD functions that change the display. */
291void lcd_update(void) ICODE_ATTR;
292void lcd_update(void)
293{
294 if (!display_on)
295 return;
296
297 lcd_copy_buffer_rect(&lcd_driver_framebuffer[0][0],
298 &lcd_framebuffer[0][0], LCD_WIDTH*LCD_HEIGHT, 1);
299}
300
301/* Update a fraction of the display. */
302void lcd_update_rect(int, int, int, int) ICODE_ATTR;
303void lcd_update_rect(int x, int y, int width, int height)
304{
305 fb_data *dst, *src;
306
307 if (!display_on)
308 return;
309
310 if (x + width > LCD_WIDTH)
311 width = LCD_WIDTH - x; /* Clip right */
312 if (x < 0)
313 width += x, x = 0; /* Clip left */
314 if (width <= 0)
315 return; /* nothing left to do */
316
317 if (y + height > LCD_HEIGHT)
318 height = LCD_HEIGHT - y; /* Clip bottom */
319 if (y < 0)
320 height += y, y = 0; /* Clip top */
321 if (height <= 0)
322 return; /* nothing left to do */
323
324 /* TODO: It may be faster to swap the addresses of lcd_driver_framebuffer
325 * and lcd_framebuffer */
326 dst = &lcd_driver_framebuffer[y][x];
327 src = &lcd_framebuffer[y][x];
328
329 /* Copy part of the Rockbox framebuffer to the second framebuffer */
330 if (width < LCD_WIDTH)
331 {
332 /* Not full width - do line-by-line */
333 lcd_copy_buffer_rect(dst, src, width, height);
334 }
335 else
336 {
337 /* Full width - copy as one line */
338 lcd_copy_buffer_rect(dst, src, LCD_WIDTH*height, 1);
339 }
340}
341
342void lcd_set_flip(bool yesno) 274void lcd_set_flip(bool yesno)
343{ 275{
344 // TODO 276 // TODO
@@ -350,70 +282,3 @@ void lcd_set_invert_display(bool yesno)
350 // TODO 282 // TODO
351 (void)yesno; 283 (void)yesno;
352} 284}
353
354void lcd_yuv_set_options(unsigned options)
355{
356 lcd_yuv_options = options;
357}
358
359/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
360extern void lcd_write_yuv420_lines(fb_data *dst,
361 unsigned char const * const src[3],
362 int width,
363 int stride);
364
365extern void lcd_write_yuv420_lines_odither(fb_data *dst,
366 unsigned char const * const src[3],
367 int width,
368 int stride,
369 int x_screen, /* To align dither pattern */
370 int y_screen);
371
372/* Performance function to blit a YUV bitmap directly to the LCD */
373void lcd_blit_yuv(unsigned char * const src[3],
374 int src_x, int src_y, int stride,
375 int x, int y, int width, int height)
376{
377 unsigned char const * yuv_src[3];
378 off_t z;
379
380 if (!display_on)
381 return;
382
383 /* Sorry, but width and height must be >= 2 or else */
384 width &= ~1;
385 height >>= 1;
386
387 fb_data *dst = &lcd_driver_framebuffer[y][x];
388
389 z = stride*src_y;
390 yuv_src[0] = src[0] + z + src_x;
391 yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
392 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
393
394 if (lcd_yuv_options & LCD_YUV_DITHER)
395 {
396 do
397 {
398 lcd_write_yuv420_lines_odither(dst, yuv_src, width, stride, y, x);
399 yuv_src[0] += stride << 1; /* Skip down two luma lines */
400 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
401 yuv_src[2] += stride >> 1;
402 dst += 2*LCD_FBWIDTH;
403 y -= 2;
404 }
405 while (--height > 0);
406 }
407 else
408 {
409 do
410 {
411 lcd_write_yuv420_lines(dst, yuv_src, width, stride);
412 yuv_src[0] += stride << 1; /* Skip down two luma lines */
413 yuv_src[1] += stride >> 1; /* Skip down one chroma line */
414 yuv_src[2] += stride >> 1;
415 dst += 2*LCD_FBWIDTH;
416 }
417 while (--height > 0);
418 }
419}