summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/iriver/h300/lcd-h300.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/iriver/h300/lcd-h300.c')
-rw-r--r--firmware/target/coldfire/iriver/h300/lcd-h300.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/firmware/target/coldfire/iriver/h300/lcd-h300.c b/firmware/target/coldfire/iriver/h300/lcd-h300.c
index 8d5370cdcf..7e73ea3905 100644
--- a/firmware/target/coldfire/iriver/h300/lcd-h300.c
+++ b/firmware/target/coldfire/iriver/h300/lcd-h300.c
@@ -325,6 +325,67 @@ bool lcd_active(void)
325 325
326/*** update functions ***/ 326/*** update functions ***/
327 327
328/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420.
329 * y should have two lines of Y back to back, 2nd line first.
330 * c should contain the Cb and Cr data for the two lines of Y back to back.
331 * Needs EMAC set to saturated, signed integer mode.
332 */
333extern void lcd_write_yuv420_lines(const unsigned char *y,
334 const unsigned char *c, int cwidth);
335
336/* Performance function to blit a YUV bitmap directly to the LCD
337 * src_x, src_y, width and height should be even
338 * x, y, width and height have to be within LCD bounds
339 */
340void lcd_blit_yuv(unsigned char * const src[3],
341 int src_x, int src_y, int stride,
342 int x, int y, int width, int height)
343{
344 /* IRAM Y, Cb and Cb buffers. */
345 unsigned char y_ibuf[LCD_WIDTH*2];
346 unsigned char c_ibuf[LCD_WIDTH];
347 const unsigned char *ysrc, *usrc, *vsrc;
348 const unsigned char *ysrc_max;
349
350 if (!display_on)
351 return;
352
353 LCD_MUTEX_LOCK();
354 width &= ~1; /* stay on the safe side */
355 height &= ~1;
356
357 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ);
358 /* Set start position and window */
359 lcd_write_reg(R_VERT_RAM_ADDR_POS, ((xoffset + 219) << 8) | xoffset);
360
361 ysrc = src[0] + src_y * stride + src_x;
362 usrc = src[1] + (src_y * stride >> 2) + (src_x >> 1);
363 vsrc = src[2] + (src_y * stride >> 2) + (src_x >> 1);
364 ysrc_max = ysrc + height * stride;
365
366 coldfire_set_macsr(EMAC_SATURATE);
367 do
368 {
369 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((y + 1) << 8) | y);
370 lcd_write_reg(R_RAM_ADDR_SET, ((x+xoffset) << 8) | y);
371 lcd_begin_write_gram();
372
373 memcpy(y_ibuf + width, ysrc, width);
374 memcpy(y_ibuf, ysrc + stride, width);
375 memcpy(c_ibuf, usrc, width >> 1);
376 memcpy(c_ibuf + (width >> 1), vsrc, width >> 1);
377 lcd_write_yuv420_lines(y_ibuf, c_ibuf, width >> 1);
378
379 y += 2;
380 ysrc += 2 * stride;
381 usrc += stride >> 1;
382 vsrc += stride >> 1;
383 }
384 while (ysrc < ysrc_max)
385 ;;
386 LCD_MUTEX_UNLOCK();
387}
388
328#ifndef BOOTLOADER 389#ifndef BOOTLOADER
329/* LCD DMA ISR */ 390/* LCD DMA ISR */
330void DMA3(void) __attribute__ ((interrupt_handler, section(".icode"))); 391void DMA3(void) __attribute__ ((interrupt_handler, section(".icode")));