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.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/firmware/target/coldfire/iriver/h300/lcd-h300.c b/firmware/target/coldfire/iriver/h300/lcd-h300.c
index 8f76d5255a..00662e16f9 100644
--- a/firmware/target/coldfire/iriver/h300/lcd-h300.c
+++ b/firmware/target/coldfire/iriver/h300/lcd-h300.c
@@ -80,6 +80,9 @@ static int xoffset = 0; /* needed for flip */
80#define LCD_CMD (*(volatile unsigned short *)0xf0000000) 80#define LCD_CMD (*(volatile unsigned short *)0xf0000000)
81#define LCD_DATA (*(volatile unsigned short *)0xf0000002) 81#define LCD_DATA (*(volatile unsigned short *)0xf0000002)
82 82
83#define R_ENTRY_MODE_HORZ 0x7030
84#define R_ENTRY_MODE_VERT 0x7038
85
83/* called very frequently - inline! */ 86/* called very frequently - inline! */
84static inline void lcd_write_reg(int reg, int val) 87static inline void lcd_write_reg(int reg, int val)
85{ 88{
@@ -307,13 +310,12 @@ void lcd_blit(const fb_data* data, int x, int by, int width,
307} 310}
308 311
309/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. 312/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420.
310 * y should have two lines of Y back to back. 313 * y should have two lines of Y back to back, 2nd line first.
311 * bu and rv should contain the Cb and Cr data for the two lines of Y. 314 * c should contain the Cb and Cr data for the two lines of Y back to back.
312 * Needs EMAC set to saturated, signed integer mode. 315 * Needs EMAC set to saturated, signed integer mode.
313 */ 316 */
314extern void lcd_write_yuv420_lines(const unsigned char *y, 317extern void lcd_write_yuv420_lines(const unsigned char *y,
315 const unsigned char *bu, 318 const unsigned char *c, int cwidth);
316 const unsigned char *rv, int width);
317 319
318/* Performance function to blit a YUV bitmap directly to the LCD 320/* Performance function to blit a YUV bitmap directly to the LCD
319 * src_x, src_y, width and height should be even 321 * src_x, src_y, width and height should be even
@@ -325,8 +327,7 @@ void lcd_yuv_blit(unsigned char * const src[3],
325{ 327{
326 /* IRAM Y, Cb and Cb buffers. */ 328 /* IRAM Y, Cb and Cb buffers. */
327 unsigned char y_ibuf[LCD_WIDTH*2]; 329 unsigned char y_ibuf[LCD_WIDTH*2];
328 unsigned char bu_ibuf[LCD_WIDTH/2]; 330 unsigned char c_ibuf[LCD_WIDTH];
329 unsigned char rv_ibuf[LCD_WIDTH/2];
330 const unsigned char *ysrc, *usrc, *vsrc; 331 const unsigned char *ysrc, *usrc, *vsrc;
331 const unsigned char *ysrc_max; 332 const unsigned char *ysrc_max;
332 333
@@ -336,11 +337,9 @@ void lcd_yuv_blit(unsigned char * const src[3],
336 width &= ~1; /* stay on the safe side */ 337 width &= ~1; /* stay on the safe side */
337 height &= ~1; 338 height &= ~1;
338 339
340 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_HORZ);
339 /* Set start position and window */ 341 /* Set start position and window */
340 lcd_write_reg(R_VERT_RAM_ADDR_POS,((x+xoffset+width-1) << 8) | (x+xoffset)); 342 lcd_write_reg(R_VERT_RAM_ADDR_POS, ((xoffset + 219) << 8) | xoffset);
341 lcd_write_reg(R_RAM_ADDR_SET, ((x+xoffset) << 8) | y);
342
343 lcd_begin_write_gram();
344 343
345 ysrc = src[0] + src_y * stride + src_x; 344 ysrc = src[0] + src_y * stride + src_x;
346 usrc = src[1] + (src_y * stride >> 2) + (src_x >> 1); 345 usrc = src[1] + (src_y * stride >> 2) + (src_x >> 1);
@@ -350,11 +349,17 @@ void lcd_yuv_blit(unsigned char * const src[3],
350 coldfire_set_macsr(EMAC_SATURATE); 349 coldfire_set_macsr(EMAC_SATURATE);
351 do 350 do
352 { 351 {
353 memcpy(y_ibuf, ysrc, width); 352 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((y + 1) << 8) | y);
354 memcpy(y_ibuf + width, ysrc + stride, width); 353 lcd_write_reg(R_RAM_ADDR_SET, ((x+xoffset) << 8) | y);
355 memcpy(bu_ibuf, usrc, width >> 1); 354 lcd_begin_write_gram();
356 memcpy(rv_ibuf, vsrc, width >> 1); 355
357 lcd_write_yuv420_lines(y_ibuf, bu_ibuf, rv_ibuf, width); 356 memcpy(y_ibuf + width, ysrc, width);
357 memcpy(y_ibuf, ysrc + stride, width);
358 memcpy(c_ibuf, usrc, width >> 1);
359 memcpy(c_ibuf + (width >> 1), vsrc, width >> 1);
360 lcd_write_yuv420_lines(y_ibuf, c_ibuf, width >> 1);
361
362 y += 2;
358 ysrc += 2 * stride; 363 ysrc += 2 * stride;
359 usrc += stride >> 1; 364 usrc += stride >> 1;
360 vsrc += stride >> 1; 365 vsrc += stride >> 1;
@@ -368,11 +373,12 @@ void lcd_update(void) ICODE_ATTR;
368void lcd_update(void) 373void lcd_update(void)
369{ 374{
370 if(display_on){ 375 if(display_on){
371 /* reset update window */ 376 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT);
377 /* set start position window */
378 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 175 << 8);
372 lcd_write_reg(R_VERT_RAM_ADDR_POS,((xoffset+219)<<8) | xoffset); 379 lcd_write_reg(R_VERT_RAM_ADDR_POS,((xoffset+219)<<8) | xoffset);
373
374 /* Copy display bitmap to hardware */
375 lcd_write_reg(R_RAM_ADDR_SET, xoffset << 8); 380 lcd_write_reg(R_RAM_ADDR_SET, xoffset << 8);
381
376 lcd_begin_write_gram(); 382 lcd_begin_write_gram();
377 383
378 DAR3 = 0xf0000002; 384 DAR3 = 0xf0000002;
@@ -403,8 +409,9 @@ void lcd_update_rect(int x, int y, int width, int height)
403 if(y + height > LCD_HEIGHT) 409 if(y + height > LCD_HEIGHT)
404 height = LCD_HEIGHT - y; 410 height = LCD_HEIGHT - y;
405 411
412 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_VERT);
406 /* set update window */ 413 /* set update window */
407 414 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 175 << 8);
408 lcd_write_reg(R_VERT_RAM_ADDR_POS,((x+xoffset+width-1) << 8) | (x+xoffset)); 415 lcd_write_reg(R_VERT_RAM_ADDR_POS,((x+xoffset+width-1) << 8) | (x+xoffset));
409 lcd_write_reg(R_RAM_ADDR_SET, ((x+xoffset) << 8) | y); 416 lcd_write_reg(R_RAM_ADDR_SET, ((x+xoffset) << 8) | y);
410 lcd_begin_write_gram(); 417 lcd_begin_write_gram();